aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-03-21 08:00:57 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-03-21 08:10:45 +0100
commit733a7992186c3d6338fcfe259c93b5dc15d796a7 (patch)
treed6e52183eb06a512319343373ddc4a11e56b350b
parent6539cfc583c5963fbb3138b99c1a8677970e0305 (diff)
parent8c29273ff058f90dfa16a30b3d8457b842c0954d (diff)
downloadbitcoin-733a7992186c3d6338fcfe259c93b5dc15d796a7.tar.xz
Merge pull request #3920
8c29273 [QT] Fixes feel when resizing the last column on tables (issue #2862) (gubatron)
-rw-r--r--src/qt/guiutil.cpp115
-rw-r--r--src/qt/guiutil.h40
-rw-r--r--src/qt/receivecoinsdialog.cpp41
-rw-r--r--src/qt/receivecoinsdialog.h13
-rw-r--r--src/qt/transactionview.cpp22
-rw-r--r--src/qt/transactionview.h13
6 files changed, 217 insertions, 27 deletions
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 7e1831f037..4a4fece3e1 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -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()
{
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 52124ff20a..26202e8d41 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -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);
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 2af3949ae4..f630324947 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -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)
diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h
index bfe8b3401f..1d051d9324 100644
--- a/src/qt/receivecoinsdialog.h
+++ b/src/qt/receivecoinsdialog.h
@@ -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();
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index a0c3ce62aa..d178efe8d5 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -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);
+}
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 18f2b9bfc9..fe8e205d6c 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -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();