1+ #include < iostream>
2+
13#include " MainWindow.h"
24#include " ui_MainWindow.h"
35
5759MainWindow::MainWindow (QWidget* parent)
5860 : QMainWindow(parent),
5961 ui(new Ui::MainWindow),
62+ db(),
6063 m_browseTableModel(new SqliteTableModel(db, this , Settings::getValue(" db" , " prefetchsize" ).toInt())),
6164 m_currentTabTableModel(m_browseTableModel),
6265 m_remoteDb(new RemoteDatabase),
@@ -292,6 +295,11 @@ void MainWindow::init()
292295 connect (m_browseTableModel, &SqliteTableModel::finishedFetch, this , &MainWindow::setRecordsetLabel);
293296 connect (ui->dataTable , &ExtendedTableWidget::selectedRowsToBeDeleted, this , &MainWindow::deleteRecord);
294297
298+ connect (m_browseTableModel, &SqliteTableModel::finishedFetch, [this ](){
299+ auto & settings = browseTableSettings[currentlyBrowsedTableName ()];
300+ plotDock->updatePlot (m_browseTableModel, &settings, true , true );
301+ });
302+
295303 // Lambda function for keyboard shortcuts for selecting next/previous table in Browse Data tab
296304 connect (ui->dataTable , &ExtendedTableWidget::switchTable, [this ](bool next) {
297305 int index = ui->comboBrowseTable ->currentIndex ();
@@ -505,13 +513,18 @@ void MainWindow::populateTable()
505513 {
506514 connect (ui->dataTable ->selectionModel (), SIGNAL (currentChanged (QModelIndex,QModelIndex)), this , SLOT (dataTableSelectionChanged (QModelIndex)));
507515
508- // Lambda function for updating the delete record button to reflect number of selected records
516+ // Lambda function for updating the delete record button to reflect number of selected records. -- TODO actual
517+ // call this once to disable Delete button...
509518 connect (ui->dataTable ->selectionModel (), &QItemSelectionModel::selectionChanged, [this ](const QItemSelection&, const QItemSelection&) {
510- // NOTE: We're assuming here that the selection is always contiguous, i.e. that there are never two selected rows with a non-selected
511- // row in between.
519+ // NOTE: We're assuming here that the selection is always contiguous, i.e. that there are never two selected
520+ // rows with a non-selected row in between.
512521 int rows = 0 ;
513- if (ui->dataTable ->selectionModel ()->selectedIndexes ().count ())
514- rows = ui->dataTable ->selectionModel ()->selectedIndexes ().last ().row () - ui->dataTable ->selectionModel ()->selectedIndexes ().first ().row () + 1 ;
522+
523+ const auto & sel = ui->dataTable ->selectionModel ()->selectedIndexes ();
524+ if (sel.count ())
525+ rows = sel.last ().row () - sel.first ().row () + 1 ;
526+
527+ ui->buttonDeleteRecord ->setEnabled (rows != 0 );
515528
516529 if (rows > 1 )
517530 ui->buttonDeleteRecord ->setText (tr (" Delete records" ));
@@ -552,6 +565,8 @@ void MainWindow::populateTable()
552565 // Encoding
553566 m_browseTableModel->setEncoding (defaultBrowseTableEncoding);
554567
568+ setRecordsetLabel ();
569+
555570 // Plot
556571 attachPlot (ui->dataTable , m_browseTableModel, &browseTableSettings[tablename]);
557572
@@ -609,6 +624,8 @@ void MainWindow::populateTable()
609624 // Encoding
610625 m_browseTableModel->setEncoding (storedData.encoding );
611626
627+ setRecordsetLabel ();
628+
612629 // Plot
613630 attachPlot (ui->dataTable , m_browseTableModel, &browseTableSettings[tablename], false );
614631 }
@@ -710,8 +727,8 @@ void MainWindow::deleteRecord()
710727 }
711728 }
712729
713- if (old_row > m_browseTableModel->totalRowCount ())
714- old_row = m_browseTableModel->totalRowCount ();
730+ if (old_row > m_browseTableModel->rowCount ())
731+ old_row = m_browseTableModel->rowCount ();
715732 selectTableLine (old_row);
716733 } else {
717734 QMessageBox::information ( this , QApplication::applicationName (), tr (" Please select a record first" ));
@@ -750,8 +767,8 @@ void MainWindow::navigateNext()
750767{
751768 int curRow = ui->dataTable ->currentIndex ().row ();
752769 curRow += ui->dataTable ->numVisibleRows () - 1 ;
753- if (curRow >= m_browseTableModel->totalRowCount ())
754- curRow = m_browseTableModel->totalRowCount () - 1 ;
770+ if (curRow >= m_browseTableModel->rowCount ())
771+ curRow = m_browseTableModel->rowCount () - 1 ;
755772 selectTableLine (curRow);
756773}
757774
@@ -762,7 +779,7 @@ void MainWindow::navigateBegin()
762779
763780void MainWindow::navigateEnd ()
764781{
765- selectTableLine (m_browseTableModel->totalRowCount ()-1 );
782+ selectTableLine (m_browseTableModel->rowCount ()-1 );
766783}
767784
768785
@@ -771,8 +788,8 @@ void MainWindow::navigateGoto()
771788 int row = ui->editGoto ->text ().toInt ();
772789 if (row <= 0 )
773790 row = 1 ;
774- if (row > m_browseTableModel->totalRowCount ())
775- row = m_browseTableModel->totalRowCount ();
791+ if (row > m_browseTableModel->rowCount ())
792+ row = m_browseTableModel->rowCount ();
776793
777794 selectTableLine (row - 1 );
778795 ui->editGoto ->setText (QString::number (row));
@@ -782,7 +799,7 @@ void MainWindow::setRecordsetLabel()
782799{
783800 // Get all the numbers, i.e. the number of the first row and the last row as well as the total number of rows
784801 int from = ui->dataTable ->verticalHeader ()->visualIndexAt (0 ) + 1 ;
785- int total = m_browseTableModel->totalRowCount ();
802+ int total = m_browseTableModel->rowCount ();
786803 int to = ui->dataTable ->verticalHeader ()->visualIndexAt (ui->dataTable ->height ()) - 1 ;
787804 if (to == -2 )
788805 to = total;
@@ -791,7 +808,23 @@ void MainWindow::setRecordsetLabel()
791808 gotoValidator->setRange (0 , total);
792809
793810 // Update the label showing the current position
794- ui->labelRecordset ->setText (tr (" %1 - %2 of %3" ).arg (from).arg (to).arg (total));
811+ QString txt;
812+ switch (m_browseTableModel->rowCountAvailable ())
813+ {
814+ case SqliteTableModel::RowCount::Unknown:
815+ txt = tr (" determining row count..." );
816+ break ;
817+ case SqliteTableModel::RowCount::Partial:
818+ txt = tr (" %1 - %2 of >= %3" ).arg (from).arg (to).arg (total);
819+ break ;
820+ case SqliteTableModel::RowCount::Complete:
821+ default :
822+ txt = tr (" %1 - %2 of %3" ).arg (from).arg (to).arg (total);
823+ break ;
824+ }
825+ ui->labelRecordset ->setText (txt);
826+
827+ ui->dataTable ->setDisabled ( m_browseTableModel->rowCountAvailable () == SqliteTableModel::RowCount::Unknown );
795828}
796829
797830void MainWindow::refresh ()
@@ -1119,7 +1152,8 @@ void MainWindow::executeQuery()
11191152 // Execute next statement
11201153 int tail_length_before = tail_length;
11211154 const char * qbegin = tail;
1122- sql3status = sqlite3_prepare_v2 (db._db ,tail, tail_length, &vm, &tail);
1155+ auto pDb = db.get (" executing query" );
1156+ sql3status = sqlite3_prepare_v2 (pDb.get (), tail, tail_length, &vm, &tail);
11231157 QString queryPart = QString::fromUtf8 (qbegin, tail - qbegin);
11241158 tail_length -= (tail - qbegin);
11251159 int execution_end_index = execution_start_index + tail_length_before - tail_length;
@@ -1144,12 +1178,20 @@ void MainWindow::executeQuery()
11441178 {
11451179 // If we get here, the SQL statement returns some sort of data. So hand it over to the model for display. Don't set the modified flag
11461180 // because statements that display data don't change data as well.
1181+ pDb = nullptr ;
11471182
1148- sqlWidget->getModel ()->setQuery (queryPart);
1183+ auto * model = sqlWidget->getModel ();
1184+ model->setQuery (queryPart);
1185+
1186+ // Wait until the initial loading of data (= first chunk and row count) has been performed. I have the
1187+ // feeling that a lot of stuff would need rewriting if we wanted to become more asynchronous here:
1188+ // essentially the entire loop over the commands would need to be signal-driven.
1189+ model->waitUntilIdle ();
1190+ qApp->processEvents (); // to make row count available
11491191
11501192 // The query takes the last placeholder as it may itself contain the sequence '%' + number
11511193 statusMessage = tr (" %1 rows returned in %2ms from: %3" ).arg (
1152- sqlWidget-> getModel ()-> totalRowCount ()).arg (timer.elapsed ()).arg (queryPart.trimmed ());
1194+ model-> rowCount ()).arg (timer.elapsed ()).arg (queryPart.trimmed ());
11531195 ok = true ;
11541196 ui->actionSqlResultsSave ->setEnabled (true );
11551197 ui->actionSqlResultsSaveAsView ->setEnabled (!db.readOnly ());
@@ -1165,7 +1207,7 @@ void MainWindow::executeQuery()
11651207
11661208 QString stmtHasChangedDatabase;
11671209 if (query_part_type == InsertStatement || query_part_type == UpdateStatement || query_part_type == DeleteStatement)
1168- stmtHasChangedDatabase = tr (" , %1 rows affected" ).arg (sqlite3_changes (db. _db ));
1210+ stmtHasChangedDatabase = tr (" , %1 rows affected" ).arg (sqlite3_changes (pDb. get () ));
11691211
11701212 // Attach/Detach statements don't modify the original database
11711213 if (query_part_type != StatementType::AttachStatement && query_part_type != StatementType::DetachStatement)
@@ -1178,18 +1220,20 @@ void MainWindow::executeQuery()
11781220 case SQLITE_MISUSE:
11791221 continue ;
11801222 default :
1181- statusMessage = QString::fromUtf8 (sqlite3_errmsg (db. _db )) + " : " + queryPart;
1223+ statusMessage = QString::fromUtf8 (sqlite3_errmsg (pDb. get () )) + " : " + queryPart;
11821224 ok = true ;
11831225 break ;
11841226 }
11851227 timer.restart ();
11861228 } else {
1187- statusMessage = QString::fromUtf8 (sqlite3_errmsg (db. _db )) + " : " + queryPart;
1229+ statusMessage = QString::fromUtf8 (sqlite3_errmsg (pDb. get () )) + " : " + queryPart;
11881230 sqlWidget->getEditor ()->setErrorIndicator (execution_start_line, execution_start_index, execution_start_line, execution_end_index);
11891231 ok = false ;
11901232
11911233 }
11921234
1235+ pDb = nullptr ; // release db
1236+
11931237 execution_start_index = execution_end_index;
11941238
11951239 // Revert to save point now if it wasn't needed. We need to do this here because there are some rare cases where the next statement might
@@ -1206,6 +1250,7 @@ void MainWindow::executeQuery()
12061250 // Process events to keep the UI responsive
12071251 qApp->processEvents ();
12081252 }
1253+
12091254 sqlWidget->finishExecution (statusMessage, ok);
12101255 attachPlot (sqlWidget->getTableResult (), sqlWidget->getModel ());
12111256
@@ -2907,8 +2952,10 @@ void MainWindow::requestCollation(const QString& name, int eTextRep)
29072952 " that this application can't provide without further knowledge.\n "
29082953 " If you choose to proceed, be aware bad things can happen to your database.\n "
29092954 " Create a backup!" ).arg (name), QMessageBox::Yes | QMessageBox::No);
2910- if (reply == QMessageBox::Yes)
2911- sqlite3_create_collation (db._db , name.toUtf8 (), eTextRep, nullptr , collCompare);
2955+ if (reply == QMessageBox::Yes) {
2956+ auto pDb = db.get (" creating collation" );
2957+ sqlite3_create_collation (pDb.get (), name.toUtf8 (), eTextRep, nullptr , collCompare);
2958+ }
29122959}
29132960
29142961void MainWindow::renameSqlTab (int index)
0 commit comments