Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
9e58f8c
merge bitcoin-core/gui#408: Add missing mnemonics in menu bar options
kwvg Jan 27, 2025
3f9dca5
merge bitcoin-core/gui#398: Pass WalletModel object to the WalletView…
kwvg Aug 7, 2021
33da874
merge bitcoin-core/gui#434: Keep InitExecutor in main gui thread
kwvg Jan 26, 2025
3db335f
merge bitcoin-core/gui#439: Do not show unused widgets at startup
kwvg Sep 29, 2021
c02483c
merge bitcoin-core/gui#319: Paste button in Open URI dialog
kwvg Jan 27, 2025
d451246
merge bitcoin-core/gui#404: Fix various edge case bugs in QValidatedL…
kwvg Jan 26, 2025
817a95a
merge bitcoin#24041: Restore GetIntArg saturating behavior
kwvg Jan 26, 2025
40b09dd
merge bitcoin#24375: Do not use `LocalTestingSetup` in getarg_tests t…
kwvg Feb 12, 2022
f9b7614
merge bitcoin#24498: Avoid crash on startup if int specified in setti…
kwvg Jan 26, 2025
aec2927
merge bitcoin-core/gui#569: add regression test for bitcoin-core/gui#567
kwvg Mar 24, 2022
b25f165
merge bitcoin-core/gui#576: Add qt unit test runner summary
kwvg Apr 6, 2022
6e4eee0
merge bitcoin-core/gui#618: Add `transactionoverviewwidget.cpp` sourc…
kwvg Jun 14, 2022
18d1523
merge bitcoin-core/gui#620: Replace `QRegExp` with `QRegularExpression`
kwvg Jun 21, 2022
75a1016
merge bitcoin-core/gui#631: Disallow encryption of watchonly wallets
kwvg Jul 15, 2022
6bf4854
partial bitcoin#23757: fix GUI not loading on Qt 5.15
kwvg Dec 12, 2021
0cb2724
merge bitcoin-core/gui#591: Add tests for `tableView` in `AddressBook…
kwvg Jan 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ BITCOIN_QT_WALLET_CPP = \
qt/transactiondesc.cpp \
qt/transactiondescdialog.cpp \
qt/transactionfilterproxy.cpp \
qt/transactionoverviewwidget.cpp \
qt/transactionrecord.cpp \
qt/transactiontablemodel.cpp \
qt/transactionview.cpp \
Expand Down
5 changes: 4 additions & 1 deletion src/Makefile.qttest.include
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ TESTS += qt/test/test_dash-qt

TEST_QT_MOC_CPP = \
qt/test/moc_apptests.cpp \
qt/test/moc_optiontests.cpp \
qt/test/moc_rpcnestedtests.cpp \
qt/test/moc_trafficgraphdatatests.cpp \
qt/test/moc_uritests.cpp
Expand All @@ -21,6 +22,7 @@ endif # ENABLE_WALLET
TEST_QT_H = \
qt/test/addressbooktests.h \
qt/test/apptests.h \
qt/test/optiontests.h \
qt/test/rpcnestedtests.h \
qt/test/uritests.h \
qt/test/util.h \
Expand All @@ -32,6 +34,7 @@ qt_test_test_dash_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_

