Skip to content

Commit

Permalink
Save filter settings and sort order for each table
Browse files Browse the repository at this point in the history
When changing the table in the Browse Data tab we used to remember the
column widths for that particular table. When changing the tab and then
coming back or when pressing the refresh button we used to save the
filters (but not for a table change). The sort order wasn't remembered
at all. I think this behaviour doesn't make any sense.

With this patch we remember column widths, sort order and filter values
for each table individually and restore it when the user switches back to
the table. All the settings are handled the same way and as much
information as possible is stored. It gets also saved in our project
file format.
  • Loading branch information
MKleusberg committed Jul 4, 2015
1 parent 1696ad1 commit 748f06d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 57 deletions.
9 changes: 1 addition & 8 deletions src/FilterTableHeader.cpp
Expand Up @@ -57,16 +57,11 @@ FilterTableHeader::FilterTableHeader(QTableView* parent) :
connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(adjustPositions()));
}

void FilterTableHeader::generateFilters(int number, bool bKeepValues)
void FilterTableHeader::generateFilters(int number)
{
// Delete all the current filter widgets
QStringList oldvalues;
for(int i=0;i < filterWidgets.size(); ++i)
{
if(bKeepValues)
oldvalues << filterWidgets.at(i)->text();
delete filterWidgets.at(i);
}
filterWidgets.clear();

// And generate a bunch of new ones
Expand All @@ -75,8 +70,6 @@ void FilterTableHeader::generateFilters(int number, bool bKeepValues)
FilterLineEdit* l = new FilterLineEdit(this, &filterWidgets, i);
l->setVisible(i>0); // This hides the first input widget which belongs to the hidden rowid column
connect(l, SIGNAL(textChanged(QString)), this, SLOT(inputChanged(QString)));
if(bKeepValues && oldvalues.size() > i && !oldvalues[i].isEmpty()) // restore old values
l->setText(oldvalues[i]);
filterWidgets.push_back(l);
}

Expand Down
2 changes: 1 addition & 1 deletion src/FilterTableHeader.h
Expand Up @@ -17,7 +17,7 @@ class FilterTableHeader : public QHeaderView
virtual QSize sizeHint() const;

public slots:
void generateFilters(int number, bool bKeepValues = false);
void generateFilters(int number);
void adjustPositions();
void clearFilters();
void setFilter(int column, const QString& value);
Expand Down
92 changes: 48 additions & 44 deletions src/MainWindow.cpp
Expand Up @@ -303,7 +303,7 @@ void MainWindow::populateStructure()
ui->dbTreeWidget->resizeColumnToContents(3);
}

void MainWindow::populateTable(const QString & tablename, bool bKeepFilter)
void MainWindow::populateTable(const QString& tablename)
{
// Remove the model-view link if the table name is empty in order to remove any data from the view
if(ui->comboBrowseTable->model()->rowCount() == 0 && tablename.isEmpty())
Expand All @@ -323,27 +323,40 @@ void MainWindow::populateTable(const QString & tablename, bool bKeepFilter)
m_browseTableModel->setTable(tablename);
ui->dataTable->setColumnHidden(0, true);

// Restore column widths
QMap<QString, QMap<int, int> >::ConstIterator colWidthsIt;
if((colWidthsIt = browseTableColumnWidths.constFind(tablename)) != browseTableColumnWidths.constEnd())
// Update the filter row
qobject_cast<FilterTableHeader*>(ui->dataTable->horizontalHeader())->generateFilters(m_browseTableModel->columnCount());

// Restore table settings
QMap<QString, BrowseDataTableSettings>::ConstIterator tableIt;
if((tableIt = browseTableSettings.constFind(tablename)) != browseTableSettings.constEnd())
{
// There are some column widths stored for this table
for(QMap<int, int>::ConstIterator it=colWidthsIt.value().constBegin();it!=colWidthsIt.value().constEnd();++it)
ui->dataTable->setColumnWidth(it.key(), it.value());
// There is information stored for this table, so extract it and apply it

// Column widths
for(QMap<int, int>::ConstIterator widthIt=tableIt.value().columnWidths.constBegin();widthIt!=tableIt.value().columnWidths.constEnd();++widthIt)
ui->dataTable->setColumnWidth(widthIt.key(), widthIt.value());

// Sorting
m_browseTableModel->sort(tableIt.value().sortOrderIndex, tableIt.value().sortOrderMode);
ui->dataTable->filterHeader()->setSortIndicator(tableIt.value().sortOrderIndex, tableIt.value().sortOrderMode);

// Filters
FilterTableHeader* filterHeader = qobject_cast<FilterTableHeader*>(ui->dataTable->horizontalHeader());
for(QMap<int, QString>::ConstIterator filterIt=tableIt.value().filterValues.constBegin();filterIt!=tableIt.value().filterValues.constEnd();++filterIt)
filterHeader->setFilter(filterIt.key(), filterIt.value());
} else {
// There aren't any column widths stored for this table yet, so set default widths
// There aren't any information stored for this table yet, so use some default values

// Column widths
for(int i=1;i<m_browseTableModel->columnCount();i++)
ui->dataTable->setColumnWidth(i, ui->dataTable->horizontalHeader()->defaultSectionSize());
}

// Reset sorting
curBrowseOrderByIndex = 0;
curBrowseOrderByMode = Qt::AscendingOrder;
m_browseTableModel->sort(curBrowseOrderByIndex, curBrowseOrderByMode);
ui->dataTable->filterHeader()->setSortIndicator(curBrowseOrderByIndex, curBrowseOrderByMode);
// Sorting
m_browseTableModel->sort(0, Qt::AscendingOrder);
ui->dataTable->filterHeader()->setSortIndicator(0, Qt::AscendingOrder);

// Update the filter row
qobject_cast<FilterTableHeader*>(ui->dataTable->horizontalHeader())->generateFilters(m_browseTableModel->columnCount(), bKeepFilter);
// The filters can be left empty as they are
}

