Skip to content

Commit

Permalink
Add new GUI widget QgsProviderConnectionComboBox for selection of
Browse files Browse the repository at this point in the history
registered connections for a specific data provider

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





class QgsProviderConnectionComboBox : QComboBox
{
%Docstring
The QgsProviderConnectionComboBox class is a combo box which displays the list of connections registered for a given provider.

.. warning::

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

.. versionadded:: 3.14
%End

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

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

.. warning::

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

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

QString currentConnectionUri() const;
%Docstring
Returns the uri of the current connection selected in the combo box.
%End

public slots:

void setConnection( const QString &connection );
%Docstring
Sets the current connection selected in the combo box.
%End

signals:
void connectionChanged( const QString &connection );
%Docstring
Emitted whenever the currently selected connection changes.
%End

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

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsproviderconnectioncombobox.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 @@ -162,6 +162,7 @@
%Include auto_generated/qgsprojectstorageguiregistry.sip
%Include auto_generated/qgspropertyassistantwidget.sip
%Include auto_generated/qgspropertyoverridebutton.sip
%Include auto_generated/qgsproviderconnectioncombobox.sip
%Include auto_generated/qgsproviderguimetadata.sip
%Include auto_generated/qgsproviderguiregistry.sip
%Include auto_generated/qgsproxystyle.sip
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -434,6 +434,7 @@ SET(QGIS_GUI_SRCS
qgsproviderguiregistry.cpp
qgsproviderguimetadata.cpp
qgsprojectstorageguiregistry.cpp
qgsproviderconnectioncombobox.cpp
qgsproxystyle.cpp
qgsquerybuilder.cpp
qgsrasterformatsaveoptionswidget.cpp
Expand Down Expand Up @@ -639,6 +640,7 @@ SET(QGIS_GUI_HDRS
qgsprojectstorageguiregistry.h
qgspropertyassistantwidget.h
qgspropertyoverridebutton.h
qgsproviderconnectioncombobox.h
qgsproviderguimetadata.h
qgsproviderguiregistry.h
qgsproxystyle.h
Expand Down
105 changes: 105 additions & 0 deletions src/gui/qgsproviderconnectioncombobox.cpp
@@ -0,0 +1,105 @@
/***************************************************************************
qgsproviderconnectioncombobox.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 "qgsproviderconnectioncombobox.h"
#include "qgsproviderconnectionmodel.h"

QgsProviderConnectionComboBox::QgsProviderConnectionComboBox( const QString &provider, QWidget *parent )
: QComboBox( parent )
{
mModel = new QgsProviderConnectionModel( provider, this );

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

setModel( mSortModel );

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

void QgsProviderConnectionComboBox::setConnection( const QString &connection )
{
if ( connection == currentConnection() )
return;

if ( connection.isEmpty() )
{
setCurrentIndex( -1 );
emit connectionChanged( QString() );
return;
}

QModelIndexList idx = mSortModel->match( mSortModel->index( 0, 0 ), QgsProviderConnectionModel::RoleConnectionName, connection, Qt::MatchFixedString | Qt::MatchCaseSensitive );
if ( !idx.empty() )
{
QModelIndex proxyIdx = idx.at( 0 );
if ( proxyIdx.isValid() )
{
setCurrentIndex( proxyIdx.row() );
emit connectionChanged( currentConnection() );
return;
}
}
setCurrentIndex( -1 );
emit connectionChanged( QString() );
}

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

return mSortModel->data( proxyIndex, QgsProviderConnectionModel::RoleConnectionName ).toString();
}

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

return mSortModel->data( proxyIndex, QgsProviderConnectionModel::RoleUri ).toString();
}

void QgsProviderConnectionComboBox::indexChanged( int i )
{
Q_UNUSED( i )
emit connectionChanged( currentConnection() );
}

void QgsProviderConnectionComboBox::rowsChanged()
{
if ( count() == 1 )
{
//currently selected connection item has changed
emit connectionChanged( currentConnection() );
}
else if ( count() == 0 )
{
emit connectionChanged( QString() );
}
}
80 changes: 80 additions & 0 deletions src/gui/qgsproviderconnectioncombobox.h
@@ -0,0 +1,80 @@
/***************************************************************************
qgsproviderconnectioncombobox.h
--------------------------------
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. *
* *
***************************************************************************/

#ifndef QGSPROVIDERCONNECTIONCOMBOBOX_H
#define QGSPROVIDERCONNECTIONCOMBOBOX_H

#include <QComboBox>

#include "qgis_gui.h"
#include "qgis_sip.h"

class QgsProviderConnectionModel;
class QSortFilterProxyModel;

/**
* \ingroup gui
* \brief The QgsProviderConnectionComboBox class is a combo box which displays the list of connections registered for a given provider.
*
* \warning The provider must support the connection API methods in its QgsProviderMetadata implementation
* in order for the model to work correctly.
*
* \since QGIS 3.14
*/
class GUI_EXPORT QgsProviderConnectionComboBox : public QComboBox
{
Q_OBJECT

public:

/**
* Constructor for QgsProviderConnectionComboBox, for the specified \a provider.
*
* \warning The provider must support the connection API methods in its QgsProviderMetadata implementation
* in order for the model to work correctly.
*/
explicit QgsProviderConnectionComboBox( const QString &provider, QWidget *parent SIP_TRANSFERTHIS = nullptr );

/**
* Returns the name of the current connection selected in the combo box.
*/
QString currentConnection() const;

/**
* Returns the uri of the current connection selected in the combo box.
*/
QString currentConnectionUri() const;

public slots:

/**
* Sets the current connection selected in the combo box.
*/
void setConnection( const QString &connection );

signals:
//! Emitted whenever the currently selected connection changes.
void connectionChanged( const QString &connection );

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

private:
QgsProviderConnectionModel *mModel = nullptr;
QSortFilterProxyModel *mSortModel = nullptr;
};

#endif // QGSPROVIDERCONNECTIONCOMBOBOX_H
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -185,6 +185,7 @@ ADD_PYTHON_TEST(PyQgsImportIntoPostGIS test_processing_importintopostgis.py)
ADD_PYTHON_TEST(PyQgsProjectionSelectionWidgets test_qgsprojectionselectionwidgets.py)
ADD_PYTHON_TEST(PyQgsProjectMetadata test_qgsprojectmetadata.py)
ADD_PYTHON_TEST(PyQgsPropertyOverrideButton test_qgspropertyoverridebutton.py)
ADD_PYTHON_TEST(PyQgsProviderConnectionComboBox test_qgsproviderconnectioncombobox.py)
ADD_PYTHON_TEST(PyQgsProviderConnectionModel test_qgsproviderconnectionmodel.py)
ADD_PYTHON_TEST(PyQgsProviderConnectionGpkg test_qgsproviderconnection_ogr_gpkg.py)
ADD_PYTHON_TEST(TestQgsRandomMarkerSymbolLayer test_qgsrandommarkersymbollayer.py)
Expand Down
7 changes: 2 additions & 5 deletions tests/src/python/test_qgsdatabasetablemodel.py
Expand Up @@ -18,7 +18,6 @@
QgsDatabaseTableModel,
QgsProviderRegistry,
QgsCoordinateReferenceSystem,
QgsAbstractDatabaseProviderConnection,
QgsWkbTypes,
QgsFields,
QgsField
Expand Down Expand Up @@ -73,8 +72,7 @@ def testModel(self):
self.assertEqual(model.data(model.index(tables.index('qgis_test.someData'), 0, QModelIndex()),
QgsDatabaseTableModel.RoleCustomInfo), {})
self.assertEqual(model.data(model.index(tables.index('qgis_test.someData'), 0, QModelIndex()),
QgsDatabaseTableModel.RoleTableFlags),
QgsAbstractDatabaseProviderConnection.TableFlag.Vector)
QgsDatabaseTableModel.RoleTableFlags), 4)
self.assertEqual(model.data(model.index(tables.index('qgis_test.someData'), 0, QModelIndex()),
QgsDatabaseTableModel.RoleWkbType), QgsWkbTypes.Point)
self.assertEqual(model.data(model.index(tables.index('qgis_test.some_poly_data'), 0, QModelIndex()),
Expand Down Expand Up @@ -157,8 +155,7 @@ def testModelSpecificSchema(self):
self.assertEqual(model.data(model.index(tables.index('someData'), 0, QModelIndex()),
QgsDatabaseTableModel.RoleCustomInfo), {})
self.assertEqual(model.data(model.index(tables.index('someData'), 0, QModelIndex()),
QgsDatabaseTableModel.RoleTableFlags),
QgsAbstractDatabaseProviderConnection.TableFlag.Vector)
QgsDatabaseTableModel.RoleTableFlags), 4)
self.assertEqual(model.data(model.index(tables.index('someData'), 0, QModelIndex()),
QgsDatabaseTableModel.RoleWkbType), QgsWkbTypes.Point)
self.assertEqual(model.data(model.index(tables.index('some_poly_data'), 0, QModelIndex()),
Expand Down

0 comments on commit 2bdb0cc

Please sign in to comment.