From 3cd5792cea917f790e219e8563c2f4d0d069e91f Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Sun, 7 Apr 2013 17:30:35 +0200 Subject: [PATCH] More improvements and fixes to the new SqliteTableModel Change the way sorting is done to correctly sort all data even if it hasn't been loaded completely yet. Fix the navigation label and buttons by showing the correct information again and fixing the validator of the input field. Log all SQL statements executed from within the SqliteTableModel. Silence a few warnings. --- src/MainWindow.cpp | 62 ++++++++++++++++++++++++---------------- src/MainWindow.h | 2 -- src/sqlitetablemodel.cpp | 31 ++++++++++++++++++-- src/sqlitetablemodel.h | 6 +++- 4 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 22219fcd..62f0932a 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -29,12 +29,12 @@ MainWindow::MainWindow(QWidget* parent) ui(new Ui::MainWindow), browseTableModel(new QStandardItemModel(this)), m_browseTableModel(new SqliteTableModel(this, &db)), - m_browseTableSortProxy(new QSortFilterProxyModel(this)), sqliteHighlighterTabSql(0), sqliteHighlighterLogUser(0), sqliteHighlighterLogApp(0), editWin(new EditDialog(this)), - findWin(0) + findWin(0), + gotoValidator(new QIntValidator(0, 0, this)) { ui->setupUi(this); init(); @@ -59,16 +59,14 @@ void MainWindow::init() ui->dbTreeWidget->setColumnHidden(1, true); ui->dbTreeWidget->setColumnWidth(0, 300); - // Create the validator for the goto line edit - gotoValidator = new QIntValidator(0, 0, this); + // Set the validator for the goto line edit ui->editGoto->setValidator(gotoValidator); // Create the SQL sytax highlighters createSyntaxHighlighters(); // Set up DB models - m_browseTableSortProxy->setSourceModel(m_browseTableModel); - ui->dataTable->setModel(m_browseTableSortProxy); + ui->dataTable->setModel(m_browseTableModel); queryResultListModel = new QStandardItemModel(this); ui->queryResultTableView->setModel(queryResultListModel); @@ -284,7 +282,7 @@ void MainWindow::populateTable( const QString & tablename) // Reset sorting curBrowseOrderByIndex = 1; curBrowseOrderByMode = Qt::AscendingOrder; - m_browseTableSortProxy->sort(curBrowseOrderByIndex, curBrowseOrderByMode); + m_browseTableModel->sort(curBrowseOrderByIndex, curBrowseOrderByMode); // Get table layout db.browseTable(tablename); @@ -295,6 +293,9 @@ void MainWindow::populateTable( const QString & tablename) ui->buttonDeleteRecord->setEnabled(is_table); ui->dataTable->setEditTriggers(is_table ? QAbstractItemView::DoubleClicked | QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed : QAbstractItemView::NoEditTriggers); + // Set the recordset label + setRecordsetLabel(); + //got to keep findWin in synch if(findWin) findWin->resetFields(); @@ -321,7 +322,7 @@ void MainWindow::resetBrowser() ui->comboBrowseTable->setCurrentIndex(pos); curBrowseOrderByIndex = 1; curBrowseOrderByMode = Qt::AscendingOrder; - m_browseTableSortProxy->sort(curBrowseOrderByIndex, curBrowseOrderByMode); + m_browseTableModel->sort(curBrowseOrderByIndex, curBrowseOrderByMode); populateTable(ui->comboBrowseTable->currentText()); } @@ -463,14 +464,15 @@ void MainWindow::updateTableView(int lineToSelect, bool keepColumnWidths) // if (lineToSelect!=-1){ // selectTableLine(lineToSelect); // } -// setRecordsetLabel(); + + setRecordsetLabel(); QApplication::restoreOverrideCursor(); } void MainWindow::selectTableLine(int lineToSelect) { ui->dataTable->clearSelection(); - ui->dataTable->selectRow(m_browseTableSortProxy->mapFromSource(m_browseTableModel->index(lineToSelect, 0)).row()); + ui->dataTable->selectRow(lineToSelect); ui->dataTable->scrollTo(ui->dataTable->currentIndex()); } @@ -478,41 +480,51 @@ void MainWindow::navigatePrevious() { int curRow = ui->dataTable->currentIndex().row(); curRow -= 100; - if(curRow < 0) curRow = 0; - updateTableView(curRow); + if(curRow < 0) + curRow = 0; + selectTableLine(curRow); } void MainWindow::navigateNext() { + // TODO: Fetch more data from DB if necessary + int curRow = ui->dataTable->currentIndex().row(); curRow += 100; - if(curRow >= browseTableModel->rowCount()) - curRow = browseTableModel->rowCount()-1; - updateTableView(curRow); + if(curRow >= m_browseTableModel->totalRowCount()) + curRow = m_browseTableModel->totalRowCount() - 1; + selectTableLine(curRow); } void MainWindow::navigateGoto() { - QString typed = ui->editGoto->text(); - bool ok; - int dec = typed.toInt( &ok); - if (dec==0) dec=1; - if (dec>db.getRecordCount()) dec = db.getRecordCount(); + // TODO: Fetch more data from DB if necessary - updateTableView(dec-1); - ui->editGoto->setText(QString::number(dec,10)); + int row = ui->editGoto->text().toInt(); + if(row <= 0) + row = 1; + if(row > m_browseTableModel->totalRowCount()) + row = m_browseTableModel->totalRowCount(); + + selectTableLine(row - 1); + ui->editGoto->setText(QString::number(row)); } void MainWindow::setRecordsetLabel() { + // Get all the numbers, i.e. the number of the first row and the last row as well as the total number of rows int from = ui->dataTable->verticalHeader()->visualIndexAt(0) + 1; int to = ui->dataTable->verticalHeader()->visualIndexAt(ui->dataTable->height()) - 1; - int total = browseTableModel->rowCount(); + int total = m_browseTableModel->totalRowCount(); if(to == -2) to = total; + // Update the validator of the goto row field + gotoValidator->setRange(0, total); + + // Update the label showing the current position ui->labelRecordset->setText(tr("%1 - %2 of %3").arg(from).arg(to).arg(total)); } @@ -684,7 +696,7 @@ void MainWindow::helpAbout() void MainWindow::updateRecordText(int row, int col, const QByteArray& newtext) { - m_browseTableModel->setData(m_browseTableSortProxy->mapToSource(m_browseTableSortProxy->index(row, col)), newtext); + m_browseTableModel->setData(m_browseTableModel->index(row, col), newtext); } void MainWindow::editWinAway() @@ -1111,7 +1123,7 @@ void MainWindow::browseTableHeaderClicked(int logicalindex) // instead of the column name we just use the column index, +2 because 'rowid, *' is the projection curBrowseOrderByIndex = logicalindex; curBrowseOrderByMode = curBrowseOrderByMode == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder; - m_browseTableSortProxy->sort(curBrowseOrderByIndex, curBrowseOrderByMode); + m_browseTableModel->sort(curBrowseOrderByIndex, curBrowseOrderByMode); // select the first item in the column so the header is bold // we might try to select the last selected item diff --git a/src/MainWindow.h b/src/MainWindow.h index 9f1fb7f8..ecfcb057 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -13,7 +13,6 @@ class QIntValidator; class QLabel; class QModelIndex; class SqliteTableModel; -class QSortFilterProxyModel; namespace Ui { class MainWindow; @@ -53,7 +52,6 @@ private: QStandardItemModel *browseTableModel; SqliteTableModel* m_browseTableModel; - QSortFilterProxyModel* m_browseTableSortProxy; QStandardItemModel *queryResultListModel; QMenu *popupTableMenu; QMenu *recentFilesMenu; diff --git a/src/sqlitetablemodel.cpp b/src/sqlitetablemodel.cpp index 8c7e9360..a6bc00b2 100644 --- a/src/sqlitetablemodel.cpp +++ b/src/sqlitetablemodel.cpp @@ -8,6 +8,8 @@ SqliteTableModel::SqliteTableModel(QObject* parent, DBBrowserDB* db) , m_db(db) , m_rowCount(0) , m_columnCount(0) + , m_iSortColumn(0) + , m_sSortOrder("ASC") , m_chunkSize(1000) { } @@ -34,6 +36,7 @@ void SqliteTableModel::setQuery(const QString& sQuery) // do a count query to get the full row count in a fast manner QString sCountQuery = QString("SELECT COUNT(*) FROM (%1);").arg(sQuery); + m_db->logSQL(sCountQuery, kLogMsg_App); QByteArray utf8Query = sCountQuery.toUtf8(); int status = sqlite3_prepare_v2(m_db->_db, utf8Query, utf8Query.size(), &stmt, NULL); @@ -53,6 +56,7 @@ void SqliteTableModel::setQuery(const QString& sQuery) m_data.clear(); m_columnCount = 0; QString sLimitQuery = QString("%1 LIMIT 0, %2;").arg(sQuery).arg(m_chunkSize); + m_db->logSQL(sLimitQuery, kLogMsg_App); utf8Query = sLimitQuery.toUtf8(); status = sqlite3_prepare_v2(m_db->_db, utf8Query, utf8Query.size(), &stmt, NULL); @@ -88,6 +92,11 @@ int SqliteTableModel::rowCount(const QModelIndex &parent) const return m_data.size(); // current fetched row count } +int SqliteTableModel::totalRowCount() const +{ + return m_rowCount; +} + int SqliteTableModel::columnCount(const QModelIndex &parent) const { (void)parent; @@ -102,7 +111,7 @@ QVariant SqliteTableModel::headerData(int section, Qt::Orientation orientation, if (orientation == Qt::Horizontal) return m_headers.at(section); else - return QString("Row %1").arg(section); + return QString("%1").arg(section + 1); } QVariant SqliteTableModel::data(const QModelIndex &index, int role) const @@ -139,7 +148,7 @@ bool SqliteTableModel::setData(const QModelIndex& index, const QVariant& value, return false; } -bool SqliteTableModel::canFetchMore(const QModelIndex &parent) const +bool SqliteTableModel::canFetchMore(const QModelIndex&) const { return m_data.size() < m_rowCount; } @@ -149,6 +158,7 @@ void SqliteTableModel::fetchMore(const QModelIndex& parent) int currentsize = m_data.size(); int row = m_data.size(); QString sLimitQuery = QString("%1 LIMIT %2, %3;").arg(m_sQuery).arg(row).arg(row + m_chunkSize); + m_db->logSQL(sLimitQuery, kLogMsg_App); QByteArray utf8Query = sLimitQuery.toUtf8(); sqlite3_stmt *stmt; int status = sqlite3_prepare_v2(m_db->_db, utf8Query, utf8Query.size(), &stmt, NULL); @@ -181,3 +191,20 @@ Qt::ItemFlags SqliteTableModel::flags(const QModelIndex& index) const return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; } + +void SqliteTableModel::sort(int column, Qt::SortOrder order) +{ + // Save sort order + m_iSortColumn = column; + m_sSortOrder = (order == Qt::AscendingOrder ? "ASC" : "DESC"); + + // Set the new query (but only if a table has already been set + if(m_sTable != "") + { + setQuery(QString("SELECT * FROM `%1` ORDER BY `%2` %3") + .arg(m_sTable) + .arg(m_headers.at(m_iSortColumn)) + .arg(m_sSortOrder) + ); + } +} diff --git a/src/sqlitetablemodel.h b/src/sqlitetablemodel.h index 35614564..bed548d3 100644 --- a/src/sqlitetablemodel.h +++ b/src/sqlitetablemodel.h @@ -13,6 +13,7 @@ public: explicit SqliteTableModel(QObject *parent = 0, DBBrowserDB* db = 0); int rowCount(const QModelIndex &parent) const; + int totalRowCount() const; int columnCount(const QModelIndex &parent) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant data(const QModelIndex &index, int role) const; @@ -24,13 +25,13 @@ public: void setQuery(const QString& sQuery); void setTable(const QString& table); void setChunkSize(size_t chunksize); + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); Qt::ItemFlags flags(const QModelIndex& index) const; signals: public slots: - private: DBBrowserDB* m_db; @@ -38,8 +39,11 @@ private: int m_columnCount; QStringList m_headers; QMap m_data; + QString m_sQuery; QString m_sTable; + int m_iSortColumn; + QString m_sSortOrder; size_t m_chunkSize; };