mirror of
https://github.com/sqlitebrowser/sqlitebrowser.git
synced 2026-02-09 13:18:33 -06:00
Add new option to freeze columns in the Browse Data tab
This adds a new context menu action called "Freeze Columns" to the context menu which appears when you right click the column headers in a Browse Data dock. With this action all columns from the first up to the clicked column are fixed in place when you scroll horizontally. This can be used to make for example the id column always visible. See issue #1888.
This commit is contained in:
@@ -224,7 +224,9 @@ void ExtendedTableWidgetEditorDelegate::updateEditorGeometry(QWidget* editor, co
|
||||
|
||||
|
||||
ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
QTableView(parent)
|
||||
QTableView(parent),
|
||||
m_frozen_table_view(qobject_cast<ExtendedTableWidget*>(parent) ? nullptr : new ExtendedTableWidget(this)),
|
||||
m_frozen_column_count(0)
|
||||
{
|
||||
setHorizontalScrollMode(ExtendedTableWidget::ScrollPerPixel);
|
||||
// Force ScrollPerItem, so scrolling shows all table rows
|
||||
@@ -405,21 +407,81 @@ ExtendedTableWidget::ExtendedTableWidget(QWidget* parent) :
|
||||
selectionModel()->select(QItemSelection(selectionModel()->selectedIndexes().first(), selectionModel()->selectedIndexes().last()), QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
});
|
||||
|
||||
// Set up frozen columns child widget
|
||||
if(m_frozen_table_view)
|
||||
{
|
||||
// Set up widget
|
||||
m_frozen_table_view->setFocusPolicy(Qt::NoFocus);
|
||||
m_frozen_table_view->verticalHeader()->hide();
|
||||
m_frozen_table_view->setStyleSheet("QTableView { border: none; }"
|
||||
"QTableView::item:selected{ background-color: " + palette().color(QPalette::Active, QPalette::Highlight).name() + "}");
|
||||
m_frozen_table_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_frozen_table_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_frozen_table_view->setVerticalScrollMode(verticalScrollMode());
|
||||
viewport()->stackUnder(m_frozen_table_view);
|
||||
m_tableHeader->stackUnder(m_frozen_table_view);
|
||||
|
||||
// Keep both widgets in sync
|
||||
connect(horizontalHeader(), &QHeaderView::sectionResized, this, &ExtendedTableWidget::updateSectionWidth);
|
||||
connect(m_frozen_table_view->horizontalHeader(), &QHeaderView::sectionResized, this, &ExtendedTableWidget::updateSectionWidth);
|
||||
connect(verticalHeader(), &QHeaderView::sectionResized, this, &ExtendedTableWidget::updateSectionHeight);
|
||||
connect(m_frozen_table_view->verticalHeader(), &QHeaderView::sectionResized, this, &ExtendedTableWidget::updateSectionHeight);
|
||||
connect(m_frozen_table_view->verticalScrollBar(), &QAbstractSlider::valueChanged, verticalScrollBar(), &QAbstractSlider::setValue);
|
||||
connect(verticalScrollBar(), &QAbstractSlider::valueChanged, m_frozen_table_view->verticalScrollBar(), &QAbstractSlider::setValue);
|
||||
|
||||
// Forward signals from frozen table view widget to the main table view widget
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::doubleClicked, this, &ExtendedTableWidget::doubleClicked);
|
||||
connect(m_frozen_table_view->filterHeader(), &FilterTableHeader::sectionClicked, filterHeader(), &FilterTableHeader::sectionClicked);
|
||||
connect(m_frozen_table_view->filterHeader(), &QHeaderView::sectionDoubleClicked, filterHeader(), &QHeaderView::sectionDoubleClicked);
|
||||
connect(m_frozen_table_view->verticalHeader(), &QHeaderView::sectionResized, verticalHeader(), &QHeaderView::sectionResized);
|
||||
connect(m_frozen_table_view->horizontalHeader(), &QHeaderView::customContextMenuRequested, horizontalHeader(), &QHeaderView::customContextMenuRequested);
|
||||
connect(m_frozen_table_view->verticalHeader(), &QHeaderView::customContextMenuRequested, verticalHeader(), &QHeaderView::customContextMenuRequested);
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::openFileFromDropEvent, this, &ExtendedTableWidget::openFileFromDropEvent);
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::selectedRowsToBeDeleted, this, &ExtendedTableWidget::selectedRowsToBeDeleted);
|
||||
connect(m_frozen_table_view->filterHeader(), &FilterTableHeader::filterChanged, filterHeader(), &FilterTableHeader::filterChanged);
|
||||
connect(m_frozen_table_view->filterHeader(), &FilterTableHeader::addCondFormat, filterHeader(), &FilterTableHeader::addCondFormat);
|
||||
connect(m_frozen_table_view->filterHeader(), &FilterTableHeader::allCondFormatsCleared, filterHeader(), &FilterTableHeader::allCondFormatsCleared);
|
||||
connect(m_frozen_table_view->filterHeader(), &FilterTableHeader::condFormatsEdited, filterHeader(), &FilterTableHeader::condFormatsEdited);
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::editCondFormats, this, &ExtendedTableWidget::editCondFormats);
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::dataAboutToBeEdited, this, &ExtendedTableWidget::dataAboutToBeEdited);
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::foreignKeyClicked, this, &ExtendedTableWidget::foreignKeyClicked);
|
||||
connect(m_frozen_table_view, &ExtendedTableWidget::currentIndexChanged, this, &ExtendedTableWidget::currentIndexChanged);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) && QT_VERSION < QT_VERSION_CHECK(5, 12, 3)
|
||||
// This work arounds QTBUG-73721 and it is applied only for the affected version range.
|
||||
setWordWrap(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
ExtendedTableWidget::~ExtendedTableWidget()
|
||||
{
|
||||
delete m_frozen_table_view;
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::setModel(QAbstractItemModel* item_model)
|
||||
{
|
||||
// Set model
|
||||
QTableView::setModel(item_model);
|
||||
|
||||
// Set up frozen table view widget
|
||||
if(item_model)
|
||||
setFrozenColumns(m_frozen_column_count);
|
||||
else
|
||||
m_frozen_table_view->hide();
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::reloadSettings()
|
||||
{
|
||||
// Set the new font and font size
|
||||
// We only get the font here to get its metrics. The actual font for the view is set in the model
|
||||
QFont dataBrowserFont(Settings::getValue("databrowser", "font").toString());
|
||||
dataBrowserFont.setPointSize(Settings::getValue("databrowser", "fontsize").toInt());
|
||||
setFont(dataBrowserFont);
|
||||
|
||||
// Set new default row height depending on the font size
|
||||
verticalHeader()->setDefaultSectionSize(verticalHeader()->fontMetrics().height()+10);
|
||||
QFontMetrics fontMetrics(dataBrowserFont);
|
||||
verticalHeader()->setDefaultSectionSize(fontMetrics.height()+10);
|
||||
if(m_frozen_table_view)
|
||||
m_frozen_table_view->reloadSettings();
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::copyMimeData(const QModelIndexList& fromIndices, QMimeData* mimeData, const bool withHeaders, const bool inSQL)
|
||||
@@ -872,13 +934,21 @@ void ExtendedTableWidget::updateGeometries()
|
||||
// Call the parent implementation first - it does most of the actual logic
|
||||
QTableView::updateGeometries();
|
||||
|
||||
// Update frozen columns view too
|
||||
if(m_frozen_table_view)
|
||||
m_frozen_table_view->updateGeometries();
|
||||
|
||||
// Check if a model has already been set yet
|
||||
if(model())
|
||||
{
|
||||
// If so and if it is a SqliteTableModel and if the parent implementation of this method decided that a scrollbar is needed, update its maximum value
|
||||
SqliteTableModel* m = qobject_cast<SqliteTableModel*>(model());
|
||||
if(m && verticalScrollBar()->maximum())
|
||||
{
|
||||
verticalScrollBar()->setMaximum(m->rowCount() - numVisibleRows() + 1);
|
||||
if(m_frozen_table_view)
|
||||
m_frozen_table_view->verticalScrollBar()->setMaximum(verticalScrollBar()->maximum());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1120,3 +1190,125 @@ void ExtendedTableWidget::setToNull(const QModelIndexList& indices)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::setFrozenColumns(size_t count)
|
||||
{
|
||||
if(!m_frozen_table_view)
|
||||
return;
|
||||
|
||||
m_frozen_column_count = count;
|
||||
|
||||
// Set up frozen table view widget
|
||||
m_frozen_table_view->setModel(model());
|
||||
m_frozen_table_view->setSelectionModel(selectionModel());
|
||||
|
||||
// Only show frozen columns in extra table view and copy column widths
|
||||
m_frozen_table_view->horizontalHeader()->blockSignals(true); // Signals need to be blocked because hiding a column would emit resizedSection
|
||||
for(size_t col=0;col<static_cast<size_t>(model()->columnCount());++col)
|
||||
m_frozen_table_view->setColumnHidden(static_cast<int>(col), col >= count);
|
||||
m_frozen_table_view->horizontalHeader()->blockSignals(false);
|
||||
for(int col=0;col<static_cast<int>(count);++col)
|
||||
m_frozen_table_view->setColumnWidth(col, columnWidth(col));
|
||||
|
||||
updateFrozenTableGeometry();
|
||||
|
||||
// Only show extra table view when there are frozen columns to see
|
||||
if(count)
|
||||
m_frozen_table_view->show();
|
||||
else
|
||||
m_frozen_table_view->hide();
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::generateFilters(size_t number, bool show_rowid)
|
||||
{
|
||||
m_tableHeader->generateFilters(number, m_frozen_column_count);
|
||||
|
||||
if(m_frozen_table_view)
|
||||
{
|
||||
size_t frozen_columns = std::min(m_frozen_column_count, number);
|
||||
m_frozen_table_view->m_tableHeader->generateFilters(frozen_columns, show_rowid ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize)
|
||||
{
|
||||
if(!m_frozen_table_view)
|
||||
return;
|
||||
|
||||
if(logicalIndex < static_cast<int>(m_frozen_column_count))
|
||||
{
|
||||
m_frozen_table_view->setColumnWidth(logicalIndex, newSize);
|
||||
setColumnWidth(logicalIndex, newSize);
|
||||
updateFrozenTableGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::updateSectionHeight(int logicalIndex, int /* oldSize */, int newSize)
|
||||
{
|
||||
if(!m_frozen_table_view)
|
||||
return;
|
||||
|
||||
m_frozen_table_view->setRowHeight(logicalIndex, newSize);
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QTableView::resizeEvent(event);
|
||||
updateFrozenTableGeometry();
|
||||
}
|
||||
|
||||
QModelIndex ExtendedTableWidget::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
QModelIndex current = QTableView::moveCursor(cursorAction, modifiers);
|
||||
if(!m_frozen_table_view)
|
||||
return current;
|
||||
|
||||
int width = 0;
|
||||
for(int i=0;i<static_cast<int>(m_frozen_column_count);i++)
|
||||
width += m_frozen_table_view->columnWidth(i);
|
||||
|
||||
if(cursorAction == MoveLeft && current.column() > 0 && visualRect(current).topLeft().x() < width)
|
||||
{
|
||||
const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x() - width;
|
||||
horizontalScrollBar()->setValue(newValue);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::scrollTo(const QModelIndex& index, ScrollHint hint)
|
||||
{
|
||||
if(index.column() >= static_cast<int>(m_frozen_column_count))
|
||||
QTableView::scrollTo(index, hint);
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::updateFrozenTableGeometry()
|
||||
{
|
||||
if(!m_frozen_table_view)
|
||||
return;
|
||||
|
||||
int width = 0;
|
||||
for(int i=0;i<static_cast<int>(m_frozen_column_count);i++)
|
||||
{
|
||||
if(!isColumnHidden(i))
|
||||
width += columnWidth(i);
|
||||
}
|
||||
|
||||
m_frozen_table_view->setGeometry(verticalHeader()->width() + frameWidth(),
|
||||
frameWidth(),
|
||||
width,
|
||||
viewport()->height() + horizontalHeader()->height());
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::setEditTriggers(QAbstractItemView::EditTriggers editTriggers)
|
||||
{
|
||||
QTableView::setEditTriggers(editTriggers);
|
||||
if(m_frozen_table_view)
|
||||
m_frozen_table_view->setEditTriggers(editTriggers);
|
||||
}
|
||||
|
||||
void ExtendedTableWidget::setFilter(size_t column, const QString& value)
|
||||
{
|
||||
filterHeader()->setFilter(column, value);
|
||||
if(m_frozen_table_view)
|
||||
m_frozen_table_view->filterHeader()->setFilter(column, value);
|
||||
}
|
||||
|
||||
@@ -51,8 +51,10 @@ class ExtendedTableWidget : public QTableView
|
||||
|
||||
public:
|
||||
explicit ExtendedTableWidget(QWidget* parent = nullptr);
|
||||
~ExtendedTableWidget() override;
|
||||
|
||||
FilterTableHeader* filterHeader() { return m_tableHeader; }
|
||||
void generateFilters(size_t number, bool show_rowid);
|
||||
|
||||
public:
|
||||
// Get set of selected columns (all cells in column has to be selected)
|
||||
@@ -64,12 +66,19 @@ public:
|
||||
|
||||
void sortByColumns(const std::vector<sqlb::SortedColumn>& columns);
|
||||
|
||||
void setFrozenColumns(size_t count);
|
||||
|
||||
void setModel(QAbstractItemModel* item_model) override;
|
||||
|
||||
void setEditTriggers(QAbstractItemView::EditTriggers editTriggers);
|
||||
|
||||
public slots:
|
||||
void reloadSettings();
|
||||
void selectTableLine(int lineToSelect);
|
||||
void selectTableLines(int firstLine, int count);
|
||||
void selectAll() override;
|
||||
void openPrintDialog();
|
||||
void setFilter(size_t column, const QString& value);
|
||||
|
||||
signals:
|
||||
void foreignKeyClicked(const sqlb::ObjectIdentifier& table, const std::string& column, const QByteArray& value);
|
||||
@@ -95,9 +104,15 @@ private:
|
||||
static std::vector<std::vector<QByteArray>> m_buffer;
|
||||
static QString m_generatorStamp;
|
||||
|
||||
ExtendedTableWidget* m_frozen_table_view;
|
||||
size_t m_frozen_column_count;
|
||||
void updateFrozenTableGeometry();
|
||||
|
||||
private slots:
|
||||
void vscrollbarChanged(int value);
|
||||
void cellClicked(const QModelIndex& index);
|
||||
void updateSectionWidth(int logicalIndex, int oldSize, int newSize);
|
||||
void updateSectionHeight(int logicalIndex, int oldSize, int newSize);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
@@ -107,6 +122,10 @@ protected:
|
||||
void dropEvent(QDropEvent* event) override;
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override;
|
||||
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override;
|
||||
void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible) override;
|
||||
|
||||
FilterTableHeader* m_tableHeader;
|
||||
QMenu* m_contextMenu;
|
||||
ExtendedTableWidgetEditorDelegate* m_editorDelegate;
|
||||
|
||||
@@ -29,7 +29,7 @@ FilterTableHeader::FilterTableHeader(QTableView* parent) :
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
}
|
||||
|
||||
void FilterTableHeader::generateFilters(size_t number, bool showFirst)
|
||||
void FilterTableHeader::generateFilters(size_t number, size_t number_of_hidden_filters)
|
||||
{
|
||||
// Delete all the current filter widgets
|
||||
qDeleteAll(filterWidgets);
|
||||
@@ -39,10 +39,7 @@ void FilterTableHeader::generateFilters(size_t number, bool showFirst)
|
||||
for(size_t i=0;i < number; ++i)
|
||||
{
|
||||
FilterLineEdit* l = new FilterLineEdit(this, &filterWidgets, i);
|
||||
if(!showFirst && i == 0) // This hides the first input widget which belongs to the hidden rowid column
|
||||
l->setVisible(false);
|
||||
else
|
||||
l->setVisible(true);
|
||||
l->setVisible(i >= number_of_hidden_filters);
|
||||
connect(l, &FilterLineEdit::delayedTextChanged, this, &FilterTableHeader::inputChanged);
|
||||
connect(l, &FilterLineEdit::addFilterAsCondFormat, this, &FilterTableHeader::addFilterAsCondFormat);
|
||||
connect(l, &FilterLineEdit::clearAllCondFormats, this, &FilterTableHeader::clearAllCondFormats);
|
||||
@@ -51,7 +48,7 @@ void FilterTableHeader::generateFilters(size_t number, bool showFirst)
|
||||
}
|
||||
|
||||
// Position them correctly
|
||||
adjustPositions();
|
||||
updateGeometries();
|
||||
}
|
||||
|
||||
QSize FilterTableHeader::sizeHint() const
|
||||
@@ -128,3 +125,8 @@ void FilterTableHeader::setFilter(size_t column, const QString& value)
|
||||
if(column < filterWidgets.size())
|
||||
filterWidgets.at(column)->setText(value);
|
||||
}
|
||||
|
||||
QString FilterTableHeader::filterValue(size_t column) const
|
||||
{
|
||||
return filterWidgets[column]->text();
|
||||
}
|
||||
|
||||
@@ -15,9 +15,10 @@ public:
|
||||
explicit FilterTableHeader(QTableView* parent = nullptr);
|
||||
QSize sizeHint() const override;
|
||||
bool hasFilters() const {return (filterWidgets.size() > 0);}
|
||||
QString filterValue(size_t column) const;
|
||||
|
||||
public slots:
|
||||
void generateFilters(size_t number, bool showFirst = false);
|
||||
void generateFilters(size_t number, size_t number_of_hidden_filters = 1);
|
||||
void adjustPositions();
|
||||
void clearFilters();
|
||||
void setFilter(size_t column, const QString& value);
|
||||
|
||||
@@ -2432,6 +2432,8 @@ static void loadBrowseDataTableSettings(BrowseDataTableSettings& settings, QXmlS
|
||||
settings.encoding = xml.attributes().value("encoding").toString();
|
||||
settings.plotXAxis = xml.attributes().value("plot_x_axis").toString();
|
||||
settings.unlockViewPk = xml.attributes().value("unlock_view_pk").toString();
|
||||
if(xml.attributes().hasAttribute("freeze_columns"))
|
||||
settings.frozenColumns = xml.attributes().value("freeze_columns").toUInt();
|
||||
|
||||
while(xml.readNext() != QXmlStreamReader::EndElement && xml.name() != "table") {
|
||||
if(xml.name() == "sort")
|
||||
@@ -2820,6 +2822,7 @@ static void saveBrowseDataTableSettings(const BrowseDataTableSettings& object, Q
|
||||
xml.writeAttribute("encoding", object.encoding);
|
||||
xml.writeAttribute("plot_x_axis", object.plotXAxis);
|
||||
xml.writeAttribute("unlock_view_pk", object.unlockViewPk);
|
||||
xml.writeAttribute("freeze_columns", QString::number(object.frozenColumns));
|
||||
|
||||
xml.writeStartElement("sort");
|
||||
for(const auto& column : object.sortColumns)
|
||||
|
||||
@@ -56,6 +56,7 @@ TableBrowser::TableBrowser(DBBrowserDB* _db, QWidget* parent) :
|
||||
|
||||
popupHeaderMenu = new QMenu(this);
|
||||
popupHeaderMenu->addAction(ui->actionShowRowidColumn);
|
||||
popupHeaderMenu->addAction(ui->actionFreezeColumns);
|
||||
popupHeaderMenu->addAction(ui->actionHideColumns);
|
||||
popupHeaderMenu->addAction(ui->actionShowAllColumns);
|
||||
popupHeaderMenu->addAction(ui->actionSelectColumn);
|
||||
@@ -68,7 +69,13 @@ TableBrowser::TableBrowser(DBBrowserDB* _db, QWidget* parent) :
|
||||
|
||||
connect(ui->actionSelectColumn, &QAction::triggered, [this]() {
|
||||
ui->dataTable->selectColumn(ui->actionBrowseTableEditDisplayFormat->property("clicked_column").toInt());
|
||||
});
|
||||
});
|
||||
connect(ui->actionFreezeColumns, &QAction::triggered, [this](bool checked) {
|
||||
if(checked)
|
||||
freezeColumns(ui->actionBrowseTableEditDisplayFormat->property("clicked_column").toUInt() + 1);
|
||||
else
|
||||
freezeColumns(0);
|
||||
});
|
||||
|
||||
// Set up shortcuts
|
||||
QShortcut* dittoRecordShortcut = new QShortcut(QKeySequence("Ctrl+\""), this);
|
||||
@@ -728,7 +735,7 @@ void TableBrowser::updateRecordsetLabel()
|
||||
generateFilters();
|
||||
ui->dataTable->adjustSize();
|
||||
} else if(!needs_filters && header->hasFilters()) {
|
||||
header->generateFilters(0);
|
||||
ui->dataTable->generateFilters(0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -836,6 +843,9 @@ void TableBrowser::applyViewportSettings(const BrowseDataTableSettings& storedDa
|
||||
ui->actionUnlockViewEditing->setVisible(true);
|
||||
ui->actionShowRowidColumn->setVisible(false);
|
||||
}
|
||||
|
||||
// Frozen columns
|
||||
freezeColumns(storedData.frozenColumns);
|
||||
}
|
||||
|
||||
void TableBrowser::enableEditing(bool enable_edit)
|
||||
@@ -850,8 +860,8 @@ void TableBrowser::enableEditing(bool enable_edit)
|
||||
|
||||
void TableBrowser::showRowidColumn(bool show)
|
||||
{
|
||||
// Block all signals from the horizontal header. Otherwise the QHeaderView::sectionResized signal causes us trouble
|
||||
ui->dataTable->horizontalHeader()->blockSignals(true);
|
||||
// Disconnect the resized signal from the horizontal header. Otherwise it's resetting the automatic column widths
|
||||
disconnect(ui->dataTable->horizontalHeader(), &QHeaderView::sectionResized, this, &TableBrowser::updateColumnWidth);
|
||||
|
||||
// WORKAROUND
|
||||
// Set the opposite hidden/visible status of what we actually want for the rowid column. This is to work around a Qt bug which
|
||||
@@ -864,6 +874,8 @@ void TableBrowser::showRowidColumn(bool show)
|
||||
|
||||
// Show/hide rowid column
|
||||
ui->dataTable->setColumnHidden(0, !show);
|
||||
if(show)
|
||||
ui->dataTable->setColumnWidth(0, ui->dataTable->horizontalHeader()->defaultSectionSize());
|
||||
|
||||
// Update checked status of the popup menu action
|
||||
ui->actionShowRowidColumn->setChecked(show);
|
||||
@@ -878,25 +890,43 @@ void TableBrowser::showRowidColumn(bool show)
|
||||
// Update the filter row
|
||||
generateFilters();
|
||||
|
||||
// Re-enable signals
|
||||
ui->dataTable->horizontalHeader()->blockSignals(false);
|
||||
// Re-enable signal
|
||||
connect(ui->dataTable->horizontalHeader(), &QHeaderView::sectionResized, this, &TableBrowser::updateColumnWidth);
|
||||
|
||||
ui->dataTable->update();
|
||||
}
|
||||
|
||||
void TableBrowser::freezeColumns(size_t columns)
|
||||
{
|
||||
// Update checked status of the popup menu action
|
||||
ui->actionFreezeColumns->setChecked(columns != 0);
|
||||
|
||||
// Save settings for this table
|
||||
sqlb::ObjectIdentifier current_table = currentlyBrowsedTableName();
|
||||
if (m_settings[current_table].frozenColumns != columns) {
|
||||
emit projectModified();
|
||||
m_settings[current_table].frozenColumns = columns;
|
||||
}
|
||||
|
||||
// Apply settings
|
||||
ui->dataTable->horizontalHeader()->blockSignals(true);
|
||||
ui->dataTable->setFrozenColumns(columns);
|
||||
generateFilters();
|
||||
ui->dataTable->horizontalHeader()->blockSignals(false);
|
||||
}
|
||||
|
||||
void TableBrowser::generateFilters()
|
||||
{
|
||||
// Generate a new row of filter line edits
|
||||
const auto& settings = m_settings[currentlyBrowsedTableName()];
|
||||
qobject_cast<FilterTableHeader*>(ui->dataTable->horizontalHeader())->generateFilters(static_cast<size_t>(m_model->columnCount()),
|
||||
settings.showRowid);
|
||||
ui->dataTable->generateFilters(static_cast<size_t>(m_model->columnCount()), settings.showRowid);
|
||||
|
||||
// Apply the stored filter strings to the new row of line edits
|
||||
// Set filters blocking signals for this since the filter is already applied to the browse table model
|
||||
FilterTableHeader* filterHeader = qobject_cast<FilterTableHeader*>(ui->dataTable->horizontalHeader());
|
||||
bool oldState = filterHeader->blockSignals(true);
|
||||
for(auto filterIt=settings.filterValues.cbegin();filterIt!=settings.filterValues.cend();++filterIt)
|
||||
filterHeader->setFilter(static_cast<size_t>(filterIt->first), filterIt->second);
|
||||
ui->dataTable->setFilter(static_cast<size_t>(filterIt->first), filterIt->second);
|
||||
filterHeader->blockSignals(oldState);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,11 +40,13 @@ struct BrowseDataTableSettings
|
||||
QString unlockViewPk;
|
||||
std::map<int, bool> hiddenColumns;
|
||||
std::vector<QString> globalFilters;
|
||||
size_t frozenColumns;
|
||||
|
||||
BrowseDataTableSettings() :
|
||||
showRowid(false),
|
||||
plotYAxes({std::map<QString, PlotDock::PlotSettings>(), std::map<QString, PlotDock::PlotSettings>()}),
|
||||
unlockViewPk("_rowid_")
|
||||
unlockViewPk("_rowid_"),
|
||||
frozenColumns(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -105,6 +107,7 @@ private slots:
|
||||
void editCondFormats(size_t column);
|
||||
void enableEditing(bool enable_edit);
|
||||
void showRowidColumn(bool show);
|
||||
void freezeColumns(size_t columns);
|
||||
void unlockViewEditing(bool unlock, QString pk = QString());
|
||||
void hideColumns(int column = -1, bool hide = true);
|
||||
void on_actionShowAllColumns_triggered();
|
||||
|
||||
@@ -1042,6 +1042,17 @@
|
||||
<string>Replace text in cells</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFreezeColumns">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Freeze columns</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Make all columns from the first column up to this column not move when scrolling horizontally</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
||||
Reference in New Issue
Block a user