Skip to content
Permalink
Browse files
refactor db2 provider gui with enhanced filtering UX
  • Loading branch information
3nids committed Nov 9, 2021
1 parent 29ff1bd commit ae0f0709a932553e99692d162ce9f022dd02f51a
Showing with 75 additions and 142 deletions.
  1. +20 −115 src/providers/db2/qgsdb2sourceselect.cpp
  2. +3 −9 src/providers/db2/qgsdb2sourceselect.h
  3. +43 −14 src/providers/db2/qgsdb2tablemodel.cpp
  4. +9 −4 src/providers/db2/qgsdb2tablemodel.h
@@ -33,6 +33,7 @@
#include "qgssettings.h"
#include "qgsproject.h"
#include "qgsgui.h"
#include "qgsdbfilterproxymodel.h"

#include <QFileDialog>
#include <QMessageBox>
@@ -122,9 +123,8 @@ void QgsDb2SourceSelectDelegate::setModelData( QWidget *editor, QAbstractItemMod
}

QgsDb2SourceSelect::QgsDb2SourceSelect( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode theWidgetMode )
: QgsAbstractDataSourceWidget( parent, fl, theWidgetMode )
: QgsDbSourceSelectBase( parent, fl, theWidgetMode )
{
setupUi( this );
QgsGui::instance()->enableAutoGeometryRestore( this );

connect( btnConnect, &QPushButton::clicked, this, &QgsDb2SourceSelect::btnConnect_clicked );
@@ -134,10 +134,6 @@ QgsDb2SourceSelect::QgsDb2SourceSelect( QWidget *parent, Qt::WindowFlags fl, Qgs
connect( btnDelete, &QPushButton::clicked, this, &QgsDb2SourceSelect::btnDelete_clicked );
connect( btnSave, &QPushButton::clicked, this, &QgsDb2SourceSelect::btnSave_clicked );
connect( btnLoad, &QPushButton::clicked, this, &QgsDb2SourceSelect::btnLoad_clicked );
connect( mSearchGroupBox, &QGroupBox::toggled, this, &QgsDb2SourceSelect::mSearchGroupBox_toggled );
connect( mSearchTableEdit, &QLineEdit::textChanged, this, &QgsDb2SourceSelect::mSearchTableEdit_textChanged );
connect( mSearchColumnComboBox, &QComboBox::currentTextChanged, this, &QgsDb2SourceSelect::mSearchColumnComboBox_currentIndexChanged );
connect( mSearchModeComboBox, &QComboBox::currentTextChanged, this, &QgsDb2SourceSelect::mSearchModeComboBox_currentIndexChanged );
connect( cmbConnections, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsDb2SourceSelect::cmbConnections_activated );
connect( mTablesTreeView, &QTreeView::clicked, this, &QgsDb2SourceSelect::mTablesTreeView_clicked );
connect( mTablesTreeView, &QTreeView::doubleClicked, this, &QgsDb2SourceSelect::mTablesTreeView_doubleClicked );
@@ -163,24 +159,10 @@ QgsDb2SourceSelect::QgsDb2SourceSelect( QWidget *parent, Qt::WindowFlags fl, Qgs

populateConnectionList();

mSearchModeComboBox->addItem( tr( "Wildcard" ) );
mSearchModeComboBox->addItem( tr( "RegExp" ) );
mTableModel = new QgsDb2TableModel( this );
setSourceModel( mTableModel );

mSearchColumnComboBox->addItem( tr( "All" ) );
mSearchColumnComboBox->addItem( tr( "Schema" ) );
mSearchColumnComboBox->addItem( tr( "Table" ) );
mSearchColumnComboBox->addItem( tr( "Type" ) );
mSearchColumnComboBox->addItem( tr( "Geometry column" ) );
mSearchColumnComboBox->addItem( tr( "Primary key column" ) );
mSearchColumnComboBox->addItem( tr( "SRID" ) );
mSearchColumnComboBox->addItem( tr( "Sql" ) );

mProxyModel.setParent( this );
mProxyModel.setFilterKeyColumn( -1 );
mProxyModel.setFilterCaseSensitivity( Qt::CaseInsensitive );
mProxyModel.setSourceModel( &mTableModel );

mTablesTreeView->setModel( &mProxyModel );
mTablesTreeView->setModel( proxyModel() );
mTablesTreeView->setSortingEnabled( true );
mTablesTreeView->setEditTriggers( QAbstractItemView::CurrentChanged );
mTablesTreeView->setItemDelegate( new QgsDb2SourceSelectDelegate( this ) );
@@ -190,28 +172,13 @@ QgsDb2SourceSelect::QgsDb2SourceSelect( QWidget *parent, Qt::WindowFlags fl, Qgs
const QgsSettings settings;
mTablesTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection );


//for Qt < 4.3.2, passing -1 to include all model columns
//in search does not seem to work
mSearchColumnComboBox->setCurrentIndex( 2 );

mHoldDialogOpen->setChecked( settings.value( QStringLiteral( "Windows/Db2SourceSelect/HoldDialogOpen" ), false ).toBool() );

for ( int i = 0; i < mTableModel.columnCount(); i++ )
for ( int i = 0; i < mTableModel->columnCount(); i++ )
{
mTablesTreeView->setColumnWidth( i, settings.value( QStringLiteral( "Windows/Db2SourceSelect/columnWidths/%1" ).arg( i ), mTablesTreeView->columnWidth( i ) ).toInt() );
}

//hide the search options by default
//they will be shown when the user ticks
//the search options group box
mSearchLabel->setVisible( false );
mSearchColumnComboBox->setVisible( false );
mSearchColumnsLabel->setVisible( false );
mSearchModeComboBox->setVisible( false );
mSearchModeLabel->setVisible( false );
mSearchTableEdit->setVisible( false );

cbxAllowGeometrylessTables->setDisabled( true );
}

@@ -323,71 +290,9 @@ void QgsDb2SourceSelect::mTablesTreeView_doubleClicked( const QModelIndex & )
addButtonClicked();
}

void QgsDb2SourceSelect::mSearchGroupBox_toggled( bool checked )
{
if ( mSearchTableEdit->text().isEmpty() )
return;

mSearchTableEdit_textChanged( checked ? mSearchTableEdit->text() : QString() );
}

void QgsDb2SourceSelect::mSearchTableEdit_textChanged( const QString &text )
{
if ( mSearchModeComboBox->currentText() == tr( "Wildcard" ) )
{
mProxyModel._setFilterWildcard( text );
}
else if ( mSearchModeComboBox->currentText() == tr( "RegExp" ) )
{
mProxyModel._setFilterRegExp( text );
}
}

void QgsDb2SourceSelect::mSearchColumnComboBox_currentIndexChanged( const QString &text )
{
if ( text == tr( "All" ) )
{
mProxyModel.setFilterKeyColumn( -1 );
}
else if ( text == tr( "Schema" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmSchema );
}
else if ( text == tr( "Table" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmTable );
}
else if ( text == tr( "Type" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmType );
}
else if ( text == tr( "Geometry column" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmGeomCol );
}
else if ( text == tr( "Primary key column" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmPkCol );
}
else if ( text == tr( "SRID" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmSrid );
}
else if ( text == tr( "Sql" ) )
{
mProxyModel.setFilterKeyColumn( QgsDb2TableModel::DbtmSql );
}
}

void QgsDb2SourceSelect::mSearchModeComboBox_currentIndexChanged( const QString &text )
{
Q_UNUSED( text )
mSearchTableEdit_textChanged( mSearchTableEdit->text() );
}

void QgsDb2SourceSelect::setLayerType( const QgsDb2LayerProperty &layerProperty )
{
mTableModel.setGeometryTypesForTable( layerProperty );
mTableModel->setGeometryTypesForTable( layerProperty );
}

QgsDb2SourceSelect::~QgsDb2SourceSelect()
@@ -401,7 +306,7 @@ QgsDb2SourceSelect::~QgsDb2SourceSelect()
QgsSettings settings;
settings.setValue( QStringLiteral( "Windows/Db2SourceSelect/HoldDialogOpen" ), mHoldDialogOpen->isChecked() );

for ( int i = 0; i < mTableModel.columnCount(); i++ )
for ( int i = 0; i < mTableModel->columnCount(); i++ )
{
settings.setValue( QStringLiteral( "Windows/Db2SourceSelect/columnWidths/%1" ).arg( i ), mTablesTreeView->columnWidth( i ) );
}
@@ -441,7 +346,7 @@ void QgsDb2SourceSelect::addButtonClicked()
if ( idx.column() != QgsDb2TableModel::DbtmTable )
continue;

const QString uri = mTableModel.layerURI( mProxyModel.mapToSource( idx ), mConnInfo, mUseEstimatedMetadata );
const QString uri = mTableModel->layerURI( proxyModel()->mapToSource( idx ), mConnInfo, mUseEstimatedMetadata );
if ( uri.isNull() )
continue;

@@ -472,8 +377,8 @@ void QgsDb2SourceSelect::btnConnect_clicked()
return;
}

