Skip to content

Commit 667f590

Browse files
committed
Fix transaction history table column size behavior
1 parent eaac942 commit 667f590

File tree

4 files changed

+109
-11
lines changed

4 files changed

+109
-11
lines changed

src/qt/bitcoingui.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1420,9 +1420,12 @@ void BitcoinGUI::gotoHistoryPage()
14201420
historyAction->setChecked(true);
14211421
centralWidget->setCurrentWidget(transactionView);
14221422

1423+
transactionView->resizeTableColumns();
1424+
14231425
exportAction->setEnabled(true);
14241426
disconnect(exportAction, &QAction::triggered, nullptr, nullptr);
14251427
connect(exportAction, &QAction::triggered, transactionView, &TransactionView::exportClicked);
1428+
14261429
}
14271430

14281431
void BitcoinGUI::gotoAddressBookPage()

src/qt/transactiontablemodel.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class TransactionTableModel : public QAbstractTableModel
2626
Amount = 4
2727
};
2828

29+
static constexpr std::initializer_list<ColumnIndex> all_ColumnIndex = {Status, Date, Type, ToAddress, Amount};
30+
2931
/** Roles to get specific information from a transaction row.
3032
These are independent of column.
3133
*/

src/qt/transactionview.cpp

+93-10
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ TransactionView::TransactionView(QWidget *parent)
3737
, transactionProxyModel(nullptr)
3838
, transactionView(nullptr)
3939
, searchWidgetIconAction(new QAction())
40+
, m_table_column_sizes({23, 120, 120, 400, 100})
41+
, m_init_column_sizes_set(false)
42+
, m_resize_columns_in_progress(false)
4043
{
4144
setContentsMargins(0, 0, 0, 0);
4245

@@ -181,16 +184,8 @@ void TransactionView::setModel(WalletModel *model)
181184
transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);
182185
transactionView->verticalHeader()->hide();
183186

184-
transactionView->horizontalHeader()->resizeSection(
185-
TransactionTableModel::Status, 23);
186-
transactionView->horizontalHeader()->resizeSection(
187-
TransactionTableModel::Date, 120);
188-
transactionView->horizontalHeader()->resizeSection(
189-
TransactionTableModel::Type, 120);
190-
transactionView->horizontalHeader()->setSectionResizeMode(
191-
TransactionTableModel::ToAddress, QHeaderView::Stretch);
192-
transactionView->horizontalHeader()->resizeSection(
193-
TransactionTableModel::Amount, 100);
187+
connect(transactionView->horizontalHeader(), &QHeaderView::sectionResized,
188+
this, &TransactionView::txnViewSectionResized);
194189
}
195190

