From 11ace1efa6289dd3b40399f28c7dbeda2c8840e0 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 52082a33..560cc713 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -311,6 +311,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); @@ -341,6 +355,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())); @@ -357,6 +376,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()); @@ -3682,3 +3703,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 ebb80fb8..1eaef302 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -10,12 +10,7 @@ #include #include -class QDragEnterEvent; class EditDialog; -class QIntValidator; -class QLabel; -class QModelIndex; -class QPersistentModelIndex; class SqliteTableModel; class DbStructureModel; class RemoteDock; @@ -23,6 +18,13 @@ class RemoteDatabase; class FindReplaceDialog; class ExtendedTableWidget; +class QDragEnterEvent; +class QIntValidator; +class QModelIndex; +class QLabel; +class QPersistentModelIndex; +class QToolButton; + namespace Ui { class MainWindow; } @@ -158,6 +160,8 @@ private: QLabel* statusEncodingLabel; QLabel* statusEncryptionLabel; QLabel* statusReadOnlyLabel; + QToolButton* statusStopButton; + QLabel* statusBusyLabel; DbStructureModel* dbStructureModel; @@ -306,6 +310,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 9aaf1ab2..5fb7f4b0 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)); } @@ -1896,3 +1897,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 677b266e..554ed79b 100644 --- a/src/sqlitedb.h +++ b/src/sqlitedb.h @@ -48,6 +48,7 @@ private: 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 @@ public: */ 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 @@ signals: 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