const QModelIndex rootItemIndex = mTableModel.indexFromItem( mTableModel.invisibleRootItem() );
mTableModel.removeRows( 0, mTableModel.rowCount( rootItemIndex ), rootItemIndex );
const QModelIndex rootItemIndex = mTableModel->indexFromItem( mTableModel->invisibleRootItem() );
mTableModel->removeRows( 0, mTableModel->rowCount( rootItemIndex ), rootItemIndex );

// populate the table list

@@ -516,7 +421,7 @@ void QgsDb2SourceSelect::btnConnect_clicked()
while ( db2GC.populateLayerProperty( layer ) )
{
QgsDebugMsg( "layer type: " + layer.type );
mTableModel.addTableEntry( layer );
mTableModel->addTableEntry( layer );

if ( mColumnTypeThread )
{
@@ -525,14 +430,14 @@ void QgsDb2SourceSelect::btnConnect_clicked()
}

//if we have only one schema item, expand it by default
const int numTopLevelItems = mTableModel.invisibleRootItem()->rowCount();
if ( numTopLevelItems < 2 || mTableModel.tableCount() < 20 )
const int numTopLevelItems = mTableModel->invisibleRootItem()->rowCount();
if ( numTopLevelItems < 2 || mTableModel->tableCount() < 20 )
{
//expand all the toplevel items
for ( int i = 0; i < numTopLevelItems; ++i )
{
mTablesTreeView->expand( mProxyModel.mapFromSource(
mTableModel.indexFromItem( mTableModel.invisibleRootItem()->child( i ) ) ) );
mTablesTreeView->expand( proxyModel()->mapFromSource(
mTableModel->indexFromItem( mTableModel->invisibleRootItem()->child( i ) ) ) );
}
}
}
@@ -587,11 +492,11 @@ void QgsDb2SourceSelect::setSql( const QModelIndex &index )
return;
}