qt_test_test_dash_qt_SOURCES = \
qt/test/apptests.cpp \
qt/test/optiontests.cpp \
qt/test/rpcnestedtests.cpp \
qt/test/test_main.cpp \
qt/test/trafficgraphdatatests.cpp \
Expand All @@ -55,7 +58,7 @@ if ENABLE_ZMQ
qt_test_test_dash_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
qt_test_test_dash_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBDASHBLS) $(LIBUNIVALUE) $(LIBLEVELDB) \
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BACKTRACE_LIB) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BACKTRACE_LIB) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \
$(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(GMP_LIBS)
qt_test_test_dash_qt_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
Expand Down
2 changes: 2 additions & 0 deletions src/qt/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
Q_IMPORT_PLUGIN(QMacStylePlugin);
#elif defined(QT_QPA_PLATFORM_ANDROID)
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
#endif
#endif

Expand Down
18 changes: 13 additions & 5 deletions src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
frameBlocksLayout->addWidget(unitDisplayControl);
frameBlocksLayout->addStretch();
frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
labelWalletHDStatusIcon->hide();
frameBlocksLayout->addWidget(labelWalletEncryptionIcon);
labelWalletEncryptionIcon->hide();
}
frameBlocksLayout->addWidget(labelProxyIcon);
frameBlocksLayout->addStretch();
Expand Down Expand Up @@ -410,7 +412,7 @@ void BitcoinGUI::createActions()
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Dash addresses"));
m_load_psbt_action = new QAction(tr("&Load PSBT from file…"), this);
m_load_psbt_action->setStatusTip(tr("Load Partially Signed Blockchain Transaction"));
m_load_psbt_clipboard_action = new QAction(tr("Load PSBT from clipboard…"), this);
m_load_psbt_clipboard_action = new QAction(tr("Load PSBT from &clipboard…"), this);
m_load_psbt_clipboard_action->setStatusTip(tr("Load Partially Signed Blockchain Transaction from clipboard"));

openInfoAction = new QAction(tr("&Information"), this);
Expand All @@ -423,7 +425,7 @@ void BitcoinGUI::createActions()
openPeersAction->setStatusTip(tr("Show peers info"));
openRepairAction = new QAction(tr("Wallet &Repair"), this);
openRepairAction->setStatusTip(tr("Show wallet repair options"));
openConfEditorAction = new QAction(tr("Open Wallet &Configuration File"), this);
openConfEditorAction = new QAction(tr("Open &wallet configuration file"), this);
openConfEditorAction->setStatusTip(tr("Open configuration file"));
// override TextHeuristicRole set by default which confuses this action with application settings
openConfEditorAction->setMenuRole(QAction::NoRole);
Expand Down Expand Up @@ -610,7 +612,7 @@ void BitcoinGUI::createMenuBar()

QMenu* window_menu = appMenuBar->addMenu(tr("&Window"));

