Skip to content

Commit

Permalink
Implement proportional column resizing for Addressbook with memory
Browse files Browse the repository at this point in the history
This is similar to gridcoin-community#2520.
  • Loading branch information
jamescowens committed Jul 17, 2022
1 parent 0601e82 commit 2aabba8
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 5 deletions.
99 changes: 94 additions & 5 deletions src/qt/addressbookpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget* parent)
, optionsModel(nullptr)
, mode(mode)
, tab(tab)
, m_table_column_sizes({150, 100})
, m_init_column_sizes_set(false)
, m_resize_columns_in_progress(false)
{
ui->setupUi(this);

Expand Down Expand Up @@ -102,6 +105,9 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget* parent)

// Pass through accept action from button box
connect(ui->okayButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);

connect(ui->tableView->horizontalHeader(), &QHeaderView::sectionResized,
this, &AddressBookPage::addressBookSectionResized);
}

AddressBookPage::~AddressBookPage()
Expand Down Expand Up @@ -144,11 +150,6 @@ void AddressBookPage::setModel(AddressTableModel *model)
ui->tableView->setModel(filterProxyModel);
ui->tableView->sortByColumn(0, Qt::AscendingOrder);

// Set column widths
ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
ui->tableView->horizontalHeader()->resizeSection(AddressTableModel::Address, 320);

connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &AddressBookPage::selectionChanged);

Expand Down Expand Up @@ -388,3 +389,91 @@ void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int
newAddressToSelect.clear();
}
}

void AddressBookPage::resizeTableColumns(const bool& neighbor_pair_adjust, const int& index,
const int& old_size, const int& new_size)
{
// This prevents unwanted recursion to here from txnViewSectionResized.
m_resize_columns_in_progress = true;

if (!model) {
m_resize_columns_in_progress = false;

return;
}

if (!m_init_column_sizes_set) {
for (int i = 0; i < (int) m_table_column_sizes.size(); ++i) {
ui->tableView->horizontalHeader()->resizeSection(i, m_table_column_sizes[i]);
}

m_init_column_sizes_set = true;
m_resize_columns_in_progress = false;

return;
}

if (neighbor_pair_adjust) {
if (index != AddressTableModel::all_ColumnIndex.size() - 1) {
int new_neighbor_section_size = ui->tableView->horizontalHeader()->sectionSize(index + 1)
+ old_size - new_size;

ui->tableView->horizontalHeader()->resizeSection(
index + 1, new_neighbor_section_size);

// This detects and deals with the case where the resize of a column tries to force the neighbor
// to a size below its minimum, in which case we have to reverse out the attempt.
if (ui->tableView->horizontalHeader()->sectionSize(index + 1)
!= new_neighbor_section_size) {
ui->tableView->horizontalHeader()->resizeSection(
index,
ui->tableView->horizontalHeader()->sectionSize(index)
+ new_neighbor_section_size
- ui->tableView->horizontalHeader()->sectionSize(index + 1));
}
} else {
// Do not allow the last column to be resized because there is no adjoining neighbor to the right
// and we are maintaining the total width fixed to the size of the containing frame.
ui->tableView->horizontalHeader()->resizeSection(index, old_size);
}

m_resize_columns_in_progress = false;

return;
}

// This is the proportional resize case when the window is resized or the history icon button is pressed.
const int width = ui->tableView->horizontalHeader()->width() - 5;

int orig_header_width = 0;

for (const auto& iter : AddressTableModel::all_ColumnIndex) {
orig_header_width += ui->tableView->horizontalHeader()->sectionSize(iter);
}

if (!width || !orig_header_width) return;

for (const auto& iter : AddressTableModel::all_ColumnIndex) {
int section_size = ui->tableView->horizontalHeader()->sectionSize(iter);

ui->tableView->horizontalHeader()->resizeSection(
iter, section_size * width / orig_header_width);
}

m_resize_columns_in_progress = false;
}

void AddressBookPage::resizeEvent(QResizeEvent *event)
{
resizeTableColumns();

QWidget::resizeEvent(event);
}