const QModelIndex idx = mProxyModel.mapToSource( index );
const QString tableName = mTableModel.itemFromIndex( idx.sibling( idx.row(), QgsDb2TableModel::DbtmTable ) )->text();
const QModelIndex idx = proxyModel()->mapToSource( index );
const QString tableName = mTableModel->itemFromIndex( idx.sibling( idx.row(), QgsDb2TableModel::DbtmTable ) )->text();

const QgsVectorLayer::LayerOptions options { QgsProject::instance()->transformContext() };
std::unique_ptr< QgsVectorLayer > vlayer = std::make_unique< QgsVectorLayer >( mTableModel.layerURI( idx, mConnInfo, mUseEstimatedMetadata ), tableName, QStringLiteral( "DB2" ), options );
std::unique_ptr< QgsVectorLayer > vlayer = std::make_unique< QgsVectorLayer >( mTableModel->layerURI( idx, mConnInfo, mUseEstimatedMetadata ), tableName, QStringLiteral( "DB2" ), options );

if ( !vlayer->isValid() )
{
@@ -602,7 +507,7 @@ void QgsDb2SourceSelect::setSql( const QModelIndex &index )
QgsQueryBuilder gb( vlayer.get(), this );
if ( gb.exec() )
{
mTableModel.setSql( mProxyModel.mapToSource( index ), gb.sql() );
mTableModel->setSql( proxyModel()->mapToSource( index ), gb.sql() );
}
}

@@ -21,11 +21,10 @@

