Skip to content
Permalink
Browse files
Add progress bar and minor UX changes
  • Loading branch information
elpaso committed Jul 6, 2021
1 parent 537670a commit 357fa9c4d8eabe3c71b58afe8b1c5f9ade02a81d
@@ -88,7 +88,6 @@ Emitted when the first batch of results has been fetched.
If the query returns no results this signal is not emitted.
%End


};

/************************************************************************
@@ -19,8 +19,6 @@
#include "qgsmessagelog.h"
#include "qgsquerybuilder.h"
#include "qgsvectorlayer.h"
#include <QStandardItem>



QgsQueryResultWidget::QgsQueryResultWidget( QWidget *parent, QgsAbstractDatabaseProviderConnection *connection )
@@ -31,6 +29,9 @@ QgsQueryResultWidget::QgsQueryResultWidget( QWidget *parent, QgsAbstractDatabase
// Unsure :/
// mSqlEditor->setLineNumbersVisible( true );

mQueryResultsTableView->hide();
mProgressBar->hide();

connect( mExecuteButton, &QPushButton::pressed, this, &QgsQueryResultWidget::executeQuery );
connect( mClearButton, &QPushButton::pressed, this, [ = ]
{
@@ -98,13 +99,7 @@ QgsQueryResultWidget::QgsQueryResultWidget( QWidget *parent, QgsAbstractDatabase

QgsQueryResultWidget::~QgsQueryResultWidget()
{
if ( mApiFetcher )
{
mApiFetcher->stopFetching();
mWorkerThread.quit();
mWorkerThread.wait();
mWorkerThread.deleteLater();
}
cancelApiFetcher();
cancelRunningQuery();
}

@@ -125,12 +120,15 @@ void QgsQueryResultWidget::executeQuery()
mStopButton->setEnabled( true );
mStatusLabel->show();
mStatusLabel->setText( tr( "Running⋯" ) );
mProgressBar->show();
mProgressBar->setRange( 0, 0 );
mSqlErrorMessage.clear();

connect( mStopButton, &QPushButton::pressed, mFeedback.get(), [ = ]
{
mStatusLabel->setText( tr( "Stopped" ) );
mFeedback->cancel();
mProgressBar->hide();
mWasCanceled = true;
} );

@@ -214,6 +212,17 @@ void QgsQueryResultWidget::cancelRunningQuery()
}
}

void QgsQueryResultWidget::cancelApiFetcher()
{
if ( mApiFetcher )
{
mApiFetcher->stopFetching();
mApiFetcherWorkerThread.quit();
mApiFetcherWorkerThread.wait();
mApiFetcherWorkerThread.deleteLater();
}
}

void QgsQueryResultWidget::startFetching()
{
if ( ! mWasCanceled )
@@ -242,7 +251,7 @@ void QgsQueryResultWidget::startFetching()
updateButtons();
updateSqlLayerColumns( );
}
mStatusLabel->setText( tr( "Fetched rows: %1 %2." )
mStatusLabel->setText( tr( "Fetched rows: %1 %2" )
.arg( mModel->rowCount( mModel->index( -1, -1 ) ) )
.arg( mWasCanceled ? tr( "(stopped)" ) : QString() ) );
} );
@@ -256,20 +265,23 @@ void QgsQueryResultWidget::startFetching()
if ( ! mWasCanceled )
{
mStatusLabel->setText( "Query executed successfully." );
mProgressBar->hide();
}
} );
}
}
else
{
mStatusLabel->setText( tr( "SQL command aborted." ) );
mProgressBar->hide();
}
}

void QgsQueryResultWidget::showError( const QString &title, const QString &message, bool isSqlError )
{
mStatusLabel->show();
mStatusLabel->setText( tr( "There was an error executing the query." ) );
mProgressBar->hide();
mQueryResultsTableView->hide();
if ( isSqlError )
{
@@ -317,14 +329,7 @@ void QgsQueryResultWidget::setConnection( QgsAbstractDatabaseProviderConnection
{
mConnection.reset( connection );

if ( mApiFetcher )
{
mApiFetcher->stopFetching();
mWorkerThread.quit();
mWorkerThread.wait();
mApiFetcher->deleteLater();
mApiFetcher = nullptr;
}
cancelApiFetcher();

if ( connection )
{
@@ -343,15 +348,15 @@ void QgsQueryResultWidget::setConnection( QgsAbstractDatabaseProviderConnection

// Add dynamic keywords in a separate thread
mApiFetcher = new QgsConnectionsApiFetcher( connection );
mApiFetcher->moveToThread( &mWorkerThread );
connect( &mWorkerThread, &QThread::started, mApiFetcher, &QgsConnectionsApiFetcher::fetchTokens );
connect( &mWorkerThread, &QThread::finished, mApiFetcher, [ = ]
mApiFetcher->moveToThread( &mApiFetcherWorkerThread );
connect( &mApiFetcherWorkerThread, &QThread::started, mApiFetcher, &QgsConnectionsApiFetcher::fetchTokens );
connect( &mApiFetcherWorkerThread, &QThread::finished, mApiFetcher, [ = ]
{
mApiFetcher->deleteLater();
mApiFetcher = nullptr;
} );
connect( mApiFetcher, &QgsConnectionsApiFetcher::tokensReady, this, &QgsQueryResultWidget::tokensReady );
mWorkerThread.start();
mApiFetcherWorkerThread.start();
}

updateButtons();
@@ -380,7 +385,7 @@ void QgsConnectionsApiFetcher::fetchTokens()
}
catch ( QgsProviderConnectionException &ex )
{
QgsMessageLog::logMessage( tr( "Error retrieving schemas: %1" ).arg( ex.what() ) );
QgsMessageLog::logMessage( tr( "Error retrieving schemas: %1" ).arg( ex.what() ), QStringLiteral( "QGIS" ), Qgis::MessageLevel::Warning );
}
}
else
@@ -404,7 +409,7 @@ void QgsConnectionsApiFetcher::fetchTokens()
}
catch ( QgsProviderConnectionException &ex )
{
QgsMessageLog::logMessage( tr( "Error retrieving tables: %1" ).arg( ex.what() ) );
QgsMessageLog::logMessage( tr( "Error retrieving tables: %1" ).arg( ex.what() ), QStringLiteral( "QGIS" ), Qgis::MessageLevel::Warning );
}

// Get fields
@@ -425,7 +430,7 @@ void QgsConnectionsApiFetcher::fetchTokens()
}
catch ( QgsProviderConnectionException &ex )
{
QgsMessageLog::logMessage( tr( "Error retrieving fields for table %1: %2" ).arg( table, ex.what() ) );
QgsMessageLog::logMessage( tr( "Error retrieving fields for table %1: %2" ).arg( table, ex.what() ), QStringLiteral( "QGIS" ), Qgis::MessageLevel::Warning );
}
}
}
@@ -32,7 +32,7 @@
#ifndef SIP_RUN

/**
* \brief The QgsConnectionsApiFetcher class fetches tokens (table and field names) of a connection from a separate thread.
* \brief The QgsConnectionsApiFetcher class fetches tokens (schema, table and field names) of a connection from a separate thread.
*/
class GUI_EXPORT QgsConnectionsApiFetcher: public QObject
{
@@ -123,10 +123,6 @@ class GUI_EXPORT QgsQueryResultWidget: public QWidget, private Ui::QgsQueryResul
*/
void tokensReady( const QStringList &tokens );

private slots:

void syncSqlOptions();

signals:

/**
@@ -143,14 +139,17 @@ class GUI_EXPORT QgsQueryResultWidget: public QWidget, private Ui::QgsQueryResul
*/
void firstResultBatchFetched();

private slots:

void syncSqlOptions();

private:

std::unique_ptr<QgsAbstractDatabaseProviderConnection> mConnection;
std::unique_ptr<QgsQueryResultModel> mModel;
std::unique_ptr<QgsFeedback> mFeedback;
QgsConnectionsApiFetcher *mApiFetcher = nullptr;
QThread mWorkerThread;
QThread mApiFetcherWorkerThread;
bool mWasCanceled = false;
QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions mSqlVectorLayerOptions;
bool mFirstRowFetched = false;
@@ -172,6 +171,10 @@ class GUI_EXPORT QgsQueryResultWidget: public QWidget, private Ui::QgsQueryResul
*/
void cancelRunningQuery();

/**
* Cancel API fetching.
*/
void cancelApiFetcher();

/**
* Starts the model population after initial query run.
@@ -183,7 +186,6 @@ class GUI_EXPORT QgsQueryResultWidget: public QWidget, private Ui::QgsQueryResul
*/
QgsAbstractDatabaseProviderConnection::SqlVectorLayerOptions sqlVectorLayerOptions() const;


friend class TestQgsQueryResultWidget;

};
@@ -21,7 +21,7 @@
<widget class="QgsCodeEditorSQL" name="mSqlEditor" native="true"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1,2,0,1,1">
<item>
<widget class="QPushButton" name="mClearButton">
<property name="text">
@@ -36,6 +36,13 @@
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="mProgressBar">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -127,7 +134,7 @@
<string/>
</property>
<property name="placeholderText">
<string>Enter the optional SQL filter ro click on the button to open the query builder tool</string>
<string>Enter the optional SQL filter or click on the button to open the query builder tool</string>
</property>
</widget>
</item>

0 comments on commit 357fa9c

Please sign in to comment.