196191
if (model && model->getOptionsModel()) {
@@ -454,3 +449,91 @@ void TransactionView::updateIcons(const QString& theme)
454449
{
455450
searchWidgetIconAction->setIcon(QIcon(":/icons/" + theme + "_search"));
456451
}
452+
453+
void TransactionView::resizeTableColumns(const bool& neighbor_pair_adjust, const int& index,
454+
const int& old_size, const int& new_size)
455+
{
456+
// This prevents unwanted recursion to here from txnViewSectionResized.
457+
m_resize_columns_in_progress = true;
458+
459+
if (!model) {
460+
m_resize_columns_in_progress = false;
461+
462+
return;
463+
}
464+
465+
if (!m_init_column_sizes_set) {
466+
for (int i = 0; i < (int) m_table_column_sizes.size(); ++i) {
467+
transactionView->horizontalHeader()->resizeSection(i, m_table_column_sizes[i]);
468+
}
469+
470+
m_init_column_sizes_set = true;
471+
m_resize_columns_in_progress = false;
472+
473+
return;
474+
}
475+
476+
if (neighbor_pair_adjust) {
477+
if (index != TransactionTableModel::all_ColumnIndex.size() - 1) {
478+
int new_neighbor_section_size = transactionView->horizontalHeader()->sectionSize(index + 1)
479+
+ old_size - new_size;
480+
481+
transactionView->horizontalHeader()->resizeSection(
482+
index + 1, new_neighbor_section_size);
483+
484+
// This detects and deals with the case where the resize of a column tries to force the neighbor
485+
// to a size below its minimum, in which case we have to reverse out the attempt.
486+
if (transactionView->horizontalHeader()->sectionSize(index + 1)
487+
!= new_neighbor_section_size) {
488+
transactionView->horizontalHeader()->resizeSection(
489+
index,
490+
transactionView->horizontalHeader()->sectionSize(index)
491+
+ new_neighbor_section_size
492+
- transactionView->horizontalHeader()->sectionSize(index + 1));
493+
}
494+
} else {
495+
// Do not allow the last column to be resized because there is no adjoining neighbor to the right
496+
// and we are maintaining the total width fixed to the size of the containing frame.
497+
transactionView->horizontalHeader()->resizeSection(index, old_size);
498+
}
499+
500+
m_resize_columns_in_progress = false;
501+
502+
return;
503+
}
504+
505+
// This is the proportional resize case when the window is resized or the history icon button is pressed.
506+
const int width = transactionView->horizontalHeader()->width() - 5;
507+
508+
int orig_header_width = 0;
509+
510+
for (const auto& iter : TransactionTableModel::all_ColumnIndex) {
511+
orig_header_width += transactionView->horizontalHeader()->sectionSize(iter);
512+
}
513+
514+
if (!width || !orig_header_width) return;
515+
516+
for (const auto& iter : TransactionTableModel::all_ColumnIndex) {
517+
int section_size = transactionView->horizontalHeader()->sectionSize(iter);
518+
519+
transactionView->horizontalHeader()->resizeSection(
520+
iter, section_size * width / orig_header_width);
521+
}
522+
523+
m_resize_columns_in_progress = false;
524+
}
525+
526+
void TransactionView::resizeEvent(QResizeEvent *event)
527+
{
528+
resizeTableColumns();
529+
530+
QWidget::resizeEvent(event);
531+
}
532+
533+
void TransactionView::txnViewSectionResized(int index, int old_size, int new_size)
534+
{
535+
// Avoid implicit recursion between resizeTableColumns and txnViewSectionResized
536+
if (m_resize_columns_in_progress) return;
537+
538+
resizeTableColumns(true, index, old_size, new_size);
539+
}

src/qt/transactionview.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class QModelIndex;
1414
class QMenu;
1515
class QFrame;
1616
class QDateTimeEdit;
17+
1718
QT_END_NAMESPACE
1819

1920
/** Widget showing the transaction list for a wallet, including a filter row.
@@ -39,6 +40,9 @@ class TransactionView : public QFrame
3940
Range
4041
};
4142

43+
protected:
44+
void resizeEvent(QResizeEvent *event) override;
45+
4246
private:
4347
WalletModel *model;
4448
TransactionFilterProxy *transactionProxyModel;
@@ -58,6 +62,10 @@ class TransactionView : public QFrame
5862

5963
QWidget *createDateRangeWidget();
6064

65+
std::vector<int> m_table_column_sizes;
66+
bool m_init_column_sizes_set;
67+
bool m_resize_columns_in_progress;
68+
6169
private slots:
6270
void contextualMenu(const QPoint &);
6371
void dateRangeChanged();
@@ -67,6 +75,7 @@ private slots:
6775
void copyAmount();
6876
void copyTxID();
6977
void updateIcons(const QString& theme);
78+
void txnViewSectionResized(int index, int old_size, int new_size);
7079

7180
signals:
7281
void doubleClicked(const QModelIndex&);
@@ -79,7 +88,8 @@ public slots:
7988
void changedAmount(const QString &amount);
8089
void exportClicked();
8190
void focusTransaction(const QModelIndex&);
82-
91+
void resizeTableColumns(const bool& neighbor_pair_adjust = false, const int& index = 0,
92+
const int& old_size = 0, const int& new_size = 0);
8393
};
8494

8595
#endif // BITCOIN_QT_TRANSACTIONVIEW_H

0 commit comments

Comments
 (0)