From 7811ad49dcbc76df25d53ec5ae433277de3fda29 Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Thu, 11 Oct 2018 20:22:38 +0200 Subject: [PATCH] Show current database action in status bar and add cancel button This adds a label to the status bar which becomes visible whenever the database is busy. It also specifies the currently running action. Also add a button which allows you to cancel this action at the next opportunity. Note that this doesn't work for the Execute SQL tab yet which requires some more rewriting of the code there. --- src/MainWindow.cpp | 28 ++++++++++++++++++++++++++++ src/MainWindow.h | 15 ++++++++++----- src/icons/cancel.png | Bin 0 -> 587 bytes src/icons/icons.qrc | 1 + src/sqlitedb.cpp | 9 +++++++++ src/sqlitedb.h | 7 +++++++ 6 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 src/icons/cancel.png diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index f6cd0cea20..2b1e514208 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -286,6 +286,20 @@ void MainWindow::init() #endif // Set statusbar fields + statusBusyLabel = new QLabel(ui->statusbar); + statusBusyLabel->setEnabled(false); + statusBusyLabel->setVisible(false); + statusBusyLabel->setToolTip(tr("The database is currenctly busy.")); + ui->statusbar->addPermanentWidget(statusBusyLabel); + + statusStopButton = new QToolButton(ui->statusbar); + statusStopButton->setVisible(false); + statusStopButton->setIcon(QIcon(":icons/cancel")); + statusStopButton->setToolTip(tr("Click here to interrupt the currently running query.")); + statusStopButton->setMaximumSize(ui->statusbar->geometry().height() - 6, ui->statusbar->geometry().height() - 6); + statusStopButton->setAutoRaise(true); + ui->statusbar->addPermanentWidget(statusStopButton); + statusEncryptionLabel = new QLabel(ui->statusbar); statusEncryptionLabel->setEnabled(false); statusEncryptionLabel->setVisible(false); @@ -316,6 +330,11 @@ void MainWindow::init() ui->editDeleteObjectAction->setToolTip(ui->editDeleteObjectAction->text()); }); + // When clicking the interrupt query button in the status bar, ask SQLite to interrupt the current query + connect(statusStopButton, &QToolButton::clicked, [this]() { + db.interruptQuery(); + }); + // Connect some more signals and slots connect(ui->dataTable->filterHeader(), SIGNAL(sectionClicked(int)), this, SLOT(browseTableHeaderClicked(int))); connect(ui->dataTable->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(setRecordsetLabel())); @@ -332,6 +351,8 @@ void MainWindow::init() connect(ui->dataTable, &ExtendedTableWidget::selectedRowsToBeDeleted, this, &MainWindow::deleteRecord); connect(ui->actionDropQualifiedCheck, &QAction::toggled, dbStructureModel, &DbStructureModel::setDropQualifiedNames); connect(ui->actionEnquoteNamesCheck, &QAction::toggled, dbStructureModel, &DbStructureModel::setDropEnquotedNames); + connect(&db, &DBBrowserDB::databaseInUseChanged, this, &MainWindow::updateDatabaseBusyStatus); + ui->actionDropQualifiedCheck->setChecked(Settings::getValue("SchemaDock", "dropQualifiedNames").toBool()); ui->actionEnquoteNamesCheck->setChecked(Settings::getValue("SchemaDock", "dropEnquotedNames").toBool()); @@ -3541,3 +3562,10 @@ void MainWindow::printDbStructure () delete dialog; delete document; } + +void MainWindow::updateDatabaseBusyStatus(bool busy, const QString& user) +{ + statusBusyLabel->setText(tr("Busy (%1)").arg(user)); + statusBusyLabel->setVisible(busy); + statusStopButton->setVisible(busy); +} diff --git a/src/MainWindow.h b/src/MainWindow.h index 62f484d6c4..7c40694df3 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -7,12 +7,7 @@ #include #include -class QDragEnterEvent; class EditDialog; -class QIntValidator; -class QLabel; -class QModelIndex; -class QPersistentModelIndex; class SqliteTableModel; class DbStructureModel; class RemoteDock; @@ -20,6 +15,13 @@ class RemoteDatabase; class FindReplaceDialog; class ExtendedTableWidget; +class QDragEnterEvent; +class QIntValidator; +class QModelIndex; +class QLabel; +class QPersistentModelIndex; +class QToolButton; + namespace Ui { class MainWindow; } @@ -157,6 +159,8 @@ class MainWindow : public QMainWindow QLabel* statusEncodingLabel; QLabel* statusEncryptionLabel; QLabel* statusReadOnlyLabel; + QToolButton* statusStopButton; + QLabel* statusBusyLabel; DbStructureModel* dbStructureModel; @@ -301,6 +305,7 @@ private slots: void updateInsertDeleteRecordButton(); void runSqlNewTab(const QString& query, const QString& title); void printDbStructure(); + void updateDatabaseBusyStatus(bool busy, const QString& user); }; #endif diff --git a/src/icons/cancel.png b/src/icons/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..c149c2bc017d5ce5a8ae9330dd7dbd012482e0f4 GIT binary patch literal 587 zcmV-R0<`^!P)FS^-G}e*;M)Q6>s#cP zI`Y#S($G6W`W@NI5g|L-MKl0Zmu$m^(0~^Lwo5OO~d#(vPfztext_indent.png printer.png package_save.png + cancel.png diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp index 49fe84b6fc..aabd40a0ee 100644 --- a/src/sqlitedb.cpp +++ b/src/sqlitedb.cpp @@ -608,6 +608,7 @@ DBBrowserDB::db_pointer_type DBBrowserDB::get(QString user) db_user = user; db_used = true; + emit databaseInUseChanged(true, user); return db_pointer_type(_db, DatabaseReleaser(this)); } @@ -1871,3 +1872,11 @@ QString DBBrowserDB::generateTemporaryTableName(const QString& schema) const return table_name; } } + +void DBBrowserDB::interruptQuery() +{ + if(!_db) + return; + + sqlite3_interrupt(_db); +} diff --git a/src/sqlitedb.h b/src/sqlitedb.h index 027fa40ee5..ef80548c04 100644 --- a/src/sqlitedb.h +++ b/src/sqlitedb.h @@ -48,6 +48,7 @@ class DBBrowserDB : public QObject std::unique_lock lk(pParent->m); pParent->db_used = false; lk.unlock(); + emit pParent->databaseInUseChanged(false, QString()); pParent->cv.notify_one(); } }; @@ -111,6 +112,11 @@ class DBBrowserDB : public QObject */ bool getRow(const sqlb::ObjectIdentifier& table, const QString& rowid, QVector& rowdata); + /** + * @brief Interrupts the currenty running statement as soon as possible. + */ + void interruptQuery(); + private: /** * @brief max Queries the table t for the max value of field. @@ -202,6 +208,7 @@ class DBBrowserDB : public QObject void dbChanged(bool dirty); void structureUpdated(); void requestCollation(QString name, int eTextRep); + void databaseInUseChanged(bool busy, QString user); private: /// external code needs to go through get() to obtain access to the database