// Activate the add and delete record buttons and editing only if a table has been selected
bool is_table = db.getObjectByName(tablename).gettype() == "table";
Expand Down Expand Up @@ -391,10 +404,7 @@ void MainWindow::resetBrowser()
int pos = ui->comboBrowseTable->findText(sCurrentTable);
pos = pos == -1 ? 0 : pos;
ui->comboBrowseTable->setCurrentIndex(pos);
curBrowseOrderByIndex = 0;
curBrowseOrderByMode = Qt::AscendingOrder;
m_browseTableModel->sort(curBrowseOrderByIndex, curBrowseOrderByMode);
populateTable(ui->comboBrowseTable->currentText(), true);
populateTable(ui->comboBrowseTable->currentText());
}

void MainWindow::fileClose()
Expand All @@ -413,8 +423,8 @@ void MainWindow::fileClose()
m_browseTableModel = new SqliteTableModel(this, &db, PreferencesDialog::getSettingsValue("db", "prefetchsize").toInt());
connect(ui->dataTable->filterHeader(), SIGNAL(filterChanged(int,QString)), this, SLOT(updateFilter(int,QString)));

// Remove all stored column widths for the browse data table
browseTableColumnWidths.clear();
// Remove all stored table information browse data tab
browseTableSettings.clear();

// Manually update the recordset label inside the Browse tab now
setRecordsetLabel();
Expand Down Expand Up @@ -555,7 +565,7 @@ void MainWindow::setRecordsetLabel()

void MainWindow::browseRefresh()
{
populateTable(ui->comboBrowseTable->currentText(), true);
populateTable(ui->comboBrowseTable->currentText());
}

void MainWindow::createTable()
Expand Down Expand Up @@ -1122,9 +1132,10 @@ void MainWindow::browseTableHeaderClicked(int logicalindex)
return;

// 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;
ui->dataTable->sortByColumn(curBrowseOrderByIndex, curBrowseOrderByMode);
BrowseDataTableSettings& settings = browseTableSettings[ui->comboBrowseTable->currentText()];
settings.sortOrderIndex = logicalindex;
settings.sortOrderMode = settings.sortOrderMode == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder;
ui->dataTable->sortByColumn(settings.sortOrderIndex, settings.sortOrderMode);

