mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-01-19 18:40:13 -06:00
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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<int, QStringList> m_data;
|
||||
|
||||
QString m_sQuery;
|
||||
QString m_sTable;
|
||||
int m_iSortColumn;
|
||||
QString m_sSortOrder;
|
||||
|
||||
size_t m_chunkSize;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user