mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-24 12:41:41 -05:00

-BEGIN VERIFY SCRIPT- regex_string='^(?!//).*(AC_APPLE_UNIVERSAL_BUILD|BOOST_PROCESS_USE_STD_FS|CHAR_EQUALS_INT8|CLIENT_VERSION_BUILD|CLIENT_VERSION_IS_RELEASE|CLIENT_VERSION_MAJOR|CLIENT_VERSION_MINOR|COPYRIGHT_HOLDERS|COPYRIGHT_HOLDERS_FINAL|COPYRIGHT_HOLDERS_SUBSTITUTION|COPYRIGHT_YEAR|ENABLE_ARM_SHANI|ENABLE_AVX2|ENABLE_EXTERNAL_SIGNER|ENABLE_SSE41|ENABLE_TRACING|ENABLE_WALLET|ENABLE_X86_SHANI|ENABLE_ZMQ|HAVE_BOOST|HAVE_BUILTIN_CLZL|HAVE_BUILTIN_CLZLL|HAVE_BYTESWAP_H|HAVE_CLMUL|HAVE_CONSENSUS_LIB|HAVE_CXX20|HAVE_DECL_BE16TOH|HAVE_DECL_BE32TOH|HAVE_DECL_BE64TOH|HAVE_DECL_BSWAP_16|HAVE_DECL_BSWAP_32|HAVE_DECL_BSWAP_64|HAVE_DECL_FORK|HAVE_DECL_FREEIFADDRS|HAVE_DECL_GETIFADDRS|HAVE_DECL_HTOBE16|HAVE_DECL_HTOBE32|HAVE_DECL_HTOBE64|HAVE_DECL_HTOLE16|HAVE_DECL_HTOLE32|HAVE_DECL_HTOLE64|HAVE_DECL_LE16TOH|HAVE_DECL_LE32TOH|HAVE_DECL_LE64TOH|HAVE_DECL_PIPE2|HAVE_DECL_SETSID|HAVE_DECL_STRERROR_R|HAVE_DEFAULT_VISIBILITY_ATTRIBUTE|HAVE_DLFCN_H|HAVE_DLLEXPORT_ATTRIBUTE|HAVE_ENDIAN_H|HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR|HAVE_FDATASYNC|HAVE_GETENTROPY_RAND|HAVE_GETRANDOM|HAVE_GMTIME_R|HAVE_INTTYPES_H|HAVE_LIBADVAPI32|HAVE_LIBCOMCTL32|HAVE_LIBCOMDLG32|HAVE_LIBGDI32|HAVE_LIBIPHLPAPI|HAVE_LIBKERNEL32|HAVE_LIBOLE32|HAVE_LIBOLEAUT32|HAVE_LIBSHELL32|HAVE_LIBSHLWAPI|HAVE_LIBUSER32|HAVE_LIBUUID|HAVE_LIBWINMM|HAVE_LIBWS2_32|HAVE_MALLOC_INFO|HAVE_MALLOPT_ARENA_MAX|HAVE_MINIUPNPC_MINIUPNPC_H|HAVE_MINIUPNPC_UPNPCOMMANDS_H|HAVE_MINIUPNPC_UPNPERRORS_H|HAVE_NATPMP_H|HAVE_O_CLOEXEC|HAVE_POSIX_FALLOCATE|HAVE_PTHREAD|HAVE_PTHREAD_PRIO_INHERIT|HAVE_STDINT_H|HAVE_STDIO_H|HAVE_STDLIB_H|HAVE_STRERROR_R|HAVE_STRINGS_H|HAVE_STRING_H|HAVE_STRONG_GETAUXVAL|HAVE_SYSCTL|HAVE_SYSCTL_ARND|HAVE_SYSTEM|HAVE_SYS_ENDIAN_H|HAVE_SYS_PRCTL_H|HAVE_SYS_RESOURCES_H|HAVE_SYS_SELECT_H|HAVE_SYS_STAT_H|HAVE_SYS_SYSCTL_H|HAVE_SYS_TYPES_H|HAVE_SYS_VMMETER_H|HAVE_THREAD_LOCAL|HAVE_TIMINGSAFE_BCMP|HAVE_UNISTD_H|HAVE_VM_VM_PARAM_H|LT_OBJDIR|PACKAGE_BUGREPORT|PACKAGE_NAME|PACKAGE_STRING|PACKAGE_TARNAME|PACKAGE_URL|PACKAGE_VERSION|PTHREAD_CREATE_JOINABLE|QT_QPA_PLATFORM_ANDROID|QT_QPA_PLATFORM_COCOA|QT_QPA_PLATFORM_MINIMAL|QT_QPA_PLATFORM_WINDOWS|QT_QPA_PLATFORM_XCB|QT_STATICPLUGIN|STDC_HEADERS|STRERROR_R_CHAR_P|USE_ASM|USE_BDB|USE_DBUS|USE_NATPMP|USE_QRCODE|USE_SQLITE|USE_UPNP|_FILE_OFFSET_BITS|_LARGE_FILES)' exclusion_files=":(exclude)src/minisketch :(exclude)src/crc32c :(exclude)src/secp256k1 :(exclude)src/crypto/sha256_arm_shani.cpp :(exclude)src/crypto/sha256_avx2.cpp :(exclude)src/crypto/sha256_sse41.cpp :(exclude)src/crypto/sha256_x86_shani.cpp" git grep --perl-regexp --files-with-matches "$regex_string" -- '*.cpp' $exclusion_files | xargs git grep -L "bitcoin-config.h" | while read -r file; do line_number=$(awk -v my_file="$file" '/\/\/ file COPYING or https?:\/\/www.opensource.org\/licenses\/mit-license.php\./ {line = NR} /^\/\// && NR == line + 1 {while(getline && /^\/\//) line = NR} END {print line+1}' "$file"); sed -i "${line_number}i\\\\n\#if defined(HAVE_CONFIG_H)\\n#include <config/bitcoin-config.h>\\n\#endif" "$file"; done; git grep --perl-regexp --files-with-matches "$regex_string" -- '*.h' $exclusion_files | xargs git grep -L "bitcoin-config.h" | while read -r file; do sed -i "/#define.*_H/a \\\\n\#if defined(HAVE_CONFIG_H)\\n#include <config/bitcoin-config.h>\\n\#endif" "$file"; done; for file in $(git grep --files-with-matches 'bitcoin-config.h' -- '*.cpp' '*.h' $exclusion_files); do if ! grep -q --perl-regexp "$regex_string" $file; then sed -i '/HAVE_CONFIG_H/{N;N;N;d;}' $file; fi; done; -END VERIFY SCRIPT- The first command creates a regular expression for matching all bitcoin-config.h symbols in the following form: ^(?!//).*(AC_APPLE_UNIVERSAL_BUILD|BOOST_PROCESS_USE_STD_FS|...|_LARGE_FILES). It was generated with: ./autogen.sh && printf '^(?!//).*(%s)' $(awk '/^#undef/ {print $2}' src/config/bitcoin-config.h.in | paste -sd "|" -) The second command holds a list of files and directories that should not be processed. These include subtree directories as well as some crypto files that already get their symbols through the makefile. The third command checks for missing bitcoin-config headers in .cpp files and adds the header if it is missing. The fourth command checks for missing bitcoin-config headers in .h files and adds the header if it is missing. The fifth command checks for unneeded bitcoin-config headers in sources files and removes the header if it is unneeded.
240 lines
6.8 KiB
C++
240 lines
6.8 KiB
C++
// Copyright (c) 2011-2022 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <qt/sendcoinsentry.h>
|
|
#include <qt/forms/ui_sendcoinsentry.h>
|
|
|
|
#include <qt/addressbookpage.h>
|
|
#include <qt/addresstablemodel.h>
|
|
#include <qt/guiutil.h>
|
|
#include <qt/optionsmodel.h>
|
|
#include <qt/platformstyle.h>
|
|
#include <qt/walletmodel.h>
|
|
|
|
#include <QApplication>
|
|
#include <QClipboard>
|
|
|
|
SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *parent) :
|
|
QWidget(parent),
|
|
ui(new Ui::SendCoinsEntry),
|
|
platformStyle(_platformStyle)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(":/icons/address-book"));
|
|
ui->pasteButton->setIcon(platformStyle->SingleColorIcon(":/icons/editpaste"));
|
|
ui->deleteButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
|
|
|
|
if (platformStyle->getUseExtraSpacing())
|
|
ui->payToLayout->setSpacing(4);
|
|
|
|
GUIUtil::setupAddressWidget(ui->payTo, this);
|
|
|
|
// Connect signals
|
|
connect(ui->payAmount, &BitcoinAmountField::valueChanged, this, &SendCoinsEntry::payAmountChanged);
|
|
connect(ui->checkboxSubtractFeeFromAmount, &QCheckBox::toggled, this, &SendCoinsEntry::subtractFeeFromAmountChanged);
|
|
connect(ui->deleteButton, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked);
|
|
connect(ui->useAvailableBalanceButton, &QPushButton::clicked, this, &SendCoinsEntry::useAvailableBalanceClicked);
|
|
}
|
|
|
|
SendCoinsEntry::~SendCoinsEntry()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void SendCoinsEntry::on_pasteButton_clicked()
|
|
{
|
|
// Paste text from clipboard into recipient field
|
|
ui->payTo->setText(QApplication::clipboard()->text());
|
|
}
|
|
|
|
void SendCoinsEntry::on_addressBookButton_clicked()
|
|
{
|
|
if(!model)
|
|
return;
|
|
AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this);
|
|
dlg.setModel(model->getAddressTableModel());
|
|
if(dlg.exec())
|
|
{
|
|
ui->payTo->setText(dlg.getReturnValue());
|
|
ui->payAmount->setFocus();
|
|
}
|
|
}
|
|
|
|
void SendCoinsEntry::on_payTo_textChanged(const QString &address)
|
|
{
|
|
updateLabel(address);
|
|
}
|
|
|
|
void SendCoinsEntry::setModel(WalletModel *_model)
|
|
{
|
|
this->model = _model;
|
|
|
|
if (_model && _model->getOptionsModel())
|
|
connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &SendCoinsEntry::updateDisplayUnit);
|
|
|
|
clear();
|
|
}
|
|
|
|
void SendCoinsEntry::clear()
|
|
{
|
|
// clear UI elements for normal payment
|
|
ui->payTo->clear();
|
|
ui->addAsLabel->clear();
|
|
ui->payAmount->clear();
|
|
if (model && model->getOptionsModel()) {
|
|
ui->checkboxSubtractFeeFromAmount->setChecked(model->getOptionsModel()->getSubFeeFromAmount());
|
|
}
|
|
ui->messageTextLabel->clear();
|
|
ui->messageTextLabel->hide();
|
|
ui->messageLabel->hide();
|
|
|
|
// update the display unit, to not use the default ("BTC")
|
|
updateDisplayUnit();
|
|
}
|
|
|
|
void SendCoinsEntry::checkSubtractFeeFromAmount()
|
|
{
|
|
ui->checkboxSubtractFeeFromAmount->setChecked(true);
|
|
}
|
|
|
|
void SendCoinsEntry::deleteClicked()
|
|
{
|
|
Q_EMIT removeEntry(this);
|
|
}
|
|
|
|
void SendCoinsEntry::useAvailableBalanceClicked()
|
|
{
|
|
Q_EMIT useAvailableBalance(this);
|
|
}
|
|
|
|
bool SendCoinsEntry::validate(interfaces::Node& node)
|
|
{
|
|
if (!model)
|
|
return false;
|
|
|
|
// Check input validity
|
|
bool retval = true;
|
|
|
|
if (!model->validateAddress(ui->payTo->text()))
|
|
{
|
|
ui->payTo->setValid(false);
|
|
retval = false;
|
|
}
|
|
|
|
if (!ui->payAmount->validate())
|
|
{
|
|
retval = false;
|
|
}
|
|
|
|
// Sending a zero amount is invalid
|
|
if (ui->payAmount->value(nullptr) <= 0)
|
|
{
|
|
ui->payAmount->setValid(false);
|
|
retval = false;
|
|
}
|
|
|
|
// Reject dust outputs:
|
|
if (retval && GUIUtil::isDust(node, ui->payTo->text(), ui->payAmount->value())) {
|
|
ui->payAmount->setValid(false);
|
|
retval = false;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
SendCoinsRecipient SendCoinsEntry::getValue()
|
|
{
|
|
recipient.address = ui->payTo->text();
|
|
recipient.label = ui->addAsLabel->text();
|
|
recipient.amount = ui->payAmount->value();
|
|
recipient.message = ui->messageTextLabel->text();
|
|
recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked);
|
|
|
|
return recipient;
|
|
}
|
|
|
|
QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
|
|
{
|
|
QWidget::setTabOrder(prev, ui->payTo);
|
|
QWidget::setTabOrder(ui->payTo, ui->addAsLabel);
|
|
QWidget *w = ui->payAmount->setupTabChain(ui->addAsLabel);
|
|
QWidget::setTabOrder(w, ui->checkboxSubtractFeeFromAmount);
|
|
QWidget::setTabOrder(ui->checkboxSubtractFeeFromAmount, ui->addressBookButton);
|
|
QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
|
|
QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
|
|
return ui->deleteButton;
|
|
}
|
|
|
|
void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
|
|
{
|
|
recipient = value;
|
|
{
|
|
// message
|
|
ui->messageTextLabel->setText(recipient.message);
|
|
ui->messageTextLabel->setVisible(!recipient.message.isEmpty());
|
|
ui->messageLabel->setVisible(!recipient.message.isEmpty());
|
|
|
|
ui->addAsLabel->clear();
|
|
ui->payTo->setText(recipient.address); // this may set a label from addressbook
|
|
if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, don't overwrite with an empty label
|
|
ui->addAsLabel->setText(recipient.label);
|
|
ui->payAmount->setValue(recipient.amount);
|
|
}
|
|
}
|
|
|
|
void SendCoinsEntry::setAddress(const QString &address)
|
|
{
|
|
ui->payTo->setText(address);
|
|
ui->payAmount->setFocus();
|
|
}
|
|
|
|
void SendCoinsEntry::setAmount(const CAmount &amount)
|
|
{
|
|
ui->payAmount->setValue(amount);
|
|
}
|
|
|
|
bool SendCoinsEntry::isClear()
|
|
{
|
|
return ui->payTo->text().isEmpty();
|
|
}
|
|
|
|
void SendCoinsEntry::setFocus()
|
|
{
|
|
ui->payTo->setFocus();
|
|
}
|
|
|
|
void SendCoinsEntry::updateDisplayUnit()
|
|
{
|
|
if (model && model->getOptionsModel()) {
|
|
ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
|
|
}
|
|
}
|
|
|
|
void SendCoinsEntry::changeEvent(QEvent* e)
|
|
{
|
|
if (e->type() == QEvent::PaletteChange) {
|
|
ui->addressBookButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/address-book")));
|
|
ui->pasteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/editpaste")));
|
|
ui->deleteButton->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/remove")));
|
|
}
|
|
|
|
QWidget::changeEvent(e);
|
|
}
|
|
|
|
bool SendCoinsEntry::updateLabel(const QString &address)
|
|
{
|
|
if(!model)
|
|
return false;
|
|
|
|
// Fill in label from address book, if address has an associated label
|
|
QString associatedLabel = model->getAddressTableModel()->labelForAddress(address);
|
|
if(!associatedLabel.isEmpty())
|
|
{
|
|
ui->addAsLabel->setText(associatedLabel);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|