QAction* minimize_action = window_menu->addAction(tr("Minimize"));
QAction* minimize_action = window_menu->addAction(tr("&Minimize"));
minimize_action->setShortcut(QKeySequence(tr("Ctrl+M")));
connect(minimize_action, &QAction::triggered, [] {
QApplication::activeWindow()->showMinimized();
Expand Down Expand Up @@ -915,8 +917,8 @@ void BitcoinGUI::addWallet(WalletModel* walletModel)
{
if (!walletFrame) return;

WalletView* wallet_view = new WalletView(walletFrame);
if (!walletFrame->addWallet(walletModel, wallet_view)) return;
WalletView* wallet_view = new WalletView(walletModel, walletFrame);
if (!walletFrame->addView(wallet_view)) return;

rpcConsole->addWallet(walletModel);
if (m_wallet_selector->count() == 0) {
Expand Down Expand Up @@ -1874,6 +1876,12 @@ void BitcoinGUI::setEncryptionStatus(int status)
{
switch(status)
{
case WalletModel::NoKeys:
labelWalletEncryptionIcon->hide();
encryptWalletAction->setChecked(false);
changePassphraseAction->setEnabled(false);
encryptWalletAction->setEnabled(false);
break;
case WalletModel::Unencrypted:
labelWalletEncryptionIcon->show();
labelWalletEncryptionIcon->setPixmap(GUIUtil::getIcon("lock_open", GUIUtil::ThemedColor::RED).pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
Expand Down
20 changes: 19 additions & 1 deletion src/qt/forms/openuridialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="pasteButton">
<property name="toolTip">
<string extracomment="Tooltip text for button that allows you to paste an address that is in your clipboard.">Paste address from clipboard</string>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
Expand Down Expand Up @@ -64,7 +80,9 @@
<header>qt/qvalidatedlineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<resources>
<include location="../dash.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
Expand Down
30 changes: 15 additions & 15 deletions src/qt/guiutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include <QPluginLoader>
#include <QPointer>
#include <QProgressDialog>
#include <QRegularExpression>
#include <QScreen>
#include <QSettings>
#include <QShortcut>
Expand Down Expand Up @@ -512,6 +513,17 @@ QString getDefaultDataDirectory()
return PathToQString(GetDefaultDataDir());
}

QString ExtractFirstSuffixFromFilter(const QString& filter)
{
QRegularExpression filter_re(QStringLiteral(".* \\(\\*\\.(.*)[ \\)]"), QRegularExpression::InvertedGreedinessOption);
QString suffix;
QRegularExpressionMatch m = filter_re.match(filter);
if (m.hasMatch()) {
suffix = m.captured(1);
}
return suffix;
}

QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,
const QString &filter,
QString *selectedSuffixOut)
Expand All @@ -529,13 +541,7 @@ QString getSaveFileName(QWidget *parent, const QString &caption, const QString &
/* Directly convert path to native OS path separators */
QString result = QDir::toNativeSeparators(QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter));

/* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
QString selectedSuffix;
if(filter_re.exactMatch(selectedFilter))
{
selectedSuffix = filter_re.cap(1);
}
QString selectedSuffix = ExtractFirstSuffixFromFilter(selectedFilter);

/* Add suffix if needed */
QFileInfo info(result);
Expand Down Expand Up @@ -577,14 +583,8 @@ QString getOpenFileName(QWidget *parent, const QString &caption, const QString &

if(selectedSuffixOut)
{
/* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
QString selectedSuffix;
if(filter_re.exactMatch(selectedFilter))
{
selectedSuffix = filter_re.cap(1);
}
*selectedSuffixOut = selectedSuffix;
*selectedSuffixOut = ExtractFirstSuffixFromFilter(selectedFilter);
;
}
return result;
}
Expand Down
8 changes: 8 additions & 0 deletions src/qt/guiutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ namespace GUIUtil
*/
QString getDefaultDataDirectory();

/**
* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...).
*
* @param[in] filter Filter specification such as "Comma Separated Files (*.csv)"
* @return QString
*/
QString ExtractFirstSuffixFromFilter(const QString& filter);

/** Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix
when no suffix is provided by the user.

Expand Down
73 changes: 40 additions & 33 deletions src/qt/initexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <qt/initexecutor.h>

#include <interfaces/node.h>
#include <qt/guiutil.h>
#include <util/system.h>
#include <util/threadnames.h>

Expand All @@ -20,7 +21,7 @@
InitExecutor::InitExecutor(interfaces::Node& node)
: QObject(), m_node(node)
{
this->moveToThread(&m_thread);
m_context.moveToThread(&m_thread);
m_thread.start();
}

Expand All @@ -40,46 +41,52 @@ void InitExecutor::handleRunawayException(const std::exception_ptr e)

void InitExecutor::initialize()
{
try {
util::ThreadRename("qt-init");
qDebug() << __func__ << ": Running initialization in thread";
interfaces::BlockAndHeaderTipInfo tip_info;
bool rv = m_node.appInitMain(&tip_info);
Q_EMIT initializeResult(rv, tip_info);
} catch (...) {
handleRunawayException(std::current_exception());
}
GUIUtil::ObjectInvoke(&m_context, [this] {
try {
util::ThreadRename("qt-init");
qDebug() << "Running initialization in thread";
interfaces::BlockAndHeaderTipInfo tip_info;
bool rv = m_node.appInitMain(&tip_info);
Q_EMIT initializeResult(rv, tip_info);
} catch (...) {
handleRunawayException(std::current_exception());
}
});
}

void InitExecutor::restart(QStringList args)
{
static bool executing_restart{false};
GUIUtil::ObjectInvoke(&m_context, [this, args] {
static bool executing_restart{false};

if(!executing_restart) { // Only restart 1x, no matter how often a user clicks on a restart-button
executing_restart = true;
try {
qDebug() << __func__ << ": Running Restart in thread";
m_node.appPrepareShutdown();
qDebug() << __func__ << ": Shutdown finished";
Q_EMIT shutdownResult();
CExplicitNetCleanup::callCleanup();
QProcess::startDetached(QApplication::applicationFilePath(), args);
qDebug() << __func__ << ": Restart initiated...";
QApplication::quit();
} catch (...) {
handleRunawayException(std::current_exception());
if (!executing_restart) { // Only restart 1x, no matter how often a user clicks on a restart-button
executing_restart = true;
try {
qDebug() << "Running Restart in thread";
m_node.appPrepareShutdown();
qDebug() << "Shutdown finished";
Q_EMIT shutdownResult();
CExplicitNetCleanup::callCleanup();
QProcess::startDetached(QApplication::applicationFilePath(), args);
qDebug() << "Restart initiated...";
QApplication::quit();
} catch (...) {
handleRunawayException(std::current_exception());
}
}
}
});
}

void InitExecutor::shutdown()
{
try {
qDebug() << __func__ << ": Running Shutdown in thread";
m_node.appShutdown();
qDebug() << __func__ << ": Shutdown finished";
Q_EMIT shutdownResult();
} catch (...) {
handleRunawayException(std::current_exception());
}
GUIUtil::ObjectInvoke(&m_context, [this] {
try {
qDebug() << "Running Shutdown in thread";
m_node.appShutdown();
qDebug() << "Shutdown finished";
Q_EMIT shutdownResult();
} catch (...) {
handleRunawayException(std::current_exception());
}
});
}
1 change: 1 addition & 0 deletions src/qt/initexecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public Q_SLOTS:
void handleRunawayException(const std::exception_ptr e);

interfaces::Node& m_node;
QObject m_context;
QThread m_thread;
};

Expand Down
23 changes: 17 additions & 6 deletions src/qt/openuridialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
#include <qt/guiutil.h>
#include <qt/sendcoinsrecipient.h>

#include <QAbstractButton>
#include <QLineEdit>
#include <QUrl>

OpenURIDialog::OpenURIDialog(QWidget *parent) :
QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::OpenURIDialog)
OpenURIDialog::OpenURIDialog(QWidget* parent) : QDialog(parent, GUIUtil::dialog_flags),
ui(new Ui::OpenURIDialog)
{
ui->setupUi(this);
GUIUtil::setIcon(ui->pasteButton, "editpaste");
QObject::connect(ui->pasteButton, &QAbstractButton::clicked, ui->uriEdit, &QLineEdit::paste);

GUIUtil::updateFonts();
GUIUtil::disableMacFocusRect(this);

GUIUtil::handleCloseWindowShortcut(this);
}

Expand All @@ -35,11 +38,19 @@ QString OpenURIDialog::getURI()
void OpenURIDialog::accept()
{
SendCoinsRecipient rcp;
if(GUIUtil::parseBitcoinURI(getURI(), &rcp))
{
if (GUIUtil::parseBitcoinURI(getURI(), &rcp)) {
/* Only accept value URIs */
QDialog::accept();
} else {
ui->uriEdit->setValid(false);
}
}

void OpenURIDialog::changeEvent(QEvent* e)
{
QDialog::changeEvent(e);
if (e->type() == QEvent::StyleChange) {
// Adjust button icon colors on theme changes
GUIUtil::setIcon(ui->pasteButton, "editpaste");
}
}
5 changes: 3 additions & 2 deletions src/qt/openuridialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ class OpenURIDialog : public QDialog
Q_OBJECT

public:
explicit OpenURIDialog(QWidget *parent);
explicit OpenURIDialog(QWidget* parent);
~OpenURIDialog();

QString getURI();

protected Q_SLOTS:
void accept() override;
void changeEvent(QEvent* e) override;

private:
Ui::OpenURIDialog *ui;
Ui::OpenURIDialog* ui;
};

#endif // BITCOIN_QT_OPENURIDIALOG_H
Loading