#include "ui_qgsdbsourceselectbase.h"
#include "qgsguiutils.h"
#include "qgsdbfilterproxymodel.h"
#include "qgsdb2tablemodel.h"
#include "qgshelp.h"
#include "qgsproviderregistry.h"
#include "qgsabstractdatasourcewidget.h"
#include "qgsdbsourceselectbase.h"

#include <QMap>
#include <QPair>
@@ -89,7 +88,7 @@ class QgsDb2GeomColumnTypeThread : public QThread
* for Db2 databases. The user can then connect and add
* tables from the database to the map canvas.
*/
class QgsDb2SourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsDbSourceSelectBase
class QgsDb2SourceSelect : public QgsDbSourceSelectBase
{
Q_OBJECT

@@ -135,10 +134,6 @@ class QgsDb2SourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsDb
void btnSave_clicked();
//! Loads the selected connections from file
void btnLoad_clicked();
void mSearchGroupBox_toggled( bool );
void mSearchTableEdit_textChanged( const QString &text );
void mSearchColumnComboBox_currentIndexChanged( const QString &text );
void mSearchModeComboBox_currentIndexChanged( const QString &text );
void setSql( const QModelIndex &index );
//! Store the selected database
void cmbConnections_activated( int );
@@ -175,8 +170,7 @@ class QgsDb2SourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsDb
QMap<QString, QPair<QString, QIcon> > mLayerIcons;

//! Model that acts as datasource for mTableTreeWidget
QgsDb2TableModel mTableModel;
QgsDatabaseFilterProxyModel mProxyModel;
QgsDb2TableModel *mTableModel = nullptr;

QPushButton *mBuildQueryButton = nullptr;

@@ -22,18 +22,47 @@
#include "qgsapplication.h"
#include "qgsiconutils.h"

QgsDb2TableModel::QgsDb2TableModel()
QgsDb2TableModel::QgsDb2TableModel( QObject *parent )
: QgsAbstractDbTableModel( parent )
{
QStringList headerLabels;
headerLabels << tr( "Schema" );
headerLabels << tr( "Table" );
headerLabels << tr( "Type" );
headerLabels << tr( "Geometry column" );
headerLabels << tr( "SRID" );
headerLabels << tr( "Primary key column" );
headerLabels << tr( "Select at id" );
headerLabels << tr( "Sql" );
setHorizontalHeaderLabels( headerLabels );
mColumns << tr( "Schema" )
<< tr( "Table" )
<< tr( "Type" )
<< tr( "Geometry column" )
<< tr( "SRID" )
<< tr( "Primary key column" )
<< tr( "Select at id" )
<< tr( "Sql" );
setHorizontalHeaderLabels( mColumns );
}

QStringList QgsDb2TableModel::columns() const
{
return mColumns;
}

int QgsDb2TableModel::defaultSearchColumn() const
{
return static_cast<int>( DbtmTable );
}

bool QgsDb2TableModel::searchableColumn( int column ) const
{
Columns col = static_cast<Columns>( column );
switch ( col )
{
case DbtmSchema:
case DbtmTable:
case DbtmGeomCol:
case DbtmType:
case DbtmSrid:
case DbtmSql:
return true;

case DbtmPkCol:
case DbtmSelectAtId:
return false;
}
}

void QgsDb2TableModel::addTableEntry( const QgsDb2LayerProperty &layerProperty )
@@ -242,8 +271,8 @@ void QgsDb2TableModel::setGeometryTypesForTable( QgsDb2LayerProperty layerProper

QList<QStandardItem *> row;

row.reserve( DbtmColumns );
for ( int j = 0; j < DbtmColumns; j++ )
row.reserve( columnCount() );
for ( int j = 0; j < columnCount(); j++ )
{
row << itemFromIndex( currentChildIndex.sibling( i, j ) );
}
@@ -315,7 +344,7 @@ bool QgsDb2TableModel::setData( const QModelIndex &idx, const QVariant &value, i
if ( ok && pkCols.size() > 0 )
ok = pkCols.contains( idx.sibling( idx.row(), DbtmPkCol ).data().toString() );

for ( int i = 0; i < DbtmColumns; i++ )
for ( int i = 0; i < columnCount(); i++ )
{
QStandardItem *item = itemFromIndex( idx.sibling( idx.row(), i ) );
if ( ok )
Loading

0 comments on commit ae0f070

Please sign in to comment.