Merge pull request #3920
8c29273
[QT] Fixes feel when resizing the last column on tables (issue #2862) (gubatron)
This commit is contained in:
commit
733a799218
6 changed files with 217 additions and 27 deletions
|
@ -379,6 +379,121 @@ bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
|
|||
return QObject::eventFilter(obj, evt);
|
||||
}
|
||||
|
||||
void TableViewLastColumnResizingFixer::connectViewHeadersSignals()
|
||||
{
|
||||
connect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int)));
|
||||
connect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged()));
|
||||
}
|
||||
|
||||
//we need to disconnect these while handling the resize events, otherwise we can enter infinite loops
|
||||
void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals()
|
||||
{
|
||||
disconnect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int)));
|
||||
disconnect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(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)
|
||||
{
|
||||
#if QT_VERSION < 0x050000
|
||||
tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode);
|
||||
#else
|
||||
tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
|
||||
#endif
|
||||
}
|
||||
|
||||
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's 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) :
|
||||
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
|
||||
boost::filesystem::path static StartupShortcutPath()
|
||||
{
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <QMessageBox>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
|
||||
class QValidatedLineEdit;
|
||||
class SendCoinsRecipient;
|
||||
|
@ -116,6 +118,44 @@ namespace GUIUtil
|
|||
int size_threshold;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 strech mode, columns aren't resizable
|
||||
* interactively or programatically.
|
||||
*
|
||||
* This helper object takes care of this issue.
|
||||
*
|
||||
*/
|
||||
class TableViewLastColumnResizingFixer: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth);
|
||||
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 slots:
|
||||
void on_sectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
void on_geometriesChanged();
|
||||
};
|
||||
|
||||
bool GetStartOnSystemStartup();
|
||||
bool SetStartOnSystemStartup(bool fAutoStart);
|
||||
|
||||
|
|
|
@ -55,34 +55,35 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) :
|
|||
connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ReceiveCoinsDialog::setModel(WalletModel *model)
|
||||
{
|
||||
this->model = model;
|
||||
|
||||
if(model && model->getOptionsModel())
|
||||
{
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
updateDisplayUnit();
|
||||
|
||||
ui->recentRequestsView->setModel(model->getRecentRequestsTableModel());
|
||||
ui->recentRequestsView->setAlternatingRowColors(true);
|
||||
ui->recentRequestsView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->recentRequestsView->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
||||
ui->recentRequestsView->horizontalHeader()->resizeSection(RecentRequestsTableModel::Date, 130);
|
||||
ui->recentRequestsView->horizontalHeader()->resizeSection(RecentRequestsTableModel::Label, 120);
|
||||
#if QT_VERSION < 0x050000
|
||||
ui->recentRequestsView->horizontalHeader()->setResizeMode(RecentRequestsTableModel::Message, QHeaderView::Stretch);
|
||||
#else
|
||||
ui->recentRequestsView->horizontalHeader()->setSectionResizeMode(RecentRequestsTableModel::Message, QHeaderView::Stretch);
|
||||
#endif
|
||||
ui->recentRequestsView->horizontalHeader()->resizeSection(RecentRequestsTableModel::Amount, 100);
|
||||
|
||||
model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
|
||||
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
connect(ui->recentRequestsView->selectionModel(),
|
||||
SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||
this,
|
||||
SLOT(on_recentRequestsView_selectionChanged(QItemSelection, QItemSelection)));
|
||||
updateDisplayUnit();
|
||||
|
||||
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);
|
||||
|
||||
//(last 2 columns are set when the table geometry is ready) by the columnResizingFixer.
|
||||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +201,12 @@ void ReceiveCoinsDialog::on_removeRequestButton_clicked()
|
|||
model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
|
||||
}
|
||||
|
||||
//We override the virtual resizeEvent of the QWidget to adjust tablet's column sizes as the table's width is proportional to the dialog's.
|
||||
void ReceiveCoinsDialog::resizeEvent(QResizeEvent* event) {
|
||||
QWidget::resizeEvent(event);
|
||||
columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
|
||||
}
|
||||
|
||||
void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Return)
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#include <QMenu>
|
||||
#include <QPoint>
|
||||
#include <QVariant>
|
||||
#include <QHeaderView>
|
||||
#include <QItemSelection>
|
||||
#include "guiutil.h"
|
||||
|
||||
namespace Ui {
|
||||
class ReceiveCoinsDialog;
|
||||
|
@ -28,11 +30,18 @@ class ReceiveCoinsDialog : public QDialog
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ColumnWidths {
|
||||
DATE_COLUMN_WIDTH = 130,
|
||||
LABEL_COLUMN_WIDTH = 120,
|
||||
AMOUNT_MINIMUM_COLUMN_WIDTH = 160,
|
||||
MINIMUM_COLUMN_WIDTH = 130
|
||||
};
|
||||
|
||||
explicit ReceiveCoinsDialog(QWidget *parent = 0);
|
||||
~ReceiveCoinsDialog();
|
||||
|
||||
void setModel(WalletModel *model);
|
||||
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
void reject();
|
||||
|
@ -43,9 +52,11 @@ protected:
|
|||
|
||||
private:
|
||||
Ui::ReceiveCoinsDialog *ui;
|
||||
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
|
||||
WalletModel *model;
|
||||
QMenu *contextMenu;
|
||||
void copyColumnToClipboard(int column);
|
||||
virtual void resizeEvent(QResizeEvent* event);
|
||||
|
||||
private slots:
|
||||
void on_receiveButton_clicked();
|
||||
|
|
|
@ -168,6 +168,7 @@ void TransactionView::setModel(WalletModel *model)
|
|||
|
||||
transactionProxyModel->setSortRole(Qt::EditRole);
|
||||
|
||||
transactionView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
transactionView->setModel(transactionProxyModel);
|
||||
transactionView->setAlternatingRowColors(true);
|
||||
transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
@ -176,15 +177,12 @@ void TransactionView::setModel(WalletModel *model)
|
|||
transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder);
|
||||
transactionView->verticalHeader()->hide();
|
||||
|
||||
transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Status, 23);
|
||||
transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Date, 120);
|
||||
transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Type, 120);
|
||||
#if QT_VERSION < 0x050000
|
||||
transactionView->horizontalHeader()->setResizeMode(TransactionTableModel::ToAddress, QHeaderView::Stretch);
|
||||
#else
|
||||
transactionView->horizontalHeader()->setSectionResizeMode(TransactionTableModel::ToAddress, QHeaderView::Stretch);
|
||||
#endif
|
||||
transactionView->horizontalHeader()->resizeSection(TransactionTableModel::Amount, 100);
|
||||
transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,3 +437,9 @@ void TransactionView::focusTransaction(const QModelIndex &idx)
|
|||
transactionView->setCurrentIndex(targetIdx);
|
||||
transactionView->setFocus();
|
||||
}
|
||||
|
||||
//We override the virtual resizeEvent of the QWidget to adjust tablet's column sizes as the table's width is proportional to the dialog's.
|
||||
void TransactionView::resizeEvent(QResizeEvent* event) {
|
||||
QWidget::resizeEvent(event);
|
||||
columnResizingFixer->stretchColumnWidth(TransactionTableModel::ToAddress);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define TRANSACTIONVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "guiutil.h"
|
||||
|
||||
class TransactionFilterProxy;
|
||||
class WalletModel;
|
||||
|
@ -44,6 +45,14 @@ public:
|
|||
Range
|
||||
};
|
||||
|
||||
enum ColumnWidths {
|
||||
STATUS_COLUMN_WIDTH = 23,
|
||||
DATE_COLUMN_WIDTH = 120,
|
||||
TYPE_COLUMN_WIDTH = 120,
|
||||
AMOUNT_MINIMUM_COLUMN_WIDTH = 120,
|
||||
MINIMUM_COLUMN_WIDTH = 23
|
||||
};
|
||||
|
||||
private:
|
||||
WalletModel *model;
|
||||
TransactionFilterProxy *transactionProxyModel;
|
||||
|
@ -62,6 +71,10 @@ private:
|
|||
|
||||
QWidget *createDateRangeWidget();
|
||||
|
||||
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
|
||||
|
||||
virtual void resizeEvent(QResizeEvent* event);
|
||||
|
||||
private slots:
|
||||
void contextualMenu(const QPoint &);
|
||||
void dateRangeChanged();
|
||||
|
|
Loading…
Reference in a new issue