Skip to content

Commit

Permalink
Merge bitcoin-core/gui#204: Drop buggy TableViewLastColumnResizingFix…
Browse files Browse the repository at this point in the history
…er class

3913d1e qt: Drop buggy TableViewLastColumnResizingFixer class (Hennadii Stepanov)

Pull request description:

  In Qt 5 the last column resizing with dragging its left edge works out-of-the-box.

  The current `TableViewLastColumnResizingFixer` implementation could put the last column content out of the view port and confuse a user:
  ![Screenshot from 2021-01-31 18-04-32](https://user-images.githubusercontent.com/32963518/106390022-fd6bd180-63ee-11eb-9216-6e5117f8dc96.png)

  Historical context:
  - #2862
  - #3626
  - #3738
  - #3920

  #205 is a nice addition.

ACKs for top commit:
  jarolrod:
    ACK 3913d1e, tested on macOS 11.1 Qt 5.15.2
  Talkless:
    tACK 3913d1e, tested on Debian Sid. Can confirm that behavior in previous commit does not produce scroll bar, last column gets "hidden". This PR makes clear that there's more to see in the view.
  promag:
    Tested ACK 3913d1e on macos.

Tree-SHA512: 12582dfce54bb1db3d9934ae092e305d32e9760cc99b0265322e161fa7f54b7d6fb6cefedf700783f767d5c3a56a8545c8d2f5ade66596c4e67b8a5287063e8a
  • Loading branch information
MarcoFalke committed Feb 22, 2021
2 parents 8d7d5f2 + 3913d1e commit fd725c2
Show file tree
Hide file tree
Showing 6 changed files with 4 additions and 182 deletions.
114 changes: 0 additions & 114 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,120 +470,6 @@ bool LabelOutOfFocusEventFilter::eventFilter(QObject* watched, QEvent* event)
return QObject::eventFilter(watched, event);
}

void TableViewLastColumnResizingFixer::connectViewHeadersSignals()
{
connect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized);
connect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged);
}

// We need to disconnect these while handling the resize events, otherwise we can enter infinite loops.
void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals()
{
disconnect(tableView->horizontalHeader(), &QHeaderView::sectionResized, this, &TableViewLastColumnResizingFixer::on_sectionResized);
disconnect(tableView->horizontalHeader(), &QHeaderView::geometriesChanged, this, &TableViewLastColumnResizingFixer::on_geometriesChanged);
}

// Setup the resize mode, handles compatibility for Qt5 and below as the method signatures changed.
// Refactored here for readability.
void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
{
tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
}

void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex, int width)
{
tableView->setColumnWidth(nColumnIndex, width);
tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
}

int TableViewLastColumnResizingFixer::getColumnsWidth()
{
int nColumnsWidthSum = 0;
for (int i = 0; i < columnCount; i++)
{
nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
}
return nColumnsWidthSum;
}

int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column)
{
int nResult = lastColumnMinimumWidth;
int nTableWidth = tableView->horizontalHeader()->width();

if (nTableWidth > 0)
{
int nOtherColsWidth = getColumnsWidth() - tableView->horizontalHeader()->sectionSize(column);
nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
}

return nResult;
}

// Make sure we don't make the columns wider than the table's viewport width.
void TableViewLastColumnResizingFixer::adjustTableColumnsWidth()
{
disconnectViewHeadersSignals();
resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
connectViewHeadersSignals();

int nTableWidth = tableView->horizontalHeader()->width();
int nColsWidth = getColumnsWidth();
if (nColsWidth > nTableWidth)
{
resizeColumn(secondToLastColumnIndex,getAvailableWidthForColumn(secondToLastColumnIndex));
}
}

// Make column use all the space available, useful during window resizing.
void TableViewLastColumnResizingFixer::stretchColumnWidth(int column)
{
disconnectViewHeadersSignals();
resizeColumn(column, getAvailableWidthForColumn(column));
connectViewHeadersSignals();
}

// When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex, int oldSize, int newSize)
{
adjustTableColumnsWidth();
int remainingWidth = getAvailableWidthForColumn(logicalIndex);
if (newSize > remainingWidth)
{
resizeColumn(logicalIndex, remainingWidth);
}
}

// When the table's geometry is ready, we manually perform the stretch of the "Message" column,
// as the "Stretch" resize mode does not allow for interactive resizing.
void TableViewLastColumnResizingFixer::on_geometriesChanged()
{
if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) != 0)
{
disconnectViewHeadersSignals();
resizeColumn(secondToLastColumnIndex, getAvailableWidthForColumn(secondToLastColumnIndex));
connectViewHeadersSignals();
}
}

/**
* Initializes all internal variables and prepares the
* the resize modes of the last 2 columns of the table and
*/
TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent) :
QObject(parent),
tableView(table),
lastColumnMinimumWidth(lastColMinimumWidth),
allColumnsMinimumWidth(allColsMinimumWidth)
{
columnCount = tableView->horizontalHeader()->count();
lastColumnIndex = columnCount - 1;
secondToLastColumnIndex = columnCount - 2;
tableView->horizontalHeader()->setMinimumSectionSize(allColumnsMinimumWidth);
setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
}

