Skip to content

Commit

Permalink
Add new GUI widget QgsDatabaseTableComboBox for selection of
Browse files Browse the repository at this point in the history
available tables for a specific data connection

(providers must implement the connections API)
  • Loading branch information
nyalldawson committed Mar 9, 2020
1 parent bd5dcd2 commit 35411af
Show file tree
Hide file tree
Showing 8 changed files with 626 additions and 1 deletion.
111 changes: 111 additions & 0 deletions python/gui/auto_generated/qgsdatabasetablecombobox.sip.in
@@ -0,0 +1,111 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsdatabasetablecombobox.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsDatabaseTableComboBox : QWidget
{
%Docstring
The QgsDatabaseTableComboBox class is a combo box which displays the list of tables for a specific database connection.

.. warning::

The provider must support the connection API methods in its QgsProviderMetadata implementation
in order for the combobox to work correctly.

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsdatabasetablecombobox.h"
%End
public:

explicit QgsDatabaseTableComboBox( const QString &provider, const QString &connection, const QString &schema = QString(), QWidget *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsDatabaseTableComboBox, for the specified ``provider`` and ``connection``.

The optional ``schema`` argument can be used to restrict the listed tables to a specific schema.

.. warning::

The provider must support the connection API methods in its QgsProviderMetadata implementation
in order for the model to work correctly.
%End

explicit QgsDatabaseTableComboBox( QgsAbstractDatabaseProviderConnection *connection /Transfer/, const QString &schema = QString(), QWidget *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsDatabaseTableComboBox, for the specified ``connection``.

The optional ``schema`` argument can be used to restrict the listed tables to a specific schema.

Ownership of ``connection`` is transferred to the combobox.
%End

QString currentTable() const;
%Docstring
Returns the name of the current table selected in the combo box.
%End

QString currentSchema() const;
%Docstring
Returns the schema of the current table selected in the combo box.
%End

QComboBox *comboBox();
%Docstring
Returns the combobox portion of the widget.
%End

public slots:

void setTable( const QString &table, const QString &schema = QString() );
%Docstring
Sets the current table selected in the combo box.

If necessary, the ``schema`` can be specified too.
%End

void setConnectionName( const QString &connection, const QString &provider = QString() );
%Docstring
Sets the database connection name from which to retrieve the available tables.

Optionally the ``provider`` can be reset too.
%End

void setSchema( const QString &schema );
%Docstring
Sets the ``schema`` from which to retrieve the available tables.
%End

void refreshTables();
%Docstring
Refreshes the list of available tables.
%End

signals:
void tableChanged( const QString &table, const QString &schema = QString() );
%Docstring
Emitted whenever the currently selected table changes.
%End

protected slots:
void indexChanged( int i );
void rowsChanged();

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsdatabasetablecombobox.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/gui/gui_auto.sip
Expand Up @@ -55,6 +55,7 @@
%Include auto_generated/qgscurveeditorwidget.sip
%Include auto_generated/qgscustomdrophandler.sip
%Include auto_generated/qgsdatabaseschemacombobox.sip
%Include auto_generated/qgsdatabasetablecombobox.sip
%Include auto_generated/qgsdataitemguiprovider.sip
%Include auto_generated/qgsdataitemguiproviderregistry.sip
%Include auto_generated/qgsdatasourceselectdialog.sip
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -322,6 +322,7 @@ SET(QGIS_GUI_SRCS
qgscustomdrophandler.cpp
qgscurveeditorwidget.cpp
qgsdatabaseschemacombobox.cpp
qgsdatabasetablecombobox.cpp
qgsdataitemguiprovider.cpp
qgsdataitemguiproviderregistry.cpp
qgsdatumtransformdialog.cpp
Expand Down Expand Up @@ -527,6 +528,7 @@ SET(QGIS_GUI_HDRS
qgscurveeditorwidget.h
qgscustomdrophandler.h
qgsdatabaseschemacombobox.h
qgsdatabasetablecombobox.h
qgsdataitemguiprovider.h
qgsdataitemguiproviderregistry.h
qgsdatasourcemanagerdialog.h
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsdatabaseschemacombobox.cpp
Expand Up @@ -78,7 +78,7 @@ void QgsDatabaseSchemaComboBox::setSchema( const QString &schema )
return;
}

QModelIndexList idx = mSortModel->match( mSortModel->index( 0, 0 ), Qt::DisplayRole, schema, Qt::MatchFixedString | Qt::MatchCaseSensitive );
QModelIndexList idx = mSortModel->match( mSortModel->index( 0, 0 ), Qt::DisplayRole, schema, 1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
if ( !idx.empty() )
{
QModelIndex proxyIdx = idx.at( 0 );
Expand Down
174 changes: 174 additions & 0 deletions src/gui/qgsdatabasetablecombobox.cpp
@@ -0,0 +1,174 @@
/***************************************************************************
qgsdatabasetablecombobox.cpp
--------------------------------
Date : March 2020
Copyright : (C) 2020 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsdatabasetablecombobox.h"
#include "qgsdatabasetablemodel.h"
#include "qgsapplication.h"
#include <QHBoxLayout>
#include <QToolButton>

QgsDatabaseTableComboBox::QgsDatabaseTableComboBox( const QString &provider, const QString &connection, const QString &schema, QWidget *parent )
: QWidget( parent )
, mProvider( provider )
, mConnection( connection )
, mSchema( schema )
{
mModel = new QgsDatabaseTableModel( provider, connection, schema, this );
init();
}

QgsDatabaseTableComboBox::QgsDatabaseTableComboBox( QgsAbstractDatabaseProviderConnection *connection, const QString &schema, QWidget *parent )
: QWidget( parent )
, mSchema( schema )
{
mModel = new QgsDatabaseTableModel( connection, schema, this );
init();
}

void QgsDatabaseTableComboBox::init()
{
mComboBox = new QComboBox();

mSortModel = new QSortFilterProxyModel( this );
mSortModel->setSourceModel( mModel );
mSortModel->setSortRole( Qt::DisplayRole );
mSortModel->setSortLocaleAware( true );
mSortModel->setSortCaseSensitivity( Qt::CaseInsensitive );
mSortModel->setDynamicSortFilter( true );
mSortModel->sort( 0 );

mComboBox->setModel( mSortModel );

QHBoxLayout *l = new QHBoxLayout();
l->setContentsMargins( 0, 0, 0, 0 );
l->addWidget( mComboBox );

QToolButton *refreshButton = new QToolButton();
refreshButton->setAutoRaise( true );
refreshButton->setToolTip( tr( "Refresh tables" ) );
refreshButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionRefresh.svg" ) ) );
l->addWidget( refreshButton );
setLayout( l );

connect( refreshButton, &QToolButton::clicked, this, &QgsDatabaseTableComboBox::refreshTables );

connect( mComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::activated ), this, &QgsDatabaseTableComboBox::indexChanged );
connect( mSortModel, &QAbstractItemModel::rowsInserted, this, &QgsDatabaseTableComboBox::rowsChanged );
connect( mSortModel, &QAbstractItemModel::rowsRemoved, this, &QgsDatabaseTableComboBox::rowsChanged );
}

void QgsDatabaseTableComboBox::setTable( const QString &table, const QString &schema )
{
if ( schema == currentSchema() && table == currentTable() )
return;

if ( table.isEmpty() )
{
mComboBox->setCurrentIndex( -1 );
emit tableChanged( QString() );
return;
}

const QModelIndexList idxs = mSortModel->match( mSortModel->index( 0, 0 ), QgsDatabaseTableModel::RoleTableName, table, -1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
for ( const QModelIndex &proxyIdx : idxs )
{
if ( proxyIdx.isValid() && proxyIdx.data( QgsDatabaseTableModel::RoleTableName ).toString() == table
&& ( schema.isEmpty() || proxyIdx.data( QgsDatabaseTableModel::RoleSchema ).toString() == schema ) )
{
mComboBox->setCurrentIndex( proxyIdx.row() );
emit tableChanged( currentTable(), currentSchema() );
return;
}
}
mComboBox->setCurrentIndex( -1 );
emit tableChanged( QString() );
}

void QgsDatabaseTableComboBox::setConnectionName( const QString &connection, const QString &provider )
{
if ( !provider.isEmpty() )
mProvider = provider;

mConnection = connection;

const QString oldTable = currentTable();
const QString oldSchema = currentSchema();
QgsDatabaseTableModel *oldModel = mModel;
mModel = new QgsDatabaseTableModel( mProvider, mConnection, mSchema, this );
mSortModel->setSourceModel( mModel );
oldModel->deleteLater();
if ( currentTable() != oldTable || currentSchema() != oldSchema )
setTable( oldTable, oldSchema );
}

void QgsDatabaseTableComboBox::setSchema( const QString &schema )
{
const QString oldTable = currentTable();
QgsDatabaseTableModel *oldModel = mModel;
mSchema = schema;
mModel = new QgsDatabaseTableModel( mProvider, mConnection, mSchema, this );
mSortModel->setSourceModel( mModel );
oldModel->deleteLater();
setTable( oldTable );
}

void QgsDatabaseTableComboBox::refreshTables()
{
const QString oldSchema = currentSchema();
const QString oldTable = currentTable();
mModel->refresh();
setTable( oldTable, oldSchema );
}

QString QgsDatabaseTableComboBox::currentSchema() const
{
const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
if ( !proxyIndex.isValid() )
{
return QString();
}

return mSortModel->data( proxyIndex, QgsDatabaseTableModel::RoleSchema ).toString();
}

QString QgsDatabaseTableComboBox::currentTable() const
{
const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
if ( !proxyIndex.isValid() )
{
return QString();
}

return mSortModel->data( proxyIndex, QgsDatabaseTableModel::RoleTableName ).toString();
}

void QgsDatabaseTableComboBox::indexChanged( int i )
{
Q_UNUSED( i )
emit tableChanged( currentTable() );
}

void QgsDatabaseTableComboBox::rowsChanged()
{
if ( mComboBox->count() == 1 )
{
//currently selected connection item has changed
emit tableChanged( currentTable(), currentSchema() );
}
else if ( mComboBox->count() == 0 )
{
emit tableChanged( QString() );
}
}

0 comments on commit 35411af

Please sign in to comment.