// select the first item in the column so the header is bold
// we might try to select the last selected item
Expand Down Expand Up @@ -1773,15 +1784,15 @@ void MainWindow::updateBrowseDataColumnWidth(int section, int /*old_size*/, int
QString tableName(ui->comboBrowseTable->currentText());
if (!selectedCols.contains(section))
{
browseTableColumnWidths[tableName][section] = new_size;
browseTableSettings[tableName].columnWidths[section] = new_size;
}
else
{
ui->dataTable->blockSignals(true);
foreach (int col, selectedCols)
{
ui->dataTable->setColumnWidth(col, new_size);
browseTableColumnWidths[tableName][col] = new_size;
browseTableSettings[tableName].columnWidths[col] = new_size;
}
ui->dataTable->blockSignals(false);
}
Expand Down Expand Up @@ -1865,18 +1876,14 @@ bool MainWindow::loadProject(QString filename)
// Currently selected table
ui->comboBrowseTable->setCurrentIndex(ui->comboBrowseTable->findText(xml.attributes().value("name").toString()));
xml.skipCurrentElement();
} else if(xml.name() == "column_widths") {
// Column widths
} else if(xml.name() == "browsetable_info") {
QString attrData = xml.attributes().value("data").toString();
QByteArray temp = QByteArray::fromBase64(attrData.toUtf8());
QDataStream stream(temp);
stream >> browseTableColumnWidths;
stream >> browseTableSettings;
populateTable(ui->comboBrowseTable->currentText()); // Refresh view
xml.skipCurrentElement();
} else if(xml.name() == "sort") {
// Sort order
ui->dataTable->sortByColumn(xml.attributes().value("column").toString().toInt(),
static_cast<Qt::SortOrder>(xml.attributes().value("order").toString().toInt()));
ui->dataTable->sortByColumn(browseTableSettings[ui->comboBrowseTable->currentText()].sortOrderIndex,
browseTableSettings[ui->comboBrowseTable->currentText()].sortOrderMode);
xml.skipCurrentElement();
}
}
Expand Down Expand Up @@ -1976,18 +1983,14 @@ void MainWindow::saveProject()
xml.writeStartElement("current_table"); // Currently selected table
xml.writeAttribute("name", ui->comboBrowseTable->currentText());
xml.writeEndElement();
{ // Column widths
{ // Table browser information
QByteArray temp;
QDataStream stream(&temp, QIODevice::WriteOnly);
stream << browseTableColumnWidths;
xml.writeStartElement("column_widths");
stream << browseTableSettings;
xml.writeStartElement("browsetable_info");
xml.writeAttribute("data", temp.toBase64());
xml.writeEndElement();
}
xml.writeStartElement("sort"); // Sort order
xml.writeAttribute("column", QString::number(curBrowseOrderByIndex));
xml.writeAttribute("order", QString::number(curBrowseOrderByMode));
xml.writeEndElement();
xml.writeEndElement();

// Execute SQL tab data
Expand Down Expand Up @@ -2027,7 +2030,8 @@ void MainWindow::fileAttach()

void MainWindow::updateFilter(int column, const QString& value)
{
m_browseTableModel->updateFilter(column ,value);
m_browseTableModel->updateFilter(column, value);
browseTableSettings[ui->comboBrowseTable->currentText()].filterValues[column] = value;
setRecordsetLabel();
}

Expand Down
35 changes: 31 additions & 4 deletions src/MainWindow.h
Expand Up @@ -32,6 +32,35 @@ class MainWindow : public QMainWindow

DBBrowserDB* getDb() { return &db; }

struct BrowseDataTableSettings
{
int sortOrderIndex;
Qt::SortOrder sortOrderMode;
QMap<int, int> columnWidths;
QMap<int, QString> filterValues;

friend QDataStream& operator<<(QDataStream& stream, const MainWindow::BrowseDataTableSettings& object)
{
stream << object.sortOrderIndex;
stream << static_cast<int>(object.sortOrderMode);
stream << object.columnWidths;
stream << object.filterValues;

return stream;
}
friend QDataStream& operator>>(QDataStream& stream, MainWindow::BrowseDataTableSettings& object)
{
stream >> object.sortOrderIndex;
int sortordermode;
stream >> sortordermode;
object.sortOrderMode = static_cast<Qt::SortOrder>(sortordermode);
stream >> object.columnWidths;
stream >> object.filterValues;

return stream;
}
};

private:
struct PragmaValues
{
Expand Down Expand Up @@ -79,9 +108,7 @@ class MainWindow : public QMainWindow
QAction *recentFileActs[MaxRecentFiles];
QAction *recentSeparatorAct;

int curBrowseOrderByIndex;
Qt::SortOrder curBrowseOrderByMode;
QMap<QString, QMap<int, int> > browseTableColumnWidths;
QMap<QString, BrowseDataTableSettings> browseTableSettings;

EditDialog* editWin;
QIntValidator* gotoValidator;
Expand Down Expand Up @@ -117,7 +144,7 @@ private slots:
void changeTreeSelection();
void fileNew();
void populateStructure();
void populateTable(const QString& tablename, bool bKeepFilter = false);
void populateTable(const QString& tablename);
void resetBrowser();
void fileClose();
void addRecord();
Expand Down

1 comment on commit 748f06d

@justinclift
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds sensible. 😄

Please sign in to comment.