void AddressBookPage::addressBookSectionResized(int index, int old_size, int new_size)
{
// Avoid implicit recursion between resizeTableColumns and txnViewSectionResized
if (m_resize_columns_in_progress) return;

resizeTableColumns(true, index, old_size, new_size);
}
12 changes: 12 additions & 0 deletions src/qt/addressbookpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public slots:
void done(int retval);
void exportClicked();
void changeFilter(const QString& needle);
void resizeTableColumns(const bool& neighbor_pair_adjust = false, const int& index = 0,
const int& old_size = 0, const int& new_size = 0);

protected:
void resizeEvent(QResizeEvent *event) override;

private:
Ui::AddressBookPage *ui;
Expand All @@ -59,6 +64,10 @@ public slots:
QAction *deleteAction;
QString newAddressToSelect;

std::vector<int> m_table_column_sizes;
bool m_init_column_sizes_set;
bool m_resize_columns_in_progress;

private slots:
void on_deleteButton_clicked();
void on_newAddressButton_clicked();
Expand All @@ -79,6 +88,9 @@ private slots:
/** New entry/entries were added to address table */
void selectNewAddress(const QModelIndex &parent, int begin, int end);

/** Resize address book table columns based on incoming signal */
void addressBookSectionResized(int index, int old_size, int new_size);

signals:
void signMessage(QString addr);
void verifyMessage(QString addr);
Expand Down
2 changes: 2 additions & 0 deletions src/qt/addresstablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class AddressTableModel : public QAbstractTableModel
Address = 1 /**< Bitcoin address */
};

static constexpr std::initializer_list<ColumnIndex> all_ColumnIndex = {Label, Address};

enum RoleIndex {
TypeRole = Qt::UserRole /**< Type of address (#Send or #Receive) */
};
Expand Down
4 changes: 4 additions & 0 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,8 @@ void BitcoinGUI::gotoAddressBookPage()
addressBookAction->setChecked(true);
centralWidget->setCurrentWidget(addressBookPage);

addressBookPage->resizeTableColumns();

exportAction->setEnabled(true);
disconnect(exportAction, &QAction::triggered, nullptr, nullptr);
connect(exportAction, &QAction::triggered, addressBookPage, &FavoritesPage::exportClicked);
Expand All @@ -1443,6 +1445,8 @@ void BitcoinGUI::gotoReceiveCoinsPage()
receiveCoinsAction->setChecked(true);
centralWidget->setCurrentWidget(receiveCoinsPage);

receiveCoinsPage->resizeTableColumns();

exportAction->setEnabled(true);
disconnect(exportAction, &QAction::triggered, nullptr, nullptr);
connect(exportAction, &QAction::triggered, receiveCoinsPage, &ReceiveCoinsPage::exportClicked);
Expand Down
7 changes: 7 additions & 0 deletions src/qt/favoritespage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,10 @@ void FavoritesPage::updateIcons(const QString& theme)
{
filterLineEditIconAction->setIcon(QIcon(":/icons/" + theme + "_search"));
}

void FavoritesPage::resizeTableColumns()
{
if (addressBookPage) {
addressBookPage->resizeTableColumns();
}
}
2 changes: 2 additions & 0 deletions src/qt/favoritespage.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class FavoritesPage : public QWidget
void setAddressTableModel(AddressTableModel* model);
void setOptionsModel(OptionsModel* model);

void resizeTableColumns();

private:
Ui::FavoritesPage* ui;
AddressBookPage* addressBookPage;
Expand Down
8 changes: 8 additions & 0 deletions src/qt/receivecoinspage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ void ReceiveCoinsPage::updateIcons(const QString& theme)
{
filterLineEditIconAction->setIcon(QIcon(":/icons/" + theme + "_search"));
}


void ReceiveCoinsPage::resizeTableColumns()
{
if (addressBookPage) {
addressBookPage->resizeTableColumns();
}
}
2 changes: 2 additions & 0 deletions src/qt/receivecoinspage.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class ReceiveCoinsPage : public QWidget
void setAddressTableModel(AddressTableModel *model);
void setOptionsModel(OptionsModel *model);

void resizeTableColumns();

private:
Ui::ReceiveCoinsPage *ui;
AddressBookPage *addressBookPage;
Expand Down

0 comments on commit 2aabba8

Please sign in to comment.