aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/README.md121
-rw-r--r--src/qt/addressbookpage.cpp2
-rw-r--r--src/qt/addresstablemodel.cpp44
-rw-r--r--src/qt/askpassphrasedialog.cpp2
-rw-r--r--src/qt/bantablemodel.cpp15
-rw-r--r--src/qt/bitcoin.cpp11
-rw-r--r--src/qt/bitcoin.qrc3
-rw-r--r--src/qt/bitcoingui.cpp6
-rw-r--r--src/qt/clientmodel.cpp9
-rw-r--r--src/qt/coincontroldialog.cpp2
-rw-r--r--src/qt/createwalletdialog.cpp4
-rw-r--r--src/qt/editaddressdialog.cpp2
-rw-r--r--src/qt/forms/createwalletdialog.ui253
-rw-r--r--src/qt/forms/debugwindow.ui162
-rw-r--r--src/qt/forms/optionsdialog.ui100
-rw-r--r--src/qt/forms/overviewpage.ui81
-rw-r--r--src/qt/guiutil.cpp161
-rw-r--r--src/qt/guiutil.h52
-rw-r--r--src/qt/intro.cpp2
-rw-r--r--src/qt/networkstyle.cpp13
-rw-r--r--src/qt/openuridialog.cpp2
-rw-r--r--src/qt/optionsdialog.cpp17
-rw-r--r--src/qt/optionsmodel.cpp13
-rw-r--r--src/qt/optionsmodel.h4
-rw-r--r--src/qt/overviewpage.cpp57
-rw-r--r--src/qt/overviewpage.h1
-rw-r--r--src/qt/peertablemodel.cpp48
-rw-r--r--src/qt/peertablemodel.h15
-rw-r--r--src/qt/platformstyle.cpp15
-rw-r--r--src/qt/psbtoperationsdialog.cpp2
-rw-r--r--src/qt/receivecoinsdialog.cpp75
-rw-r--r--src/qt/receivecoinsdialog.h6
-rw-r--r--src/qt/receiverequestdialog.cpp2
-rw-r--r--src/qt/recentrequeststablemodel.cpp2
-rw-r--r--src/qt/res/fonts/RobotoMono-Bold.ttfbin0 -> 87008 bytes
-rw-r--r--src/qt/rpcconsole.cpp78
-rw-r--r--src/qt/rpcconsole.h10
-rw-r--r--src/qt/sendcoinsdialog.cpp2
-rw-r--r--src/qt/signverifymessagedialog.cpp2
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/test/rpcnestedtests.cpp2
-rw-r--r--src/qt/test/test_main.cpp7
-rw-r--r--src/qt/transactiondescdialog.cpp2
-rw-r--r--src/qt/transactionoverviewwidget.h41
-rw-r--r--src/qt/transactiontablemodel.cpp31
-rw-r--r--src/qt/transactionview.cpp75
-rw-r--r--src/qt/transactionview.h5
-rw-r--r--src/qt/utilitydialog.cpp2
-rw-r--r--src/qt/walletframe.cpp17
-rw-r--r--src/qt/walletmodel.cpp10
50 files changed, 934 insertions, 656 deletions
diff --git a/src/qt/README.md b/src/qt/README.md
index 30c68db15b..20c712c98d 100644
--- a/src/qt/README.md
+++ b/src/qt/README.md
@@ -1,10 +1,12 @@
-This directory contains the BitcoinQT graphical user interface (GUI). It uses the cross-platform framework [Qt](https://www1.qt.io/developers/).
+This directory contains the source code for the Bitcoin Core graphical user interface (GUI). It uses the [Qt](https://www1.qt.io/developers/) cross-platform framework.
The current precise version for Qt 5 is specified in [qt.mk](/depends/packages/qt.mk).
## Compile and run
-See build instructions ([macOS](/doc/build-osx.md), [Windows](/doc/build-windows.md), [Unix](/doc/build-unix.md), etc).
+See build instructions: [Unix](/doc/build-unix.md), [macOS](/doc/build-osx.md), [Windows](/doc/build-windows.md), [FreeBSD](/doc/build-freebsd.md), [NetBSD](/doc/build-netbsd.md), [OpenBSD](/doc/build-openbsd.md)
+
+When following your systems build instructions, make sure to install the `Qt` dependencies.
To run:
@@ -12,84 +14,111 @@ To run:
./src/qt/bitcoin-qt
```
-## Files and directories
-
-### forms
+## Files and Directories
-Contains [Designer UI](https://doc.qt.io/qt-5.9/designer-using-a-ui-file.html) files. They are created with [Qt Creator](#using-qt-creator-as-ide), but can be edited using any text editor.
+#### forms/
-### locale
+- A directory that contains [Designer UI](https://doc.qt.io/qt-5.9/designer-using-a-ui-file.html) files. These files specify the characteristics of form elements in XML. Qt UI files can be edited with [Qt Creator](#using-qt-creator-as-ide) or using any text editor.
-Contains translations. They are periodically updated. The process is described [here](/doc/translation_process.md).
+#### locale/
-### res
+- Contains translations. They are periodically updated and an effort is made to support as many languages as possible. The process of contributing translations is described in [doc/translation_process.md](/doc/translation_process.md).
-Resources such as the icon.
+#### res/
-### test
+ - Contains graphical resources used to enhance the UI experience.
-Tests.
+#### test/
-### bitcoingui.(h/cpp)
+- Functional tests used to ensure proper functionality of the GUI. Significant changes to the GUI code normally require new or updated tests.
-Represents the main window of the Bitcoin UI.
+#### bitcoingui.(h/cpp)
-### \*model.(h/cpp)
+- Represents the main window of the Bitcoin UI.
-The model. When it has a corresponding controller, it generally inherits from [QAbstractTableModel](https://doc.qt.io/qt-5/qabstracttablemodel.html). Models that are used by controllers as helpers inherit from other Qt classes like [QValidator](https://doc.qt.io/qt-5/qvalidator.html).
+#### \*model.(h/cpp)
-ClientModel is used by the main application `bitcoingui` and several models like `peertablemodel`.
+- The model. When it has a corresponding controller, it generally inherits from [QAbstractTableModel](https://doc.qt.io/qt-5/qabstracttablemodel.html). Models that are used by controllers as helpers inherit from other Qt classes like [QValidator](https://doc.qt.io/qt-5/qvalidator.html).
+- ClientModel is used by the main application `bitcoingui` and several models like `peertablemodel`.
-### \*page.(h/cpp)
+#### \*page.(h/cpp)
-A controller. `:NAMEpage.cpp` generally includes `:NAMEmodel.h` and `forms/:NAME.page.ui` with a similar `:NAME`.
+- A controller. `:NAMEpage.cpp` generally includes `:NAMEmodel.h` and `forms/:NAME.page.ui` with a similar `:NAME`.
-### \*dialog.(h/cpp)
+#### \*dialog.(h/cpp)
-Various dialogs, e.g. to open a URL. Inherit from [QDialog](https://doc.qt.io/qt-5/qdialog.html).
+- Various dialogs, e.g. to open a URL. Inherit from [QDialog](https://doc.qt.io/qt-5/qdialog.html).
-### paymentserver.(h/cpp)
+#### paymentserver.(h/cpp)
-Used to process BIP21 payment URI requests. Also handles URI based application switching (e.g. when following a bitcoin:... link from a browser).
+- (Deprecated) Used to process BIP21 payment URI requests. Also handles URI-based application switching (e.g. when following a bitcoin:... link from a browser).
-### walletview.(h/cpp)
+#### walletview.(h/cpp)
-Represents the view to a single wallet.
+- Represents the view to a single wallet.
-### Other .h/cpp files
+#### Other .h/cpp files
* UI elements like BitcoinAmountField, which inherit from QWidget.
* `bitcoinstrings.cpp`: automatically generated
-* `bitcoinunits.(h/cpp)`: BTC / mBTC / etc handling
+* `bitcoinunits.(h/cpp)`: BTC / mBTC / etc. handling
* `callback.h`
-* `guiconstants.h`: UI colors, app name, etc
+* `guiconstants.h`: UI colors, app name, etc.
* `guiutil.h`: several helper functions
* `macdockiconhandler.(h/mm)`: macOS dock icon handler
* `macnotificationhandler.(h/mm)`: display notifications in macOS
## Contribute
-See [CONTRIBUTING.md](/CONTRIBUTING.md) for general guidelines. Specifically for Qt:
+See [CONTRIBUTING.md](/CONTRIBUTING.md) for general guidelines.
+
+**Note:** Do not change `local/bitcoin_en.ts`. It is updated [automatically](/doc/translation_process.md#writing-code-with-translations).
+
+## Using Qt Creator as an IDE
+
+[Qt Creator](https://www.qt.io/product/development-tools) is a powerful tool which packages a UI designer tool (Qt Designer) and a C++ IDE into one application. This is especially useful if you want to change the UI layout.
+
+#### Download Qt Creator
+
+On Unix and macOS, Qt Creator can be installed through your package manager. Alternatively, you can download a binary from the [Qt Website](https://www.qt.io/download/).
+
+**Note:** If installing from a binary grabbed from the Qt Website: During the installation process, uncheck everything except for `Qt Creator`.
+
+##### macOS
+
+```sh
+brew install qt-creator
+```
+
+##### Ubuntu & Debian
+
+```sh
+sudo apt-get install qtcreator
+```
+
+#### Setup Qt Creator
-* don't change `local/bitcoin_en.ts`; this happens [automatically](/doc/translation_process.md#writing-code-with-translations)
+1. Make sure you've installed all dependencies specified in your systems build instructions
+2. Follow the compile instructions for your system, run `./configure` with the `--enable-debug` flag
+3. Start Qt Creator. At the start page, do: `New` -> `Import Project` -> `Import Existing Project`
+4. Enter `bitcoin-qt` as the Project Name and enter the absolute path to `src/qt` as Location
+5. Check over the file selection, you may need to select the `forms` directory (necessary if you intend to edit *.ui files)
+6. Confirm the `Summary` page
+7. In the `Projects` tab, select `Manage Kits...`
-## Using Qt Creator as IDE
+ **macOS**
+ - Under `Kits`: select the default "Desktop" kit
+ - Under `Compilers`: select `"Clang (x86 64bit in /usr/bin)"`
+ - Under `Debuggers`: select `"LLDB"` as debugger (you might need to set the path to your LLDB installation)
-You can use Qt Creator as an IDE. This is especially useful if you want to change
-the UI layout.
+ **Ubuntu & Debian**
-Download and install the community edition of [Qt Creator](https://www.qt.io/download/).
-Uncheck everything except Qt Creator during the installation process.
+ Note: Some of these options may already be set
-Instructions for macOS:
+ - Under `Kits`: select the default "Desktop" kit
+ - Under `Compilers`: select `"GCC (x86 64bit in /usr/bin)"`
+ - Under `Debuggers`: select `"GDB"` as debugger
-1. Make sure you installed everything through Homebrew mentioned in the [macOS build instructions](/doc/build-osx.md)
-2. Use `./configure` with the `--enable-debug` flag
-3. In Qt Creator do "New Project" -> Import Project -> Import Existing Project
-4. Enter "bitcoin-qt" as project name, enter src/qt as location
-5. Leave the file selection as it is
-6. Confirm the "summary page"
-7. In the "Projects" tab select "Manage Kits..."
-8. Select the default "Desktop" kit and select "Clang (x86 64bit in /usr/bin)" as compiler
-9. Select LLDB as debugger (you might need to set the path to your installation)
-10. Start debugging with Qt Creator (you might need to the executable to "bitcoin-qt" under "Run", which is where you can also add command line arguments)
+8. While in the `Projects` tab, ensure that you have the `bitcoin-qt` executable specified under `Run`
+ - If the executable is not specified: click `"Choose..."`, navigate to `src/qt`, and select `bitcoin-qt`
+9. You're all set! Start developing, building, and debugging the Bitcoin Core GUI
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index 0fa52359a8..ab6168a541 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -56,7 +56,7 @@ protected:
};
AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::AddressBookPage),
model(nullptr),
mode(_mode),
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index bb444f22b3..ee2462ed74 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -198,42 +198,38 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const
AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
- if(role == Qt::DisplayRole || role == Qt::EditRole)
- {
- switch(index.column())
- {
+ const auto column = static_cast<ColumnIndex>(index.column());
+ if (role == Qt::DisplayRole || role == Qt::EditRole) {
+ switch (column) {
case Label:
- if(rec->label.isEmpty() && role == Qt::DisplayRole)
- {
+ if (rec->label.isEmpty() && role == Qt::DisplayRole) {
return tr("(no label)");
- }
- else
- {
+ } else {
return rec->label;
}
case Address:
return rec->address;
- }
- }
- else if (role == Qt::FontRole)
- {
- QFont font;
- if(index.column() == Address)
- {
- font = GUIUtil::fixedPitchFont();
- }
- return font;
- }
- else if (role == TypeRole)
- {
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
+ } else if (role == Qt::FontRole) {
+ switch (column) {
+ case Label:
+ return QFont();
+ case Address:
+ return GUIUtil::fixedPitchFont();
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
+ } else if (role == TypeRole) {
switch(rec->type)
{
case AddressTableEntry::Sending:
return Send;
case AddressTableEntry::Receiving:
return Receive;
- default: break;
- }
+ case AddressTableEntry::Hidden:
+ return {};
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
}
return QVariant();
}
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index c2349b78f9..5b1330b81b 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -20,7 +20,7 @@
#include <QPushButton>
AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent, SecureString* passphrase_out) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::AskPassphraseDialog),
mode(_mode),
model(nullptr),
diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp
index a01a7bc386..6cb4a4c546 100644
--- a/src/qt/bantablemodel.cpp
+++ b/src/qt/bantablemodel.cpp
@@ -23,15 +23,13 @@ bool BannedNodeLessThan::operator()(const CCombinedBan& left, const CCombinedBan
if (order == Qt::DescendingOrder)
std::swap(pLeft, pRight);
- switch(column)
- {
+ switch (static_cast<BanTableModel::ColumnIndex>(column)) {
case BanTableModel::Address:
return pLeft->subnet.ToString().compare(pRight->subnet.ToString()) < 0;
case BanTableModel::Bantime:
return pLeft->banEntry.nBanUntil < pRight->banEntry.nBanUntil;
- }
-
- return false;
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
}
// private implementation
@@ -119,16 +117,17 @@ QVariant BanTableModel::data(const QModelIndex &index, int role) const
CCombinedBan *rec = static_cast<CCombinedBan*>(index.internalPointer());
+ const auto column = static_cast<ColumnIndex>(index.column());
if (role == Qt::DisplayRole) {
- switch(index.column())
- {
+ switch (column) {
case Address:
return QString::fromStdString(rec->subnet.ToString());
case Bantime:
QDateTime date = QDateTime::fromMSecsSinceEpoch(0);
date = date.addSecs(rec->banEntry.nBanUntil);
return QLocale::system().toString(date, QLocale::LongFormat);
- }
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
}
return QVariant();
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 8efb0e35d0..f25b415820 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -44,6 +44,7 @@
#include <QApplication>
#include <QDebug>
+#include <QFontDatabase>
#include <QLibraryInfo>
#include <QLocale>
#include <QMessageBox>
@@ -51,6 +52,7 @@
#include <QThread>
#include <QTimer>
#include <QTranslator>
+#include <QtGlobal>
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
@@ -60,6 +62,7 @@ Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
+Q_IMPORT_PLUGIN(QMacStylePlugin);
#endif
#endif
@@ -462,11 +465,17 @@ int GuiMain(int argc, char* argv[])
// Generate high-dpi pixmaps
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
-#if QT_VERSION >= 0x050600
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+
+#if (QT_VERSION <= QT_VERSION_CHECK(5, 9, 8)) && defined(Q_OS_MACOS)
+ const auto os_name = QSysInfo::prettyProductName();
+ if (os_name.startsWith("macOS 11") || os_name.startsWith("macOS 10.16")) {
+ QApplication::setStyle("fusion");
+ }
#endif
BitcoinApplication app;
+ QFontDatabase::addApplicationFont(":/fonts/monospace");
/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
// Command-line options take precedence:
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index 7115459808..fed373e551 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -83,4 +83,7 @@
<file alias="spinner-034">res/animation/spinner-034.png</file>
<file alias="spinner-035">res/animation/spinner-035.png</file>
</qresource>
+ <qresource prefix="/fonts">
+ <file alias="monospace">res/fonts/RobotoMono-Bold.ttf</file>
+ </qresource>
</RCC>
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index f2a49e5a76..6677c9e3b5 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -30,6 +30,7 @@
#include <qt/macdockiconhandler.h>
#endif
+#include <functional>
#include <chain.h>
#include <chainparams.h>
#include <interfaces/handler.h>
@@ -87,6 +88,8 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
}
+ setContextMenuPolicy(Qt::PreventContextMenu);
+
#ifdef ENABLE_WALLET
enableWallet = WalletModel::isWalletEnabled();
#endif // ENABLE_WALLET
@@ -543,7 +546,6 @@ void BitcoinGUI::createToolBars()
{
QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
appToolBar = toolbar;
- toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
toolbar->setMovable(false);
toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
toolbar->addAction(overviewAction);
@@ -845,7 +847,7 @@ void BitcoinGUI::showDebugWindowActivateConsole()
void BitcoinGUI::showHelpMessageClicked()
{
- helpMessageDialog->show();
+ GUIUtil::bringToFront(helpMessageDialog);
}
#ifdef ENABLE_WALLET
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index a2f46c339b..b244bc94f2 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -19,6 +19,7 @@
#include <validation.h>
#include <stdint.h>
+#include <functional>
#include <QDebug>
#include <QThread>
@@ -70,14 +71,14 @@ ClientModel::~ClientModel()
int ClientModel::getNumConnections(unsigned int flags) const
{
- CConnman::NumConnections connections = CConnman::CONNECTIONS_NONE;
+ ConnectionDirection connections = ConnectionDirection::None;
if(flags == CONNECTIONS_IN)
- connections = CConnman::CONNECTIONS_IN;
+ connections = ConnectionDirection::In;
else if (flags == CONNECTIONS_OUT)
- connections = CConnman::CONNECTIONS_OUT;
+ connections = ConnectionDirection::Out;
else if (flags == CONNECTIONS_ALL)
- connections = CConnman::CONNECTIONS_ALL;
+ connections = ConnectionDirection::Both;
return m_node.getNodeCount(connections);
}
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 08abef7866..ca78c96d70 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -42,7 +42,7 @@ bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const {
}
CoinControlDialog::CoinControlDialog(CCoinControl& coin_control, WalletModel* _model, const PlatformStyle *_platformStyle, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::CoinControlDialog),
m_coin_control(coin_control),
model(_model),
diff --git a/src/qt/createwalletdialog.cpp b/src/qt/createwalletdialog.cpp
index 70f080f4de..1467801522 100644
--- a/src/qt/createwalletdialog.cpp
+++ b/src/qt/createwalletdialog.cpp
@@ -9,10 +9,12 @@
#include <qt/createwalletdialog.h>
#include <qt/forms/ui_createwalletdialog.h>
+#include <qt/guiutil.h>
+
#include <QPushButton>
CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::CreateWalletDialog)
{
ui->setupUi(this);
diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp
index cd25f856a2..e51ed9e656 100644
--- a/src/qt/editaddressdialog.cpp
+++ b/src/qt/editaddressdialog.cpp
@@ -13,7 +13,7 @@
EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::EditAddressDialog),
mapper(nullptr),
mode(_mode),
diff --git a/src/qt/forms/createwalletdialog.ui b/src/qt/forms/createwalletdialog.ui
index 0b33c2cb8d..881869a46c 100644
--- a/src/qt/forms/createwalletdialog.ui
+++ b/src/qt/forms/createwalletdialog.ui
@@ -7,140 +7,135 @@
<x>0</x>
<y>0</y>
<width>364</width>
- <height>213</height>
+ <height>249</height>
</rect>
</property>
<property name="windowTitle">
<string>Create Wallet</string>
</property>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="geometry">
- <rect>
- <x>10</x>
- <y>170</y>
- <width>341</width>
- <height>32</height>
- </rect>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- <widget class="QLineEdit" name="wallet_name_line_edit">
- <property name="geometry">
- <rect>
- <x>120</x>
- <y>20</y>
- <width>231</width>
- <height>24</height>
- </rect>
- </property>
- <property name="placeholderText">
- <string>Wallet</string>
- </property>
- </widget>
- <widget class="QLabel" name="label">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>20</y>
- <width>101</width>
- <height>21</height>
- </rect>
- </property>
- <property name="text">
- <string>Wallet Name</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="encrypt_wallet_checkbox">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>50</y>
- <width>220</width>
- <height>22</height>
- </rect>
- </property>
- <property name="toolTip">
- <string>Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice.</string>
- </property>
- <property name="text">
- <string>Encrypt Wallet</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- <widget class="QLabel" name="advanced_options_label">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>90</y>
- <width>220</width>
- <height>21</height>
- </rect>
- </property>
- <property name="styleSheet">
- <string notr="true">font-weight:bold;</string>
- </property>
- <property name="text">
- <string>Advanced options</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="disable_privkeys_checkbox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>115</y>
- <width>220</width>
- <height>22</height>
- </rect>
- </property>
- <property name="toolTip">
- <string>Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets.</string>
- </property>
- <property name="text">
- <string>Disable Private Keys</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="blank_wallet_checkbox">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>135</y>
- <width>220</width>
- <height>22</height>
- </rect>
- </property>
- <property name="toolTip">
- <string>Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time.</string>
- </property>
- <property name="text">
- <string>Make Blank Wallet</string>
- </property>
- </widget>
- <widget class="QCheckBox" name="descriptor_checkbox">
- <property name="geometry">
- <rect>
- <x>20</x>
- <y>155</y>
- <width>220</width>
- <height>22</height>
- </rect>
- </property>
- <property name="toolTip">
- <string>Use descriptors for scriptPubKey management</string>
- </property>
- <property name="text">
- <string>Descriptor Wallet</string>
- </property>
- </widget>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="wallet_name_label">
+ <property name="text">
+ <string>Wallet Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="wallet_name_line_edit">
+ <property name="minimumSize">
+ <size>
+ <width>262</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="placeholderText">
+ <string>Wallet</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="encrypt_wallet_checkbox">
+ <property name="toolTip">
+ <string>Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice.</string>
+ </property>
+ <property name="text">
+ <string>Encrypt Wallet</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_1">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>8</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Advanced Options</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_groupbox">
+ <item>
+ <widget class="QCheckBox" name="disable_privkeys_checkbox">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip">
+ <string>Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets.</string>
+ </property>
+ <property name="text">
+ <string>Disable Private Keys</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="blank_wallet_checkbox">
+ <property name="toolTip">
+ <string>Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time.</string>
+ </property>
+ <property name="text">
+ <string>Make Blank Wallet</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="descriptor_checkbox">
+ <property name="toolTip">
+ <string>Use descriptors for scriptPubKey management</string>
+ </property>
+ <property name="text">
+ <string>Descriptor Wallet</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
<tabstops>
<tabstop>wallet_name_line_edit</tabstop>
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index bce578a158..e45cafe48a 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -988,7 +988,7 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="widget_2" native="true">
+ <widget class="QWidget" name="peersTabRightPanel" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -1079,10 +1079,10 @@
<item row="1" column="0">
<widget class="QLabel" name="peerConnectionTypeLabel">
<property name="toolTip">
- <string>The type of peer connection:&lt;ul&gt;&lt;li&gt;Inbound: initiated by peer&lt;/li&gt;&lt;li&gt;Outbound Full Relay: default&lt;/li&gt;&lt;li&gt;Outbound Block Relay: does not relay transactions or addresses&lt;/li&gt;&lt;li&gt;Outbound Manual: added using RPC %1 or %2/%3 configuration options&lt;/li&gt;&lt;li&gt;Outbound Feeler: short-lived, for testing addresses&lt;/li&gt;&lt;li&gt;Outbound Address Fetch: short-lived, for soliciting addresses&lt;/li&gt;&lt;/ul&gt;</string>
+ <string>The direction and type of peer connection: %1</string>
</property>
<property name="text">
- <string>Connection Type</string>
+ <string>Direction/Type</string>
</property>
</widget>
</item>
@@ -1198,13 +1198,65 @@
</widget>
</item>
<item row="6" column="0">
+ <widget class="QLabel" name="peerRelayTxesLabel">
+ <property name="toolTip">
+ <string>Whether the peer requested us to relay transactions.</string>
+ </property>
+ <property name="text">
+ <string>Wants Tx Relay</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="peerRelayTxes">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="peerHighBandwidthLabel">
+ <property name="toolTip">
+ <string>High bandwidth BIP152 compact block relay: %1</string>
+ </property>
+ <property name="text">
+ <string>High Bandwidth</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QLabel" name="peerHighBandwidth">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Starting Block</string>
</property>
</widget>
</item>
- <item row="6" column="1">
+ <item row="8" column="1">
<widget class="QLabel" name="peerHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1220,14 +1272,14 @@
</property>
</widget>
</item>
- <item row="7" column="0">
+ <item row="9" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Synced Headers</string>
</property>
</widget>
</item>
- <item row="7" column="1">
+ <item row="9" column="1">
<widget class="QLabel" name="peerSyncHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1243,14 +1295,14 @@
</property>
</widget>
</item>
- <item row="8" column="0">
+ <item row="10" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Synced Blocks</string>
</property>
</widget>
</item>
- <item row="8" column="1">
+ <item row="10" column="1">
<widget class="QLabel" name="peerCommonHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1266,14 +1318,14 @@
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="11" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Connection Time</string>
</property>
</widget>
</item>
- <item row="9" column="1">
+ <item row="11" column="1">
<widget class="QLabel" name="peerConnTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1289,14 +1341,66 @@
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="12" column="0">
+ <widget class="QLabel" name="peerLastBlockLabel">
+ <property name="toolTip">
+ <string>Elapsed time since a novel block passing initial validity checks was received from this peer.</string>
+ </property>
+ <property name="text">
+ <string>Last Block</string>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="1">
+ <widget class="QLabel" name="peerLastBlock">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QLabel" name="peerLastTxLabel">
+ <property name="toolTip">
+ <string>Elapsed time since a novel transaction accepted into our mempool was received from this peer.</string>
+ </property>
+ <property name="text">
+ <string>Last Tx</string>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="1">
+ <widget class="QLabel" name="peerLastTx">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Last Send</string>
</property>
</widget>
</item>
- <item row="10" column="1">
+ <item row="14" column="1">
<widget class="QLabel" name="peerLastSend">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1312,14 +1416,14 @@
</property>
</widget>
</item>
- <item row="11" column="0">
+ <item row="15" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Last Receive</string>
</property>
</widget>
</item>
- <item row="11" column="1">
+ <item row="15" column="1">
<widget class="QLabel" name="peerLastRecv">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1335,14 +1439,14 @@
</property>
</widget>
</item>
- <item row="12" column="0">
+ <item row="16" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Sent</string>
</property>
</widget>
</item>
- <item row="12" column="1">
+ <item row="16" column="1">
<widget class="QLabel" name="peerBytesSent">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1358,14 +1462,14 @@
</property>
</widget>
</item>
- <item row="13" column="0">
+ <item row="17" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Received</string>
</property>
</widget>
</item>
- <item row="13" column="1">
+ <item row="17" column="1">
<widget class="QLabel" name="peerBytesRecv">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1381,14 +1485,14 @@
</property>
</widget>
</item>
- <item row="14" column="0">
+ <item row="18" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Ping Time</string>
</property>
</widget>
</item>
- <item row="14" column="1">
+ <item row="18" column="1">
<widget class="QLabel" name="peerPingTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1404,7 +1508,7 @@
</property>
</widget>
</item>
- <item row="15" column="0">
+ <item row="19" column="0">
<widget class="QLabel" name="peerPingWaitLabel">
<property name="toolTip">
<string>The duration of a currently outstanding ping.</string>
@@ -1414,7 +1518,7 @@
</property>
</widget>
</item>
- <item row="15" column="1">
+ <item row="19" column="1">
<widget class="QLabel" name="peerPingWait">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1430,14 +1534,14 @@
</property>
</widget>
</item>
- <item row="16" column="0">
+ <item row="20" column="0">
<widget class="QLabel" name="peerMinPingLabel">
<property name="text">
<string>Min Ping</string>
</property>
</widget>
</item>
- <item row="16" column="1">
+ <item row="20" column="1">
<widget class="QLabel" name="peerMinPing">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1453,14 +1557,14 @@
</property>
</widget>
</item>
- <item row="17" column="0">
+ <item row="21" column="0">
<widget class="QLabel" name="label_timeoffset">
<property name="text">
<string>Time Offset</string>
</property>
</widget>
</item>
- <item row="17" column="1">
+ <item row="21" column="1">
<widget class="QLabel" name="timeoffset">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1476,7 +1580,7 @@
</property>
</widget>
</item>
- <item row="18" column="0">
+ <item row="22" column="0">
<widget class="QLabel" name="peerMappedASLabel">
<property name="toolTip">
<string>The mapped Autonomous System used for diversifying peer selection.</string>
@@ -1486,7 +1590,7 @@
</property>
</widget>
</item>
- <item row="18" column="1">
+ <item row="22" column="1">
<widget class="QLabel" name="peerMappedAS">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -1502,7 +1606,7 @@
</property>
</widget>
</item>
- <item row="19" column="0">
+ <item row="23" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
index 8181cc47e2..6d279540e9 100644
--- a/src/qt/forms/optionsdialog.ui
+++ b/src/qt/forms/optionsdialog.ui
@@ -706,6 +706,106 @@
</layout>
</item>
<item>
+ <widget class="QGroupBox" name="font_groupBox">
+ <property name="title">
+ <string>Monospaced font in the Overview tab:</string>
+ </property>
+ <layout class="QVBoxLayout" name="font_verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="embeddedFont_horizontalLayout">
+ <item>
+ <widget class="QRadioButton" name="embeddedFont_radioButton">
+ <property name="text">
+ <string>embedded &quot;%1&quot;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="embeddedFont_horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="embeddedFont_verticalLayout">
+ <item>
+ <widget class="QLabel" name="embeddedFont_label_1">
+ <property name="text">
+ <string>111.11111111 BTC</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="embeddedFont_label_9">
+ <property name="text">
+ <string>909.09090909 BTC</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="font_line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="systemFont_horizontalLayout">
+ <item>
+ <widget class="QRadioButton" name="systemFont_radioButton">
+ <property name="text">
+ <string>closest matching &quot;%1&quot;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="systemFont_horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="systemFont_verticalLayout">
+ <item>
+ <widget class="QLabel" name="systemFont_label_1">
+ <property name="text">
+ <string>111.11111111 BTC</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="systemFont_label_9">
+ <property name="text">
+ <string>909.09090909 BTC</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<spacer name="verticalSpacer_Display">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index 4d3f90c484..f85de0811a 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -68,7 +68,7 @@
</property>
<property name="maximumSize">
<size>
- <width>30</width>
+ <width>45</width>
<height>16777215</height>
</size>
</property>
@@ -89,9 +89,6 @@
<height>24</height>
</size>
</property>
- <property name="flat">
- <bool>true</bool>
- </property>
</widget>
</item>
<item>
@@ -116,13 +113,6 @@
</property>
<item row="2" column="2">
<widget class="QLabel" name="labelWatchPending">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -142,13 +132,6 @@
</item>
<item row="2" column="1">
<widget class="QLabel" name="labelUnconfirmed">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -168,13 +151,6 @@
</item>
<item row="3" column="2">
<widget class="QLabel" name="labelWatchImmature">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -227,13 +203,6 @@
</item>
<item row="3" column="1">
<widget class="QLabel" name="labelImmature">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -273,13 +242,6 @@
</item>
<item row="5" column="1">
<widget class="QLabel" name="labelTotal">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -299,13 +261,6 @@
</item>
<item row="5" column="2">
<widget class="QLabel" name="labelWatchTotal">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -342,13 +297,6 @@
</item>
<item row="1" column="1">
<widget class="QLabel" name="labelBalance">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -368,13 +316,6 @@
</item>
<item row="1" column="2">
<widget class="QLabel" name="labelWatchAvailable">
- <property name="font">
- <font>
- <family>Monospace</family>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@@ -462,7 +403,7 @@
</property>
<property name="maximumSize">
<size>
- <width>30</width>
+ <width>45</width>
<height>16777215</height>
</size>
</property>
@@ -483,9 +424,6 @@
<height>24</height>
</size>
</property>
- <property name="flat">
- <bool>true</bool>
- </property>
</widget>
</item>
<item>
@@ -504,7 +442,7 @@
</layout>
</item>
<item>
- <widget class="QListView" name="listTransactions">
+ <widget class="TransactionOverviewWidget" name="listTransactions">
<property name="styleSheet">
<string notr="true">QListView { background: transparent; }</string>
</property>
@@ -517,9 +455,15 @@
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
+ <property name="sizeAdjustPolicy">
+ <enum>QAbstractScrollArea::AdjustToContents</enum>
+ </property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
+ <property name="uniformItemSizes">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
@@ -544,6 +488,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>TransactionOverviewWidget</class>
+ <extends>QListView</extends>
+ <header>qt/transactionoverviewwidget.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 430ecd322f..89d6deb70d 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -40,12 +40,14 @@
#include <QFontDatabase>
#include <QFontMetrics>
#include <QGuiApplication>
+#include <QJsonObject>
#include <QKeyEvent>
#include <QLineEdit>
#include <QList>
#include <QLocale>
#include <QMenu>
#include <QMouseEvent>
+#include <QPluginLoader>
#include <QProgressDialog>
#include <QScreen>
#include <QSettings>
@@ -57,6 +59,8 @@
#include <QUrlQuery>
#include <QtGlobal>
+#include <chrono>
+
#if defined(Q_OS_MAC)
#include <QProcess>
@@ -76,8 +80,11 @@ QString dateTimeStr(qint64 nTime)
return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
}
-QFont fixedPitchFont()
+QFont fixedPitchFont(bool use_embedded_font)
{
+ if (use_embedded_font) {
+ return {"Roboto Mono"};
+ }
return QFontDatabase::systemFont(QFontDatabase::FixedFont);
}
@@ -468,120 +475,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()
{
@@ -764,15 +657,19 @@ QString NetworkToQString(Network net)
assert(false);
}
-QString ConnectionTypeToQString(ConnectionType conn_type)
+QString ConnectionTypeToQString(ConnectionType conn_type, bool prepend_direction)
{
+ QString prefix;
+ if (prepend_direction) {
+ prefix = (conn_type == ConnectionType::INBOUND) ? QObject::tr("Inbound") : QObject::tr("Outbound") + " ";
+ }
switch (conn_type) {
- case ConnectionType::INBOUND: return QObject::tr("Inbound");
- case ConnectionType::OUTBOUND_FULL_RELAY: return QObject::tr("Outbound Full Relay");
- case ConnectionType::BLOCK_RELAY: return QObject::tr("Outbound Block Relay");
- case ConnectionType::MANUAL: return QObject::tr("Outbound Manual");
- case ConnectionType::FEELER: return QObject::tr("Outbound Feeler");
- case ConnectionType::ADDR_FETCH: return QObject::tr("Outbound Address Fetch");
+ case ConnectionType::INBOUND: return prefix;
+ case ConnectionType::OUTBOUND_FULL_RELAY: return prefix + QObject::tr("Full Relay");
+ case ConnectionType::BLOCK_RELAY: return prefix + QObject::tr("Block Relay");
+ case ConnectionType::MANUAL: return prefix + QObject::tr("Manual");
+ case ConnectionType::FEELER: return prefix + QObject::tr("Feeler");
+ case ConnectionType::ADDR_FETCH: return prefix + QObject::tr("Address Fetch");
} // no default case, so the compiler can warn about missing cases
assert(false);
}
@@ -811,9 +708,11 @@ QString formatServicesStr(quint64 mask)
return QObject::tr("None");
}
-QString formatPingTime(int64_t ping_usec)
+QString formatPingTime(std::chrono::microseconds ping_time)
{
- return (ping_usec == std::numeric_limits<int64_t>::max() || ping_usec == 0) ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(ping_usec / 1000), 10));
+ return (ping_time == std::chrono::microseconds::max() || ping_time == 0us) ?
+ QObject::tr("N/A") :
+ QString(QObject::tr("%1 ms")).arg(QString::number((int)(count_microseconds(ping_time) / 1000), 10));
}
QString formatTimeOffset(int64_t nTimeOffset)
@@ -936,6 +835,20 @@ void LogQtInfo()
const std::string plugin_link{"dynamic"};
#endif
LogPrintf("Qt %s (%s), plugin=%s (%s)\n", qVersion(), qt_link, QGuiApplication::platformName().toStdString(), plugin_link);
+ const auto static_plugins = QPluginLoader::staticPlugins();
+ if (static_plugins.empty()) {
+ LogPrintf("No static plugins.\n");
+ } else {
+ LogPrintf("Static plugins:\n");
+ for (const QStaticPlugin& p : static_plugins) {
+ QJsonObject meta_data = p.metaData();
+ const std::string plugin_class = meta_data.take(QString("className")).toString().toStdString();
+ const int plugin_version = meta_data.take(QString("version")).toInt();
+ LogPrintf(" %s, version %d\n", plugin_class, plugin_version);
+ }
+ }
+
+ LogPrintf("Style: %s / %s\n", QApplication::style()->objectName().toStdString(), QApplication::style()->metaObject()->className());
LogPrintf("System: %s, %s\n", QSysInfo::prettyProductName().toStdString(), QSysInfo::buildAbi().toStdString());
for (const QScreen* s : QGuiApplication::screens()) {
LogPrintf("Screen: %s %dx%d, pixel ratio=%.1f\n", s->name().toStdString(), s->size().width(), s->size().height(), s->devicePixelRatio());
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index c471b888f7..6395ec6abd 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -20,6 +20,8 @@
#include <QString>
#include <QTableView>
+#include <chrono>
+
class QValidatedLineEdit;
class SendCoinsRecipient;
@@ -45,12 +47,15 @@ QT_END_NAMESPACE
*/
namespace GUIUtil
{
+ // Use this flags to prevent a "What's This" button in the title bar of the dialog on Windows.
+ constexpr auto dialog_flags = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
+
// Create human-readable string from date
QString dateTimeStr(const QDateTime &datetime);
QString dateTimeStr(qint64 nTime);
// Return a monospace font
- QFont fixedPitchFont();
+ QFont fixedPitchFont(bool use_embedded_font = false);
// Set up widget for address
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
@@ -178,45 +183,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);
@@ -230,7 +196,7 @@ namespace GUIUtil
QString NetworkToQString(Network net);
/** Convert enum ConnectionType to QString */
- QString ConnectionTypeToQString(ConnectionType conn_type);
+ QString ConnectionTypeToQString(ConnectionType conn_type, bool prepend_direction);
/** Convert seconds into a QString with days, hours, mins, secs */
QString formatDurationStr(int secs);
@@ -238,8 +204,8 @@ namespace GUIUtil
/** Format CNodeStats.nServices bitmask into a user-readable string */
QString formatServicesStr(quint64 mask);
- /** Format a CNodeStats.m_ping_usec into a user-readable string or display N/A, if 0 */
- QString formatPingTime(int64_t ping_usec);
+ /** Format a CNodeStats.m_last_ping_time into a user-readable string or display N/A, if 0 */
+ QString formatPingTime(std::chrono::microseconds ping_time);
/** Format a CNodeCombinedStats.nTimeOffset into a user-readable string */
QString formatTimeOffset(int64_t nTimeOffset);
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 235722d091..aa6b2665fa 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -119,7 +119,7 @@ int GetPruneTargetGB()
} // namespace
Intro::Intro(QWidget *parent, int64_t blockchain_size_gb, int64_t chain_state_size_gb) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::Intro),
thread(nullptr),
signalled(false),
diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp
index b1081f6aee..ee70c1bc30 100644
--- a/src/qt/networkstyle.cpp
+++ b/src/qt/networkstyle.cpp
@@ -22,7 +22,6 @@ static const struct {
{"signet", QAPP_APP_NAME_SIGNET, 35, 15},
{"regtest", QAPP_APP_NAME_REGTEST, 160, 30},
};
-static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
// titleAddText needs to be const char* for tr()
NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *_titleAddText):
@@ -81,14 +80,12 @@ NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift,
const NetworkStyle* NetworkStyle::instantiate(const std::string& networkId)
{
std::string titleAddText = networkId == CBaseChainParams::MAIN ? "" : strprintf("[%s]", networkId);
- for (unsigned x=0; x<network_styles_count; ++x)
- {
- if (networkId == network_styles[x].networkId)
- {
+ for (const auto& network_style : network_styles) {
+ if (networkId == network_style.networkId) {
return new NetworkStyle(
- network_styles[x].appName,
- network_styles[x].iconColorHueShift,
- network_styles[x].iconColorSaturationReduction,
+ network_style.appName,
+ network_style.iconColorHueShift,
+ network_style.iconColorSaturationReduction,
titleAddText.c_str());
}
}
diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp
index 9a3d43c2a6..10bf82d532 100644
--- a/src/qt/openuridialog.cpp
+++ b/src/qt/openuridialog.cpp
@@ -11,7 +11,7 @@
#include <QUrl>
OpenURIDialog::OpenURIDialog(QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::OpenURIDialog)
{
ui->setupUi(this);
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 416b9c83c9..e6b9488344 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -29,7 +29,7 @@
#include <QTimer>
OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::OptionsDialog),
model(nullptr),
mapper(nullptr)
@@ -144,6 +144,20 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
ui->minimizeToTray->setEnabled(false);
}
+ QFont embedded_font{GUIUtil::fixedPitchFont(true)};
+ ui->embeddedFont_radioButton->setText(ui->embeddedFont_radioButton->text().arg(QFontInfo(embedded_font).family()));
+ embedded_font.setWeight(QFont::Bold);
+ ui->embeddedFont_label_1->setFont(embedded_font);
+ ui->embeddedFont_label_9->setFont(embedded_font);
+
+ QFont system_font{GUIUtil::fixedPitchFont(false)};
+ ui->systemFont_radioButton->setText(ui->systemFont_radioButton->text().arg(QFontInfo(system_font).family()));
+ system_font.setWeight(QFont::Bold);
+ ui->systemFont_label_1->setFont(system_font);
+ ui->systemFont_label_9->setFont(system_font);
+ // Checking the embeddedFont_radioButton automatically unchecks the systemFont_radioButton.
+ ui->systemFont_radioButton->setChecked(true);
+
GUIUtil::handleCloseWindowShortcut(this);
}
@@ -246,6 +260,7 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->lang, OptionsModel::Language);
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
+ mapper->addMapping(ui->embeddedFont_radioButton, OptionsModel::UseEmbeddedMonospacedFont);
}
void OptionsDialog::setOkButtonState(bool fState)
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 1e0391a35c..d51a5b06ff 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -163,6 +163,12 @@ void OptionsModel::Init(bool resetSettings)
addOverriddenOption("-lang");
language = settings.value("language").toString();
+
+ if (!settings.contains("UseEmbeddedMonospacedFont")) {
+ settings.setValue("UseEmbeddedMonospacedFont", "true");
+ }
+ m_use_embedded_monospaced_font = settings.value("UseEmbeddedMonospacedFont").toBool();
+ Q_EMIT useEmbeddedMonospacedFontChanged(m_use_embedded_monospaced_font);
}
/** Helper function to copy contents from one QSettings to another.
@@ -326,6 +332,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return strThirdPartyTxUrls;
case Language:
return settings.value("language");
+ case UseEmbeddedMonospacedFont:
+ return m_use_embedded_monospaced_font;
case CoinControlFeatures:
return fCoinControlFeatures;
case Prune:
@@ -453,6 +461,11 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
setRestartRequired(true);
}
break;
+ case UseEmbeddedMonospacedFont:
+ m_use_embedded_monospaced_font = value.toBool();
+ settings.setValue("UseEmbeddedMonospacedFont", m_use_embedded_monospaced_font);
+ Q_EMIT useEmbeddedMonospacedFontChanged(m_use_embedded_monospaced_font);
+ break;
case CoinControlFeatures:
fCoinControlFeatures = value.toBool();
settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index f7171951a1..4d012a9b8f 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -59,6 +59,7 @@ public:
DisplayUnit, // BitcoinUnits::Unit
ThirdPartyTxUrls, // QString
Language, // QString
+ UseEmbeddedMonospacedFont, // bool
CoinControlFeatures, // bool
ThreadsScriptVerif, // int
Prune, // bool
@@ -84,6 +85,7 @@ public:
bool getMinimizeOnClose() const { return fMinimizeOnClose; }
int getDisplayUnit() const { return nDisplayUnit; }
QString getThirdPartyTxUrls() const { return strThirdPartyTxUrls; }
+ bool getUseEmbeddedMonospacedFont() const { return m_use_embedded_monospaced_font; }
bool getCoinControlFeatures() const { return fCoinControlFeatures; }
const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
@@ -107,6 +109,7 @@ private:
QString language;
int nDisplayUnit;
QString strThirdPartyTxUrls;
+ bool m_use_embedded_monospaced_font;
bool fCoinControlFeatures;
/* settings that were overridden by command-line */
QString strOverriddenByCommandLine;
@@ -120,6 +123,7 @@ Q_SIGNALS:
void displayUnitChanged(int unit);
void coinControlFeaturesChanged(bool);
void showTrayIconChanged(bool);
+ void useEmbeddedMonospacedFontChanged(bool);
};
#endif // BITCOIN_QT_OPTIONSMODEL_H
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index cca4dce624..7f12b1d2b5 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -12,6 +12,7 @@
#include <qt/optionsmodel.h>
#include <qt/platformstyle.h>
#include <qt/transactionfilterproxy.h>
+#include <qt/transactionoverviewwidget.h>
#include <qt/transactiontablemodel.h>
#include <qt/walletmodel.h>
@@ -21,6 +22,9 @@
#include <QPainter>
#include <QStatusTipEvent>
+#include <algorithm>
+#include <map>
+
#define DECORATION_SIZE 54
#define NUM_ITEMS 5
@@ -34,7 +38,7 @@ public:
QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC),
platformStyle(_platformStyle)
{
-
+ connect(this, &TxViewDelegate::width_changed, this, &TxViewDelegate::sizeHintChanged);
}
inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
@@ -67,13 +71,15 @@ public:
painter->setPen(foreground);
QRect boundingRect;
- painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address, &boundingRect);
+ painter->drawText(addressRect, Qt::AlignLeft | Qt::AlignVCenter, address, &boundingRect);
+ int address_rect_min_width = boundingRect.width();
if (index.data(TransactionTableModel::WatchonlyRole).toBool())
{
QIcon iconWatchonly = qvariant_cast<QIcon>(index.data(TransactionTableModel::WatchonlyDecorationRole));
QRect watchonlyRect(boundingRect.right() + 5, mainRect.top()+ypad+halfheight, 16, halfheight);
iconWatchonly.paint(painter, watchonlyRect);
+ address_rect_min_width += 5 + watchonlyRect.width();
}
if(amount < 0)
@@ -94,23 +100,42 @@ public:
{
amountText = QString("[") + amountText + QString("]");
}
- painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);
+
+ QRect amount_bounding_rect;
+ painter->drawText(amountRect, Qt::AlignRight | Qt::AlignVCenter, amountText, &amount_bounding_rect);
painter->setPen(option.palette.color(QPalette::Text));
- painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));
+ QRect date_bounding_rect;
+ painter->drawText(amountRect, Qt::AlignLeft | Qt::AlignVCenter, GUIUtil::dateTimeStr(date), &date_bounding_rect);
+
+ const int minimum_width = std::max(address_rect_min_width, amount_bounding_rect.width() + date_bounding_rect.width());
+ const auto search = m_minimum_width.find(index.row());
+ if (search == m_minimum_width.end() || search->second != minimum_width) {
+ m_minimum_width[index.row()] = minimum_width;
+ Q_EMIT width_changed(index);
+ }
painter->restore();
}
inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
- return QSize(DECORATION_SIZE, DECORATION_SIZE);
+ const auto search = m_minimum_width.find(index.row());
+ const int minimum_text_width = search == m_minimum_width.end() ? 0 : search->second;
+ return {DECORATION_SIZE + 8 + minimum_text_width, DECORATION_SIZE};
}
int unit;
- const PlatformStyle *platformStyle;
+Q_SIGNALS:
+ //! An intermediate signal for emitting from the `paint() const` member function.
+ void width_changed(const QModelIndex& index) const;
+
+private:
+ const PlatformStyle* platformStyle;
+ mutable std::map<int, int> m_minimum_width;
};
+
#include <qt/overviewpage.moc>
OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) :
@@ -126,7 +151,6 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
// use a SingleColorIcon for the "out of sync warning" icon
QIcon icon = platformStyle->SingleColorIcon(":/icons/warning");
- icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503)
ui->labelTransactionsStatus->setIcon(icon);
ui->labelWalletStatus->setIcon(icon);
@@ -136,7 +160,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
- connect(ui->listTransactions, &QListView::clicked, this, &OverviewPage::handleTransactionClicked);
+ connect(ui->listTransactions, &TransactionOverviewWidget::clicked, this, &OverviewPage::handleTransactionClicked);
// start with displaying the "out of sync" warnings
showOutOfSyncWarning(true);
@@ -233,6 +257,9 @@ void OverviewPage::setClientModel(ClientModel *model)
// Show warning, for example if this is a prerelease version
connect(model, &ClientModel::alertsChanged, this, &OverviewPage::updateAlerts);
updateAlerts(model->getStatusBarWarnings());
+
+ connect(model->getOptionsModel(), &OptionsModel::useEmbeddedMonospacedFontChanged, this, &OverviewPage::setMonospacedFont);
+ setMonospacedFont(model->getOptionsModel()->getUseEmbeddedMonospacedFont());
}
}
@@ -297,3 +324,17 @@ void OverviewPage::showOutOfSyncWarning(bool fShow)
ui->labelWalletStatus->setVisible(fShow);
ui->labelTransactionsStatus->setVisible(fShow);
}
+
+void OverviewPage::setMonospacedFont(bool use_embedded_font)
+{
+ QFont f = GUIUtil::fixedPitchFont(use_embedded_font);
+ f.setWeight(QFont::Bold);
+ ui->labelBalance->setFont(f);
+ ui->labelUnconfirmed->setFont(f);
+ ui->labelImmature->setFont(f);
+ ui->labelTotal->setFont(f);
+ ui->labelWatchAvailable->setFont(f);
+ ui->labelWatchPending->setFont(f);
+ ui->labelWatchImmature->setFont(f);
+ ui->labelWatchTotal->setFont(f);
+}
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index 578ef601fb..5158c81678 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -61,6 +61,7 @@ private Q_SLOTS:
void updateAlerts(const QString &warnings);
void updateWatchOnlyLabels(bool showWatchOnly);
void handleOutOfSyncWarningClicks();
+ void setMonospacedFont(bool use_embedded_font);
};
#endif // BITCOIN_QT_OVERVIEWPAGE_H
diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp
index bad81d894c..3459bf4cf8 100644
--- a/src/qt/peertablemodel.cpp
+++ b/src/qt/peertablemodel.cpp
@@ -23,25 +23,25 @@ bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombine
if (order == Qt::DescendingOrder)
std::swap(pLeft, pRight);
- switch(column)
- {
+ switch (static_cast<PeerTableModel::ColumnIndex>(column)) {
case PeerTableModel::NetNodeId:
return pLeft->nodeid < pRight->nodeid;
case PeerTableModel::Address:
return pLeft->addrName.compare(pRight->addrName) < 0;
+ case PeerTableModel::ConnectionType:
+ return pLeft->m_conn_type < pRight->m_conn_type;
case PeerTableModel::Network:
return pLeft->m_network < pRight->m_network;
case PeerTableModel::Ping:
- return pLeft->m_min_ping_usec < pRight->m_min_ping_usec;
+ return pLeft->m_min_ping_time < pRight->m_min_ping_time;
case PeerTableModel::Sent:
return pLeft->nSendBytes < pRight->nSendBytes;
case PeerTableModel::Received:
return pLeft->nRecvBytes < pRight->nRecvBytes;
case PeerTableModel::Subversion:
return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
- }
-
- return false;
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
}
// private implementation
@@ -155,36 +155,44 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
CNodeCombinedStats *rec = static_cast<CNodeCombinedStats*>(index.internalPointer());
+ const auto column = static_cast<ColumnIndex>(index.column());
if (role == Qt::DisplayRole) {
- switch(index.column())
- {
+ switch (column) {
case NetNodeId:
return (qint64)rec->nodeStats.nodeid;
case Address:
// prepend to peer address down-arrow symbol for inbound connection and up-arrow for outbound connection
return QString(rec->nodeStats.fInbound ? "↓ " : "↑ ") + QString::fromStdString(rec->nodeStats.addrName);
+ case ConnectionType:
+ return GUIUtil::ConnectionTypeToQString(rec->nodeStats.m_conn_type, /* prepend_direction */ false);
case Network:
return GUIUtil::NetworkToQString(rec->nodeStats.m_network);
case Ping:
- return GUIUtil::formatPingTime(rec->nodeStats.m_min_ping_usec);
+ return GUIUtil::formatPingTime(rec->nodeStats.m_min_ping_time);
case Sent:
return GUIUtil::formatBytes(rec->nodeStats.nSendBytes);
case Received:
return GUIUtil::formatBytes(rec->nodeStats.nRecvBytes);
case Subversion:
return QString::fromStdString(rec->nodeStats.cleanSubVer);
- }
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
} else if (role == Qt::TextAlignmentRole) {
- switch (index.column()) {
- case Network:
- return QVariant(Qt::AlignCenter);
- case Ping:
- case Sent:
- case Received:
- return QVariant(Qt::AlignRight | Qt::AlignVCenter);
- default:
- return QVariant();
- }
+ switch (column) {
+ case NetNodeId:
+ case Address:
+ return {};
+ case ConnectionType:
+ case Network:
+ return QVariant(Qt::AlignCenter);
+ case Ping:
+ case Sent:
+ case Received:
+ return QVariant(Qt::AlignRight | Qt::AlignVCenter);
+ case Subversion:
+ return {};
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
} else if (role == StatsRole) {
switch (index.column()) {
case NetNodeId: return QVariant::fromValue(rec);
diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h
index 7bff239507..0823235ec0 100644
--- a/src/qt/peertablemodel.h
+++ b/src/qt/peertablemodel.h
@@ -59,12 +59,13 @@ public:
enum ColumnIndex {
NetNodeId = 0,
- Address = 1,
- Network = 2,
- Ping = 3,
- Sent = 4,
- Received = 5,
- Subversion = 6
+ Address,
+ ConnectionType,
+ Network,
+ Ping,
+ Sent,
+ Received,
+ Subversion
};
enum {
@@ -87,7 +88,7 @@ public Q_SLOTS:
private:
interfaces::Node& m_node;
- const QStringList columns{tr("Peer Id"), tr("Address"), tr("Network"), tr("Ping"), tr("Sent"), tr("Received"), tr("User Agent")};
+ const QStringList columns{tr("Peer Id"), tr("Address"), tr("Type"), tr("Network"), tr("Ping"), tr("Sent"), tr("Received"), tr("User Agent")};
std::unique_ptr<PeerTablePriv> priv;
QTimer *timer;
};
diff --git a/src/qt/platformstyle.cpp b/src/qt/platformstyle.cpp
index c6b80fd340..aab8d8e4af 100644
--- a/src/qt/platformstyle.cpp
+++ b/src/qt/platformstyle.cpp
@@ -23,7 +23,6 @@ static const struct {
/* Other: linux, unix, ... */
{"other", true, true, false}
};
-static const unsigned platform_styles_count = sizeof(platform_styles)/sizeof(*platform_styles);
namespace {
/* Local functions for colorizing single-color images */
@@ -121,15 +120,13 @@ QIcon PlatformStyle::TextColorIcon(const QIcon& icon) const
const PlatformStyle *PlatformStyle::instantiate(const QString &platformId)
{
- for (unsigned x=0; x<platform_styles_count; ++x)
- {
- if (platformId == platform_styles[x].platformId)
- {
+ for (const auto& platform_style : platform_styles) {
+ if (platformId == platform_style.platformId) {
return new PlatformStyle(
- platform_styles[x].platformId,
- platform_styles[x].imagesOnButtons,
- platform_styles[x].colorizeIcons,
- platform_styles[x].useExtraSpacing);
+ platform_style.platformId,
+ platform_style.imagesOnButtons,
+ platform_style.colorizeIcons,
+ platform_style.useExtraSpacing);
}
}
return nullptr;
diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp
index 28103495da..d1f8d56100 100644
--- a/src/qt/psbtoperationsdialog.cpp
+++ b/src/qt/psbtoperationsdialog.cpp
@@ -19,7 +19,7 @@
PSBTOperationsDialog::PSBTOperationsDialog(
- QWidget* parent, WalletModel* wallet_model, ClientModel* client_model) : QDialog(parent),
+ QWidget* parent, WalletModel* wallet_model, ClientModel* client_model) : QDialog(parent, GUIUtil::dialog_flags),
m_ui(new Ui::PSBTOperationsDialog),
m_wallet_model(wallet_model),
m_client_model(client_model)
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 1a9cd78d1e..61cb89d75a 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -8,6 +8,7 @@
#include <qt/forms/ui_receivecoinsdialog.h>
#include <qt/addresstablemodel.h>
+#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/platformstyle.h>
#include <qt/receiverequestdialog.h>
@@ -18,12 +19,12 @@
#include <QCursor>
#include <QMessageBox>
#include <QScrollBar>
+#include <QSettings>
#include <QTextDocument>
ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::ReceiveCoinsDialog),
- columnResizingFixer(nullptr),
model(nullptr),
platformStyle(_platformStyle)
{
@@ -43,13 +44,15 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid
// context menu actions
QAction *copyURIAction = new QAction(tr("Copy URI"), this);
- QAction *copyLabelAction = new QAction(tr("Copy label"), this);
- QAction *copyMessageAction = new QAction(tr("Copy message"), this);
- QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
+ QAction* copyAddressAction = new QAction(tr("Copy address"), this);
+ copyLabelAction = new QAction(tr("Copy label"), this);
+ copyMessageAction = new QAction(tr("Copy message"), this);
+ copyAmountAction = new QAction(tr("Copy amount"), this);
// context menu
contextMenu = new QMenu(this);
contextMenu->addAction(copyURIAction);
+ contextMenu->addAction(copyAddressAction);
contextMenu->addAction(copyLabelAction);
contextMenu->addAction(copyMessageAction);
contextMenu->addAction(copyAmountAction);
@@ -57,11 +60,27 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid
// context menu signals
connect(ui->recentRequestsView, &QWidget::customContextMenuRequested, this, &ReceiveCoinsDialog::showMenu);
connect(copyURIAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyURI);
+ connect(copyAddressAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyAddress);
connect(copyLabelAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyLabel);
connect(copyMessageAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyMessage);
connect(copyAmountAction, &QAction::triggered, this, &ReceiveCoinsDialog::copyAmount);
connect(ui->clearButton, &QPushButton::clicked, this, &ReceiveCoinsDialog::clear);
+
+ QTableView* tableView = ui->recentRequestsView;
+ tableView->verticalHeader()->hide();
+ tableView->setAlternatingRowColors(true);
+ tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
+
+ QSettings settings;
+ if (!tableView->horizontalHeader()->restoreState(settings.value("RecentRequestsViewHeaderState").toByteArray())) {
+ 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);
+ }
}
void ReceiveCoinsDialog::setModel(WalletModel *_model)
@@ -75,22 +94,12 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
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);
- tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
+ tableView->sortByColumn(RecentRequestsTableModel::Date, Qt::DescendingOrder);
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);
@@ -110,6 +119,8 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
ReceiveCoinsDialog::~ReceiveCoinsDialog()
{
+ QSettings settings;
+ settings.setValue("RecentRequestsViewHeaderState", ui->recentRequestsView->horizontalHeader()->saveState());
delete ui;
}
@@ -234,14 +245,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())
@@ -267,9 +270,18 @@ void ReceiveCoinsDialog::copyColumnToClipboard(int column)
// context menu
void ReceiveCoinsDialog::showMenu(const QPoint &point)
{
- if (!selectedRow().isValid()) {
+ const QModelIndex sel = selectedRow();
+ if (!sel.isValid()) {
return;
}
+
+ // disable context menu actions when appropriate
+ const RecentRequestsTableModel* const submodel = model->getRecentRequestsTableModel();
+ const RecentRequestEntry& req = submodel->entry(sel.row());
+ copyLabelAction->setDisabled(req.recipient.label.isEmpty());
+ copyMessageAction->setDisabled(req.recipient.message.isEmpty());
+ copyAmountAction->setDisabled(req.recipient.amount == 0);
+
contextMenu->exec(QCursor::pos());
}
@@ -286,6 +298,19 @@ void ReceiveCoinsDialog::copyURI()
GUIUtil::setClipboard(uri);
}
+// context menu action: copy address
+void ReceiveCoinsDialog::copyAddress()
+{
+ const QModelIndex sel = selectedRow();
+ if (!sel.isValid()) {
+ return;
+ }
+
+ const RecentRequestsTableModel* const submodel = model->getRecentRequestsTableModel();
+ const QString address = submodel->entry(sel.row()).recipient.address;
+ GUIUtil::setClipboard(address);
+}
+
// context menu action: copy label
void ReceiveCoinsDialog::copyLabel()
{
diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h
index 9b89bd6a8b..fbbccc5a33 100644
--- a/src/qt/receivecoinsdialog.h
+++ b/src/qt/receivecoinsdialog.h
@@ -51,14 +51,15 @@ public Q_SLOTS:
private:
Ui::ReceiveCoinsDialog *ui;
- GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
WalletModel *model;
QMenu *contextMenu;
+ QAction* copyLabelAction;
+ QAction* copyMessageAction;
+ QAction* copyAmountAction;
const PlatformStyle *platformStyle;
QModelIndex selectedRow();
void copyColumnToClipboard(int column);
- virtual void resizeEvent(QResizeEvent *event) override;
private Q_SLOTS:
void on_receiveButton_clicked();
@@ -69,6 +70,7 @@ private Q_SLOTS:
void updateDisplayUnit();
void showMenu(const QPoint &point);
void copyURI();
+ void copyAddress();
void copyLabel();
void copyMessage();
void copyAmount();
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
index bef3edc5fe..78ae5c07da 100644
--- a/src/qt/receiverequestdialog.cpp
+++ b/src/qt/receiverequestdialog.cpp
@@ -19,7 +19,7 @@
#endif
ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::ReceiveRequestDialog),
model(nullptr)
{
diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp
index 18b913774b..03531a1381 100644
--- a/src/qt/recentrequeststablemodel.cpp
+++ b/src/qt/recentrequeststablemodel.cpp
@@ -181,7 +181,7 @@ void RecentRequestsTableModel::addNewRequest(const SendCoinsRecipient &recipient
// called from ctor when loading from wallet
void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
{
- std::vector<char> data(recipient.begin(), recipient.end());
+ std::vector<uint8_t> data(recipient.begin(), recipient.end());
CDataStream ss(data, SER_DISK, CLIENT_VERSION);
RecentRequestEntry entry;
diff --git a/src/qt/res/fonts/RobotoMono-Bold.ttf b/src/qt/res/fonts/RobotoMono-Bold.ttf
new file mode 100644
index 0000000000..900fce6848
--- /dev/null
+++ b/src/qt/res/fonts/RobotoMono-Bold.ttf
Binary files differ
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index df98dbbc99..b258219894 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -16,9 +16,10 @@
#include <chainparams.h>
#include <interfaces/node.h>
#include <netbase.h>
-#include <rpc/server.h>
#include <rpc/client.h>
+#include <rpc/server.h>
#include <util/strencodings.h>
+#include <util/string.h>
#include <util/system.h>
#include <util/threadnames.h>
@@ -459,11 +460,27 @@ RPCConsole::RPCConsole(interfaces::Node& node, const PlatformStyle *_platformSty
ui->splitter->restoreState(settings.value("PeersTabSplitterSizes").toByteArray());
- QChar nonbreaking_hyphen(8209);
+ constexpr QChar nonbreaking_hyphen(8209);
+ const std::vector<QString> CONNECTION_TYPE_DOC{
+ tr("Inbound: initiated by peer"),
+ tr("Outbound Full Relay: default"),
+ tr("Outbound Block Relay: does not relay transactions or addresses"),
+ tr("Outbound Manual: added using RPC %1 or %2/%3 configuration options")
+ .arg("addnode")
+ .arg(QString(nonbreaking_hyphen) + "addnode")
+ .arg(QString(nonbreaking_hyphen) + "connect"),
+ tr("Outbound Feeler: short-lived, for testing addresses"),
+ tr("Outbound Address Fetch: short-lived, for soliciting addresses")};
+ const QString list{"<ul><li>" + Join(CONNECTION_TYPE_DOC, QString("</li><li>")) + "</li></ul>"};
+ ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(list));
+ const QString hb_list{"<ul><li>\""
+ + ts.to + "\" – " + tr("we selected the peer for high bandwidth relay") + "</li><li>\""
+ + ts.from + "\" – " + tr("the peer selected us for high bandwidth relay") + "</li><li>\""
+ + ts.no + "\" – " + tr("no high bandwidth relay selected") + "</li></ul>"};
+ ui->peerHighBandwidthLabel->setToolTip(ui->peerHighBandwidthLabel->toolTip().arg(hb_list));
ui->dataDir->setToolTip(ui->dataDir->toolTip().arg(QString(nonbreaking_hyphen) + "datadir"));
ui->blocksDir->setToolTip(ui->blocksDir->toolTip().arg(QString(nonbreaking_hyphen) + "blocksdir"));
ui->openDebugLogfileButton->setToolTip(ui->openDebugLogfileButton->toolTip().arg(PACKAGE_NAME));
- ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg("addnode").arg(QString(nonbreaking_hyphen) + "addnode").arg(QString(nonbreaking_hyphen) + "connect"));
if (platformStyle->getImagesOnButtons()) {
ui->openDebugLogfileButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
@@ -602,10 +619,10 @@ void RPCConsole::setClientModel(ClientModel *model, int bestblock_height, int64_
// create peer table context menu actions
QAction* disconnectAction = new QAction(tr("&Disconnect"), this);
- QAction* banAction1h = new QAction(tr("Ban for") + " " + tr("1 &hour"), this);
- QAction* banAction24h = new QAction(tr("Ban for") + " " + tr("1 &day"), this);
- QAction* banAction7d = new QAction(tr("Ban for") + " " + tr("1 &week"), this);
- QAction* banAction365d = new QAction(tr("Ban for") + " " + tr("1 &year"), this);
+ QAction* banAction1h = new QAction(ts.ban_for + " " + tr("1 &hour"), this);
+ QAction* banAction24h = new QAction(ts.ban_for + " " + tr("1 &day"), this);
+ QAction* banAction7d = new QAction(ts.ban_for + " " + tr("1 &week"), this);
+ QAction* banAction365d = new QAction(ts.ban_for + " " + tr("1 &year"), this);
// create peer table context menu
peersTableContextMenu = new QMenu(this);
@@ -1085,7 +1102,7 @@ void RPCConsole::updateDetailWidget()
{
const QList<QModelIndex> selected_peers = GUIUtil::getEntryData(ui->peerWidget, PeerTableModel::NetNodeId);
if (!clientModel || !clientModel->getPeerTableModel() || selected_peers.size() != 1) {
- ui->detailWidget->hide();
+ ui->peersTabRightPanel->hide();
ui->peerHeading->setText(tr("Select a peer to view detailed information."));
return;
}
@@ -1097,21 +1114,29 @@ void RPCConsole::updateDetailWidget()
peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
ui->peerHeading->setText(peerAddrDetails);
ui->peerServices->setText(GUIUtil::formatServicesStr(stats->nodeStats.nServices));
- ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastSend) : tr("never"));
- ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastRecv) : tr("never"));
+ ui->peerRelayTxes->setText(stats->nodeStats.fRelayTxes ? ts.yes : ts.no);
+ QString bip152_hb_settings;
+ if (stats->nodeStats.m_bip152_highbandwidth_to) bip152_hb_settings = ts.to;
+ if (stats->nodeStats.m_bip152_highbandwidth_from) bip152_hb_settings += (bip152_hb_settings.isEmpty() ? ts.from : QLatin1Char('/') + ts.from);
+ if (bip152_hb_settings.isEmpty()) bip152_hb_settings = ts.no;
+ ui->peerHighBandwidth->setText(bip152_hb_settings);
+ const int64_t time_now{GetSystemTimeInSeconds()};
+ ui->peerConnTime->setText(GUIUtil::formatDurationStr(time_now - stats->nodeStats.nTimeConnected));
+ ui->peerLastBlock->setText(TimeDurationField(time_now, stats->nodeStats.nLastBlockTime));
+ ui->peerLastTx->setText(TimeDurationField(time_now, stats->nodeStats.nLastTXTime));
+ ui->peerLastSend->setText(TimeDurationField(time_now, stats->nodeStats.nLastSend));
+ ui->peerLastRecv->setText(TimeDurationField(time_now, stats->nodeStats.nLastRecv));
ui->peerBytesSent->setText(GUIUtil::formatBytes(stats->nodeStats.nSendBytes));
ui->peerBytesRecv->setText(GUIUtil::formatBytes(stats->nodeStats.nRecvBytes));
- ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nTimeConnected));
- ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.m_ping_usec));
- ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.m_ping_wait_usec));
- ui->peerMinPing->setText(GUIUtil::formatPingTime(stats->nodeStats.m_min_ping_usec));
+ ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.m_last_ping_time));
+ ui->peerMinPing->setText(GUIUtil::formatPingTime(stats->nodeStats.m_min_ping_time));
ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset));
ui->peerVersion->setText(QString::number(stats->nodeStats.nVersion));
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
- ui->peerConnectionType->setText(GUIUtil::ConnectionTypeToQString(stats->nodeStats.m_conn_type));
+ ui->peerConnectionType->setText(GUIUtil::ConnectionTypeToQString(stats->nodeStats.m_conn_type, /* prepend_direction */ true));
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
if (stats->nodeStats.m_permissionFlags == PF_NONE) {
- ui->peerPermissions->setText(tr("N/A"));
+ ui->peerPermissions->setText(ts.na);
} else {
QStringList permissions;
for (const auto& permission : NetPermissions::ToStrings(stats->nodeStats.m_permissionFlags)) {
@@ -1119,27 +1144,28 @@ void RPCConsole::updateDetailWidget()
}
ui->peerPermissions->setText(permissions.join(" & "));
}
- ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) : tr("N/A"));
+ ui->peerMappedAS->setText(stats->nodeStats.m_mapped_as != 0 ? QString::number(stats->nodeStats.m_mapped_as) : ts.na);
// This check fails for example if the lock was busy and
// nodeStateStats couldn't be fetched.
if (stats->fNodeStateStatsAvailable) {
// Sync height is init to -1
- if (stats->nodeStateStats.nSyncHeight > -1)
+ if (stats->nodeStateStats.nSyncHeight > -1) {
ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight));
- else
- ui->peerSyncHeight->setText(tr("Unknown"));
-
+ } else {
+ ui->peerSyncHeight->setText(ts.unknown);
+ }
// Common height is init to -1
- if (stats->nodeStateStats.nCommonHeight > -1)
+ if (stats->nodeStateStats.nCommonHeight > -1) {
ui->peerCommonHeight->setText(QString("%1").arg(stats->nodeStateStats.nCommonHeight));
- else
- ui->peerCommonHeight->setText(tr("Unknown"));
-
+ } else {
+ ui->peerCommonHeight->setText(ts.unknown);
+ }
ui->peerHeight->setText(QString::number(stats->nodeStateStats.m_starting_height));
+ ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStateStats.m_ping_wait));
}
- ui->detailWidget->show();
+ ui->peersTabRightPanel->show();
}
void RPCConsole::resizeEvent(QResizeEvent *event)
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 5f308dc36d..b9806e40c9 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -136,6 +136,11 @@ Q_SIGNALS:
void cmdRequest(const QString &command, const WalletModel* wallet_model);
private:
+ struct TranslatedStrings {
+ const QString yes{tr("Yes")}, no{tr("No")}, to{tr("To")}, from{tr("From")},
+ ban_for{tr("Ban for")}, na{tr("N/A")}, unknown{tr("Unknown")};
+ } const ts;
+
void startExecutor();
void setTrafficGraphRange(int mins);
@@ -168,6 +173,11 @@ private:
/** Update UI with latest network info from model. */
void updateNetworkState();
+ /** Helper for the output of a time duration field. Inputs are UNIX epoch times. */
+ QString TimeDurationField(uint64_t time_now, uint64_t time_at_event) const {
+ return time_at_event ? GUIUtil::formatDurationStr(time_now - time_at_event) : tr("Never");
+ }
+
private Q_SLOTS:
void updateAlerts(const QString& warnings);
};
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 61a3e53133..0aafce6528 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -55,7 +55,7 @@ int getIndexForConfTarget(int target) {
}
SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::SendCoinsDialog),
clientModel(nullptr),
model(nullptr),
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 6c110f0688..2e7df60574 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -19,7 +19,7 @@
#include <QClipboard>
SignVerifyMessageDialog::SignVerifyMessageDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::SignVerifyMessageDialog),
model(nullptr),
platformStyle(_platformStyle)
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 5796a6ef56..2292c01d6a 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -18,6 +18,8 @@
#include <util/system.h>
#include <util/translation.h>
+#include <functional>
+
#include <QApplication>
#include <QCloseEvent>
#include <QPainter>
diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp
index 24d7735447..0d9928d363 100644
--- a/src/qt/test/rpcnestedtests.cpp
+++ b/src/qt/test/rpcnestedtests.cpp
@@ -33,7 +33,7 @@ static RPCHelpMan rpcNestedTest_rpc()
}
static const CRPCCommand vRPCCommands[] = {
- {"test", "rpcNestedTest", &rpcNestedTest_rpc, {"arg1", "arg2", "arg3"}},
+ {"test", &rpcNestedTest_rpc},
};
void RPCNestedTests::rpcNestedTests()
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index 9ef5fe8fc7..a1baf6a402 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -54,6 +54,13 @@ int main(int argc, char* argv[])
NodeContext node_context;
std::unique_ptr<interfaces::Node> node = interfaces::MakeNode(&node_context);
+ gArgs.ForceSetArg("-listen", "0");
+ gArgs.ForceSetArg("-listenonion", "0");
+ gArgs.ForceSetArg("-discover", "0");
+ gArgs.ForceSetArg("-dnsseed", "0");
+ gArgs.ForceSetArg("-fixedseeds", "0");
+ gArgs.ForceSetArg("-upnp", "0");
+ gArgs.ForceSetArg("-natpmp", "0");
bool fInvalid = false;
diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp
index b547bf7645..6f31d8463f 100644
--- a/src/qt/transactiondescdialog.cpp
+++ b/src/qt/transactiondescdialog.cpp
@@ -11,7 +11,7 @@
#include <QModelIndex>
TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::TransactionDescDialog)
{
ui->setupUi(this);
diff --git a/src/qt/transactionoverviewwidget.h b/src/qt/transactionoverviewwidget.h
new file mode 100644
index 0000000000..2bdead7bc4
--- /dev/null
+++ b/src/qt/transactionoverviewwidget.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2021 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H
+#define BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H
+
+#include <qt/transactiontablemodel.h>
+
+#include <QListView>
+#include <QSize>
+#include <QSizePolicy>
+
+QT_BEGIN_NAMESPACE
+class QShowEvent;
+class QWidget;
+QT_END_NAMESPACE
+
+class TransactionOverviewWidget : public QListView
+{
+ Q_OBJECT
+
+public:
+ explicit TransactionOverviewWidget(QWidget* parent = nullptr) : QListView(parent) {}
+
+ QSize sizeHint() const override
+ {
+ return {sizeHintForColumn(TransactionTableModel::ToAddress), QListView::sizeHint().height()};
+ }
+
+protected:
+ void showEvent(QShowEvent* event) override
+ {
+ Q_UNUSED(event);
+ QSizePolicy sp = sizePolicy();
+ sp.setHorizontalPolicy(QSizePolicy::Minimum);
+ setSizePolicy(sp);
+ }
+};
+
+#endif // BITCOIN_QT_TRANSACTIONOVERVIEWWIDGET_H
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 05b250eea9..a7556eed04 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -19,6 +19,7 @@
#include <uint256.h>
#include <algorithm>
+#include <functional>
#include <QColor>
#include <QDateTime>
@@ -525,27 +526,30 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
return QVariant();
TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer());
- switch(role)
- {
+ const auto column = static_cast<ColumnIndex>(index.column());
+ switch (role) {
case RawDecorationRole:
- switch(index.column())
- {
+ switch (column) {
case Status:
return txStatusDecoration(rec);
case Watchonly:
return txWatchonlyDecoration(rec);
+ case Date: return {};
+ case Type: return {};
case ToAddress:
return txAddressDecoration(rec);
- }
- break;
+ case Amount: return {};
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
case Qt::DecorationRole:
{
QIcon icon = qvariant_cast<QIcon>(index.data(RawDecorationRole));
return platformStyle->TextColorIcon(icon);
}
case Qt::DisplayRole:
- switch(index.column())
- {
+ switch (column) {
+ case Status: return {};
+ case Watchonly: return {};
case Date:
return formatTxDate(rec);
case Type:
@@ -554,12 +558,11 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
return formatTxToAddress(rec, false);
case Amount:
return formatTxAmount(rec, true, BitcoinUnits::SeparatorStyle::ALWAYS);
- }
- break;
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
case Qt::EditRole:
// Edit role is used for sorting, so return the unformatted values
- switch(index.column())
- {
+ switch (column) {
case Status:
return QString::fromStdString(rec->status.sortKey);
case Date:
@@ -572,8 +575,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
return formatTxToAddress(rec, true);
case Amount:
return qint64(rec->credit + rec->debit);
- }
- break;
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
case Qt::ToolTipRole:
return formatTooltip(rec);
case Qt::TextAlignmentRole:
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 0cf6480b82..f99a3e286d 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -31,6 +31,7 @@
#include <QMenu>
#include <QPoint>
#include <QScrollBar>
+#include <QSettings>
#include <QTableView>
#include <QTimer>
#include <QUrl>
@@ -126,27 +127,39 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
vlayout->setContentsMargins(0,0,0,0);
vlayout->setSpacing(0);
- QTableView *view = new QTableView(this);
+ transactionView = new QTableView(this);
+ transactionView->setObjectName("transactionView");
vlayout->addLayout(hlayout);
vlayout->addWidget(createDateRangeWidget());
- vlayout->addWidget(view);
+ vlayout->addWidget(transactionView);
vlayout->setSpacing(0);
- int width = view->verticalScrollBar()->sizeHint().width();
+ int width = transactionView->verticalScrollBar()->sizeHint().width();
// Cover scroll bar width with spacing
if (platformStyle->getUseExtraSpacing()) {
hlayout->addSpacing(width+2);
} else {
hlayout->addSpacing(width);
}
- // Always show scroll bar
- view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- view->setTabKeyNavigation(false);
- view->setContextMenuPolicy(Qt::CustomContextMenu);
-
- view->installEventFilter(this);
-
- transactionView = view;
- transactionView->setObjectName("transactionView");
+ transactionView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ transactionView->setTabKeyNavigation(false);
+ transactionView->setContextMenuPolicy(Qt::CustomContextMenu);
+ transactionView->installEventFilter(this);
+ transactionView->setAlternatingRowColors(true);
+ transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ transactionView->setSortingEnabled(true);
+ transactionView->verticalHeader()->hide();
+
+ QSettings settings;
+ if (!transactionView->horizontalHeader()->restoreState(settings.value("TransactionViewHeaderState").toByteArray())) {
+ transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Watchonly, WATCHONLY_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Date, DATE_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH);
+ transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
+ transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
+ transactionView->horizontalHeader()->setStretchLastSection(true);
+ }
// Actions
abandonAction = new QAction(tr("Abandon transaction"), this);
@@ -158,7 +171,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this);
QAction *copyTxHexAction = new QAction(tr("Copy raw transaction"), this);
QAction *copyTxPlainText = new QAction(tr("Copy full transaction details"), this);
- QAction *editLabelAction = new QAction(tr("Edit label"), this);
+ QAction *editLabelAction = new QAction(tr("Edit address label"), this);
QAction *showDetailsAction = new QAction(tr("Show transaction details"), this);
contextMenu = new QMenu(this);
@@ -183,8 +196,8 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(prefix_typing_delay, &QTimer::timeout, this, &TransactionView::changedSearch);
- connect(view, &QTableView::doubleClicked, this, &TransactionView::doubleClicked);
- connect(view, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu);
+ connect(transactionView, &QTableView::doubleClicked, this, &TransactionView::doubleClicked);
+ connect(transactionView, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu);
connect(bumpFeeAction, &QAction::triggered, this, &TransactionView::bumpFee);
connect(abandonAction, &QAction::triggered, this, &TransactionView::abandonTx);
@@ -204,6 +217,12 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa
});
}
+TransactionView::~TransactionView()
+{
+ QSettings settings;
+ settings.setValue("TransactionViewHeaderState", transactionView->horizontalHeader()->saveState());
+}
+
void TransactionView::setModel(WalletModel *_model)
{
this->model = _model;
@@ -214,25 +233,9 @@ void TransactionView::setModel(WalletModel *_model)
transactionProxyModel->setDynamicSortFilter(true);
transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
-
transactionProxyModel->setSortRole(Qt::EditRole);
-
- transactionView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
transactionView->setModel(transactionProxyModel);
- transactionView->setAlternatingRowColors(true);
- transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
- transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
- transactionView->horizontalHeader()->setSortIndicator(TransactionTableModel::Date, Qt::DescendingOrder);
- transactionView->setSortingEnabled(true);
- transactionView->verticalHeader()->hide();
-
- transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);
- transactionView->setColumnWidth(TransactionTableModel::Watchonly, WATCHONLY_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, this);
+ transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);
if (_model->getOptionsModel())
{
@@ -623,14 +626,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)
{
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index b268823066..35ada4aa7a 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -35,6 +35,7 @@ class TransactionView : public QWidget
public:
explicit TransactionView(const PlatformStyle *platformStyle, QWidget *parent = nullptr);
+ ~TransactionView();
void setModel(WalletModel *model);
@@ -82,10 +83,6 @@ private:
QWidget *createDateRangeWidget();
- GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer{nullptr};
-
- virtual void resizeEvent(QResizeEvent* event) override;
-
bool eventFilter(QObject *obj, QEvent *event) override;
private Q_SLOTS:
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index b7f85446f4..05499b2a41 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -29,7 +29,7 @@
/** "Help message" or "About" dialog box */
HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
- QDialog(parent),
+ QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::HelpMessageDialog)
{
ui->setupUi(this);
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 2edb7eff8a..02b3c62867 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -106,9 +106,24 @@ void WalletFrame::setCurrentWallet(WalletModel* wallet_model)
{
if (mapWalletViews.count(wallet_model) == 0) return;
+ // Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget.
+ WalletView* view_about_to_hide = currentWalletView();
+ if (view_about_to_hide) {
+ QSizePolicy sp = view_about_to_hide->sizePolicy();
+ sp.setHorizontalPolicy(QSizePolicy::Ignored);
+ view_about_to_hide->setSizePolicy(sp);
+ }
+
WalletView *walletView = mapWalletViews.value(wallet_model);
- walletStack->setCurrentWidget(walletView);
assert(walletView);
+
+ // Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously.
+ QSizePolicy sp = walletView->sizePolicy();
+ sp.setHorizontalPolicy(QSizePolicy::Preferred);
+ walletView->setSizePolicy(sp);
+ walletView->updateGeometry();
+
+ walletStack->setCurrentWidget(walletView);
walletView->updateEncryptionStatus();
}
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index cad472b43b..02254da3ce 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -29,6 +29,7 @@
#include <wallet/wallet.h> // for CRecipient
#include <stdint.h>
+#include <functional>
#include <QDebug>
#include <QMessageBox>
@@ -244,7 +245,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
ssTx << *newTx;
- transaction_array.append(&(ssTx[0]), ssTx.size());
+ transaction_array.append((const char*)&(ssTx[0]), ssTx.size());
}
// Add addresses / update labels that we've sent to the address book,
@@ -514,6 +515,13 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
questionString.append("</td><td>");
questionString.append(BitcoinUnits::formatHtmlWithUnit(getOptionsModel()->getDisplayUnit(), new_fee));
questionString.append("</td></tr></table>");
+
+ // Display warning in the "Confirm fee bump" window if the "Coin Control Features" option is enabled
+ if (getOptionsModel()->getCoinControlFeatures()) {
+ questionString.append("<br><br>");
+ questionString.append(tr("Warning: This may pay the additional fee by reducing change outputs or adding inputs, when necessary. It may add a new change output if one does not already exist. These changes may potentially leak privacy."));
+ }
+
SendConfirmationDialog confirmationDialog(tr("Confirm fee bump"), questionString);
confirmationDialog.exec();
QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result());