#ifdef WIN32
fs::path static StartupShortcutPath()
{
Expand Down
39 changes: 0 additions & 39 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,45 +181,6 @@ namespace GUIUtil
bool eventFilter(QObject* watched, QEvent* event) override;
};

/**
* Makes a QTableView last column feel as if it was being resized from its left border.
* Also makes sure the column widths are never larger than the table's viewport.
* In Qt, all columns are resizable from the right, but it's not intuitive resizing the last column from the right.
* Usually our second to last columns behave as if stretched, and when on stretch mode, columns aren't resizable
* interactively or programmatically.
*
* This helper object takes care of this issue.
*
*/
class TableViewLastColumnResizingFixer: public QObject
{
Q_OBJECT

public:
TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent);
void stretchColumnWidth(int column);

private:
QTableView* tableView;
int lastColumnMinimumWidth;
int allColumnsMinimumWidth;
int lastColumnIndex;
int columnCount;
int secondToLastColumnIndex;

void adjustTableColumnsWidth();
int getAvailableWidthForColumn(int column);
int getColumnsWidth();
void connectViewHeadersSignals();
void disconnectViewHeadersSignals();
void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode);
void resizeColumn(int nColumnIndex, int width);

private Q_SLOTS:
void on_sectionResized(int logicalIndex, int oldSize, int newSize);
void on_geometriesChanged();
};

bool GetStartOnSystemStartup();
bool SetStartOnSystemStartup(bool fAutoStart);

Expand Down
14 changes: 2 additions & 12 deletions src/qt/receivecoinsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::ReceiveCoinsDialog),
columnResizingFixer(nullptr),
model(nullptr),
platformStyle(_platformStyle)
{
Expand Down Expand Up @@ -78,20 +77,19 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
QTableView* tableView = ui->recentRequestsView;

tableView->verticalHeader()->hide();
tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
tableView->setModel(_model->getRecentRequestsTableModel());
tableView->setAlternatingRowColors(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
tableView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
tableView->horizontalHeader()->setStretchLastSection(true);

connect(tableView->selectionModel(),
&QItemSelectionModel::selectionChanged, this,
&ReceiveCoinsDialog::recentRequestsView_selectionChanged);
// Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);

if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
ui->useBech32->setCheckState(Qt::Checked);
Expand Down Expand Up @@ -235,14 +233,6 @@ void ReceiveCoinsDialog::on_removeRequestButton_clicked()
model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
}

// We override the virtual resizeEvent of the QWidget to adjust tables column
// sizes as the tables width is proportional to the dialogs width.
void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
}

QModelIndex ReceiveCoinsDialog::selectedRow()
{
if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
Expand Down
2 changes: 0 additions & 2 deletions src/qt/receivecoinsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,12 @@ public Q_SLOTS:

private:
Ui::ReceiveCoinsDialog *ui;
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
WalletModel *model;
QMenu *contextMenu;
const PlatformStyle *platformStyle;

QModelIndex selectedRow();
void copyColumnToClipboard(int column);
virtual void resizeEvent(QResizeEvent *event) override;

private Q_SLOTS:
void on_receiveButton_clicked();
Expand Down
13 changes: 2 additions & 11 deletions src/qt/transactionview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ void TransactionView::setModel(WalletModel *_model)

transactionProxyModel->setSortRole(Qt::EditRole);

transactionView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
transactionView->setModel(transactionProxyModel);
transactionView->setAlternatingRowColors(true);
transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
Expand All @@ -231,8 +230,8 @@ void TransactionView::setModel(WalletModel *_model)
transactionView->setColumnWidth(TransactionTableModel::Date, DATE_COLUMN_WIDTH);
transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH);
transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);

columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this);
transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
transactionView->horizontalHeader()->setStretchLastSection(true);

if (_model->getOptionsModel())
{
Expand Down Expand Up @@ -623,14 +622,6 @@ void TransactionView::focusTransaction(const uint256& txid)
}
}

// We override the virtual resizeEvent of the QWidget to adjust tables column
// sizes as the tables width is proportional to the dialogs width.
void TransactionView::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
columnResizingFixer->stretchColumnWidth(TransactionTableModel::ToAddress);
}

// Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
bool TransactionView::eventFilter(QObject *obj, QEvent *event)
{
Expand Down
4 changes: 0 additions & 4 deletions src/qt/transactionview.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ class TransactionView : public QWidget

QWidget *createDateRangeWidget();

GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer{nullptr};

virtual void resizeEvent(QResizeEvent* event) override;

bool eventFilter(QObject *obj, QEvent *event) override;

private Q_SLOTS:
Expand Down

0 comments on commit fd725c2

Please sign in to comment.