diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 498d6e8063..3f6e2436a6 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -1,272 +1,271 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) -#include "config/bitcoin-config.h" +#include #endif -#include "askpassphrasedialog.h" -#include "ui_askpassphrasedialog.h" +#include +#include -#include "guiconstants.h" -#include "walletmodel.h" - -#include "support/allocators/secure.h" +#include +#include +#include #include #include #include AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) : QDialog(parent), ui(new Ui::AskPassphraseDialog), mode(_mode), model(0), fCapsLock(false) { ui->setupUi(this); ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint()); ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint()); ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint()); ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); // Setup Caps Lock detection. ui->passEdit1->installEventFilter(this); ui->passEdit2->installEventFilter(this); ui->passEdit3->installEventFilter(this); switch (mode) { case Encrypt: // Ask passphrase x2 ui->warningLabel->setText( tr("Enter the new passphrase to the wallet.
Please use a " "passphrase of ten or more random characters, or " "eight or more words.")); ui->passLabel1->hide(); ui->passEdit1->hide(); setWindowTitle(tr("Encrypt wallet")); break; case Unlock: // Ask passphrase ui->warningLabel->setText(tr("This operation needs your wallet " "passphrase to unlock the wallet.")); ui->passLabel2->hide(); ui->passEdit2->hide(); ui->passLabel3->hide(); ui->passEdit3->hide(); setWindowTitle(tr("Unlock wallet")); break; case Decrypt: // Ask passphrase ui->warningLabel->setText(tr("This operation needs your wallet " "passphrase to decrypt the wallet.")); ui->passLabel2->hide(); ui->passEdit2->hide(); ui->passLabel3->hide(); ui->passEdit3->hide(); setWindowTitle(tr("Decrypt wallet")); break; case ChangePass: // Ask old passphrase + new passphrase x2 setWindowTitle(tr("Change passphrase")); ui->warningLabel->setText(tr( "Enter the old passphrase and new passphrase to the wallet.")); break; } textChanged(); connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); } AskPassphraseDialog::~AskPassphraseDialog() { secureClearPassFields(); delete ui; } void AskPassphraseDialog::setModel(WalletModel *_model) { this->model = _model; } void AskPassphraseDialog::accept() { SecureString oldpass, newpass1, newpass2; if (!model) return; oldpass.reserve(MAX_PASSPHRASE_SIZE); newpass1.reserve(MAX_PASSPHRASE_SIZE); newpass2.reserve(MAX_PASSPHRASE_SIZE); // TODO: get rid of this .c_str() by implementing // SecureString::operator=(std::string) // Alternately, find a way to make this input mlock()'d to begin with. oldpass.assign(ui->passEdit1->text().toStdString().c_str()); newpass1.assign(ui->passEdit2->text().toStdString().c_str()); newpass2.assign(ui->passEdit3->text().toStdString().c_str()); secureClearPassFields(); switch (mode) { case Encrypt: { if (newpass1.empty() || newpass2.empty()) { // Cannot encrypt with empty passphrase break; } QMessageBox::StandardButton retval = QMessageBox::question( this, tr("Confirm wallet encryption"), tr("Warning: If you encrypt your wallet and lose your " "passphrase, you will LOSE ALL OF YOUR BITCOINS!") + "

" + tr("Are you sure you wish to encrypt your wallet?"), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if (retval == QMessageBox::Yes) { if (newpass1 == newpass2) { if (model->setWalletEncrypted(true, newpass1)) { QMessageBox::warning( this, tr("Wallet encrypted"), "" + tr("%1 will close now to finish the encryption " "process. " "Remember that encrypting your wallet " "cannot fully protect " "your bitcoins from being stolen by malware " "infecting your computer.") .arg(tr(PACKAGE_NAME)) + "

" + tr("IMPORTANT: Any previous backups you have " "made of your wallet file " "should be replaced with the newly " "generated, encrypted wallet file. " "For security reasons, previous backups of " "the unencrypted wallet file " "will become useless as soon as you start " "using the new, encrypted wallet.") + "
"); QApplication::quit(); } else { QMessageBox::critical( this, tr("Wallet encryption failed"), tr("Wallet encryption failed due to an internal " "error. Your wallet was not encrypted.")); } QDialog::accept(); // Success } else { QMessageBox::critical( this, tr("Wallet encryption failed"), tr("The supplied passphrases do not match.")); } } else { QDialog::reject(); // Cancelled } } break; case Unlock: if (!model->setWalletLocked(false, oldpass)) { QMessageBox::critical(this, tr("Wallet unlock failed"), tr("The passphrase entered for the " "wallet decryption was incorrect.")); } else { QDialog::accept(); // Success } break; case Decrypt: if (!model->setWalletEncrypted(false, oldpass)) { QMessageBox::critical(this, tr("Wallet decryption failed"), tr("The passphrase entered for the " "wallet decryption was incorrect.")); } else { QDialog::accept(); // Success } break; case ChangePass: if (newpass1 == newpass2) { if (model->changePassphrase(oldpass, newpass1)) { QMessageBox::information( this, tr("Wallet encrypted"), tr("Wallet passphrase was successfully changed.")); QDialog::accept(); // Success } else { QMessageBox::critical( this, tr("Wallet encryption failed"), tr("The passphrase entered for the wallet decryption " "was incorrect.")); } } else { QMessageBox::critical( this, tr("Wallet encryption failed"), tr("The supplied passphrases do not match.")); } break; } } void AskPassphraseDialog::textChanged() { // Validate input, set Ok button to enabled when acceptable bool acceptable = false; switch (mode) { case Encrypt: // New passphrase x2 acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); break; case Unlock: // Old passphrase x1 case Decrypt: acceptable = !ui->passEdit1->text().isEmpty(); break; case ChangePass: // Old passphrase x1, new passphrase x2 acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); break; } ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable); } bool AskPassphraseDialog::event(QEvent *event) { // Detect Caps Lock key press. if (event->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(event); if (ke->key() == Qt::Key_CapsLock) { fCapsLock = !fCapsLock; } if (fCapsLock) { ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!")); } else { ui->capsLabel->clear(); } } return QWidget::event(event); } bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event) { /* Detect Caps Lock. * There is no good OS-independent way to check a key state in Qt, but we * can detect Caps Lock by checking for the following condition: * Shift key is down and the result is a lower case character, or * Shift key is not down and the result is an upper case character. */ if (event->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(event); QString str = ke->text(); if (str.length() != 0) { const QChar *psz = str.unicode(); bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0; if ((fShift && *psz >= 'a' && *psz <= 'z') || (!fShift && *psz >= 'A' && *psz <= 'Z')) { fCapsLock = true; ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!")); } else if (psz->isLetter()) { fCapsLock = false; ui->capsLabel->clear(); } } } return QDialog::eventFilter(object, event); } static void SecureClearQLineEdit(QLineEdit *edit) { // Attempt to overwrite text so that they do not linger around in memory edit->setText(QString(" ").repeated(edit->text().size())); edit->clear(); } void AskPassphraseDialog::secureClearPassFields() { SecureClearQLineEdit(ui->passEdit1); SecureClearQLineEdit(ui->passEdit2); SecureClearQLineEdit(ui->passEdit3); } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 516b4d7316..119487dc5a 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -1,112 +1,112 @@ // Copyright (c) 2011-2016 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_COINCONTROLDIALOG_H #define BITCOIN_QT_COINCONTROLDIALOG_H -#include "amount.h" +#include #include #include #include #include #include #include #include #include class PlatformStyle; class WalletModel; class CCoinControl; class CTxMemPool; namespace Ui { class CoinControlDialog; } #define ASYMP_UTF8 "\xE2\x89\x88" class CCoinControlWidgetItem : public QTreeWidgetItem { public: explicit CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} explicit CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} explicit CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} bool operator<(const QTreeWidgetItem &other) const override; }; class CoinControlDialog : public QDialog { Q_OBJECT public: explicit CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent = 0); ~CoinControlDialog(); void setModel(WalletModel *model); // static because also called from sendcoinsdialog static void updateLabels(WalletModel *, QDialog *); static QList payAmounts; static CCoinControl *coinControl(); static bool fSubtractFeeFromAmount; private: Ui::CoinControlDialog *ui; WalletModel *model; int sortColumn; Qt::SortOrder sortOrder; QMenu *contextMenu; QTreeWidgetItem *contextMenuItem; QAction *copyTransactionHashAction; QAction *lockAction; QAction *unlockAction; const PlatformStyle *platformStyle; void sortView(int, Qt::SortOrder); void updateView(); enum { COLUMN_CHECKBOX = 0, COLUMN_AMOUNT, COLUMN_LABEL, COLUMN_ADDRESS, COLUMN_DATE, COLUMN_CONFIRMATIONS, COLUMN_TXHASH, COLUMN_VOUT_INDEX, }; friend class CCoinControlWidgetItem; private Q_SLOTS: void showMenu(const QPoint &); void copyAmount(); void copyLabel(); void copyAddress(); void copyTransactionHash(); void lockCoin(); void unlockCoin(); void clipboardQuantity(); void clipboardAmount(); void clipboardFee(); void clipboardAfterFee(); void clipboardBytes(); void clipboardLowOutput(); void clipboardChange(); void radioTreeMode(bool); void radioListMode(bool); void viewItemChanged(QTreeWidgetItem *, int); void headerSectionClicked(int); void buttonBoxClicked(QAbstractButton *); void buttonSelectAllClicked(); void updateLabelLocked(); }; #endif // BITCOIN_QT_COINCONTROLDIALOG_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 0b21a1fb74..4b01731f36 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -1,128 +1,128 @@ // Copyright (c) 2011-2016 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 "editaddressdialog.h" -#include "ui_editaddressdialog.h" +#include +#include -#include "addresstablemodel.h" -#include "guiutil.h" +#include +#include #include #include EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) : QDialog(parent), ui(new Ui::EditAddressDialog), mapper(0), mode(_mode), model(0) { ui->setupUi(this); GUIUtil::setupAddressWidget(ui->addressEdit, this); switch (mode) { case NewReceivingAddress: setWindowTitle(tr("New receiving address")); ui->addressEdit->setEnabled(false); break; case NewSendingAddress: setWindowTitle(tr("New sending address")); break; case EditReceivingAddress: setWindowTitle(tr("Edit receiving address")); ui->addressEdit->setEnabled(false); break; case EditSendingAddress: setWindowTitle(tr("Edit sending address")); break; } mapper = new QDataWidgetMapper(this); mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); } EditAddressDialog::~EditAddressDialog() { delete ui; } void EditAddressDialog::setModel(AddressTableModel *_model) { this->model = _model; if (!_model) return; mapper->setModel(_model); mapper->addMapping(ui->labelEdit, AddressTableModel::Label); mapper->addMapping(ui->addressEdit, AddressTableModel::Address); } void EditAddressDialog::loadRow(int row) { mapper->setCurrentIndex(row); } bool EditAddressDialog::saveCurrentRow() { if (!model) return false; switch (mode) { case NewReceivingAddress: case NewSendingAddress: address = model->addRow( mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive, ui->labelEdit->text(), ui->addressEdit->text()); break; case EditReceivingAddress: case EditSendingAddress: if (mapper->submit()) { address = ui->addressEdit->text(); } break; } return !address.isEmpty(); } void EditAddressDialog::accept() { if (!model) return; if (!saveCurrentRow()) { switch (model->getEditStatus()) { case AddressTableModel::OK: // Failed with unknown reason. Just reject. break; case AddressTableModel::NO_CHANGES: // No changes were made during edit operation. Just reject. break; case AddressTableModel::INVALID_ADDRESS: QMessageBox::warning(this, windowTitle(), tr("The entered address \"%1\" is not a " "valid Bitcoin address.") .arg(ui->addressEdit->text()), QMessageBox::Ok, QMessageBox::Ok); break; case AddressTableModel::DUPLICATE_ADDRESS: QMessageBox::warning(this, windowTitle(), tr("The entered address \"%1\" is already " "in the address book.") .arg(ui->addressEdit->text()), QMessageBox::Ok, QMessageBox::Ok); break; case AddressTableModel::WALLET_UNLOCK_FAILURE: QMessageBox::critical(this, windowTitle(), tr("Could not unlock wallet."), QMessageBox::Ok, QMessageBox::Ok); break; case AddressTableModel::KEY_GENERATION_FAILURE: QMessageBox::critical(this, windowTitle(), tr("New key generation failed."), QMessageBox::Ok, QMessageBox::Ok); break; } return; } QDialog::accept(); } QString EditAddressDialog::getAddress() const { return address; } void EditAddressDialog::setAddress(const QString &_address) { this->address = _address; ui->addressEdit->setText(_address); } diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index d8962e664e..d94252dde3 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -1,45 +1,45 @@ // Copyright (c) 2011-2014 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 "openuridialog.h" -#include "ui_openuridialog.h" +#include +#include -#include "guiutil.h" -#include "walletmodel.h" +#include +#include #include OpenURIDialog::OpenURIDialog(const Config *configIn, QWidget *parent) : QDialog(parent), ui(new Ui::OpenURIDialog), config(configIn) { ui->setupUi(this); ui->uriEdit->setPlaceholderText(GUIUtil::bitcoinURIScheme(*config) + ":"); } OpenURIDialog::~OpenURIDialog() { delete ui; } QString OpenURIDialog::getURI() { return ui->uriEdit->text(); } void OpenURIDialog::accept() { SendCoinsRecipient rcp; QString uriScheme = GUIUtil::bitcoinURIScheme(*config); if (GUIUtil::parseBitcoinURI(uriScheme, getURI(), &rcp)) { /* Only accept value URIs */ QDialog::accept(); } else { ui->uriEdit->setValid(false); } } void OpenURIDialog::on_selectFileButton_clicked() { QString filename = GUIUtil::getOpenFileName( this, tr("Select payment request file to open"), "", "", nullptr); if (filename.isEmpty()) return; QUrl fileUri = QUrl::fromLocalFile(filename); ui->uriEdit->setText(GUIUtil::bitcoinURIScheme(*config) + ":?r=" + QUrl::toPercentEncoding(fileUri.toString())); } diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 65dbeaaf85..08d46ae3ee 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -1,281 +1,281 @@ // Copyright (c) 2011-2016 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 "receivecoinsdialog.h" -#include "ui_receivecoinsdialog.h" - -#include "addressbookpage.h" -#include "addresstablemodel.h" -#include "bitcoinunits.h" -#include "guiutil.h" -#include "optionsmodel.h" -#include "platformstyle.h" -#include "receiverequestdialog.h" -#include "recentrequeststablemodel.h" -#include "walletmodel.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, const Config *configIn, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), columnResizingFixer(0), model(0), platformStyle(_platformStyle), config(configIn) { ui->setupUi(this); if (!_platformStyle->getImagesOnButtons()) { ui->clearButton->setIcon(QIcon()); ui->receiveButton->setIcon(QIcon()); ui->showRequestButton->setIcon(QIcon()); ui->removeRequestButton->setIcon(QIcon()); } else { ui->clearButton->setIcon( _platformStyle->SingleColorIcon(":/icons/remove")); ui->receiveButton->setIcon( _platformStyle->SingleColorIcon(":/icons/receiving_addresses")); ui->showRequestButton->setIcon( _platformStyle->SingleColorIcon(":/icons/edit")); ui->removeRequestButton->setIcon( _platformStyle->SingleColorIcon(":/icons/remove")); } // 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); // context menu contextMenu = new QMenu(this); contextMenu->addAction(copyURIAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyMessageAction); contextMenu->addAction(copyAmountAction); // context menu signals connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI())); connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage())); connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); } void ReceiveCoinsDialog::setModel(WalletModel *_model) { this->model = _model; if (_model && _model->getOptionsModel()) { _model->getRecentRequestsTableModel()->sort( RecentRequestsTableModel::Date, Qt::DescendingOrder); connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); 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); connect(tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection))); // 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); } } ReceiveCoinsDialog::~ReceiveCoinsDialog() { delete ui; } void ReceiveCoinsDialog::clear() { ui->reqAmount->clear(); ui->reqLabel->setText(""); ui->reqMessage->setText(""); updateDisplayUnit(); } void ReceiveCoinsDialog::reject() { clear(); } void ReceiveCoinsDialog::accept() { clear(); } void ReceiveCoinsDialog::updateDisplayUnit() { if (model && model->getOptionsModel()) { ui->reqAmount->setDisplayUnit( model->getOptionsModel()->getDisplayUnit()); } } void ReceiveCoinsDialog::on_receiveButton_clicked() { if (!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel()) return; QString address; QString label = ui->reqLabel->text(); /* Generate new receiving address */ address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, ""); SendCoinsRecipient info(address, label, ui->reqAmount->value(), ui->reqMessage->text()); ReceiveRequestDialog *dialog = new ReceiveRequestDialog(config, this); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setModel(model); dialog->setInfo(info); dialog->show(); clear(); /* Store request for later reference */ model->getRecentRequestsTableModel()->addNewRequest(info); } void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked( const QModelIndex &index) { const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel(); ReceiveRequestDialog *dialog = new ReceiveRequestDialog(config, this); dialog->setModel(model); dialog->setInfo(submodel->entry(index.row()).recipient); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); } void ReceiveCoinsDialog::recentRequestsView_selectionChanged( const QItemSelection &selected, const QItemSelection &deselected) { // Enable Show/Remove buttons only if anything is selected. bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty(); ui->showRequestButton->setEnabled(enable); ui->removeRequestButton->setEnabled(enable); } void ReceiveCoinsDialog::on_showRequestButton_clicked() { if (!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); for (const QModelIndex &index : selection) { on_recentRequestsView_doubleClicked(index); } } void ReceiveCoinsDialog::on_removeRequestButton_clicked() { if (!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); if (selection.empty()) return; // correct for selection mode ContiguousSelection QModelIndex firstIndex = selection.at(0); 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); } void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Return) { // press return -> submit form if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus()) { event->ignore(); on_receiveButton_clicked(); return; } } this->QDialog::keyPressEvent(event); } QModelIndex ReceiveCoinsDialog::selectedRow() { if (!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) return QModelIndex(); QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); if (selection.empty()) return QModelIndex(); // correct for selection mode ContiguousSelection QModelIndex firstIndex = selection.at(0); return firstIndex; } // copy column of selected row to clipboard void ReceiveCoinsDialog::copyColumnToClipboard(int column) { QModelIndex firstIndex = selectedRow(); if (!firstIndex.isValid()) { return; } GUIUtil::setClipboard( model->getRecentRequestsTableModel() ->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole) .toString()); } // context menu void ReceiveCoinsDialog::showMenu(const QPoint &point) { if (!selectedRow().isValid()) { return; } contextMenu->exec(QCursor::pos()); } // context menu action: copy URI void ReceiveCoinsDialog::copyURI() { QModelIndex sel = selectedRow(); if (!sel.isValid()) { return; } const RecentRequestsTableModel *const submodel = model->getRecentRequestsTableModel(); const QString uri = GUIUtil::formatBitcoinURI( *config, submodel->entry(sel.row()).recipient); GUIUtil::setClipboard(uri); } // context menu action: copy label void ReceiveCoinsDialog::copyLabel() { copyColumnToClipboard(RecentRequestsTableModel::Label); } // context menu action: copy message void ReceiveCoinsDialog::copyMessage() { copyColumnToClipboard(RecentRequestsTableModel::Message); } // context menu action: copy amount void ReceiveCoinsDialog::copyAmount() { copyColumnToClipboard(RecentRequestsTableModel::Amount); } diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 5d89ab18e4..8411c021cf 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -1,84 +1,84 @@ // Copyright (c) 2011-2016 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_RECEIVECOINSDIALOG_H #define BITCOIN_QT_RECEIVECOINSDIALOG_H -#include "guiutil.h" +#include #include #include #include #include #include #include #include class Config; class OptionsModel; class PlatformStyle; class WalletModel; namespace Ui { class ReceiveCoinsDialog; } QT_BEGIN_NAMESPACE class QModelIndex; QT_END_NAMESPACE /** Dialog for requesting payment of bitcoins */ class ReceiveCoinsDialog : public QDialog { Q_OBJECT public: enum ColumnWidths { DATE_COLUMN_WIDTH = 130, LABEL_COLUMN_WIDTH = 120, AMOUNT_MINIMUM_COLUMN_WIDTH = 180, MINIMUM_COLUMN_WIDTH = 130 }; explicit ReceiveCoinsDialog(const PlatformStyle *platformStyle, const Config *configIn, QWidget *parent = 0); ~ReceiveCoinsDialog(); void setModel(WalletModel *model); public Q_SLOTS: void clear(); void reject(); void accept(); protected: virtual void keyPressEvent(QKeyEvent *event); private: Ui::ReceiveCoinsDialog *ui; GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer; WalletModel *model; QMenu *contextMenu; const PlatformStyle *platformStyle; const Config *config; QModelIndex selectedRow(); void copyColumnToClipboard(int column); virtual void resizeEvent(QResizeEvent *event); private Q_SLOTS: void on_receiveButton_clicked(); void on_showRequestButton_clicked(); void on_removeRequestButton_clicked(); void on_recentRequestsView_doubleClicked(const QModelIndex &index); void recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void updateDisplayUnit(); void showMenu(const QPoint &point); void copyURI(); void copyLabel(); void copyMessage(); void copyAmount(); }; #endif // BITCOIN_QT_RECEIVECOINSDIALOG_H diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 41e00db5ae..8e45b444b9 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,204 +1,204 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Copyright (c) 2017 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "receiverequestdialog.h" -#include "ui_receiverequestdialog.h" +#include +#include -#include "bitcoinunits.h" -#include "config.h" -#include "guiconstants.h" -#include "guiutil.h" -#include "optionsmodel.h" -#include "walletmodel.h" +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include #if defined(HAVE_CONFIG_H) -#include "config/bitcoin-config.h" /* for USE_QRCODE */ +#include /* for USE_QRCODE */ #endif #ifdef USE_QRCODE #include #endif QRImageWidget::QRImageWidget(QWidget *parent) : QLabel(parent), contextMenu(0) { contextMenu = new QMenu(this); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); contextMenu->addAction(saveImageAction); QAction *copyImageAction = new QAction(tr("&Copy Image"), this); connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage())); contextMenu->addAction(copyImageAction); } QImage QRImageWidget::exportImage() { if (!pixmap()) return QImage(); return pixmap()->toImage(); } void QRImageWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton && pixmap()) { event->accept(); QMimeData *mimeData = new QMimeData; mimeData->setImageData(exportImage()); QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->exec(); } else { QLabel::mousePressEvent(event); } } void QRImageWidget::saveImage() { if (!pixmap()) return; QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Image (*.png)"), nullptr); if (!fn.isEmpty()) { exportImage().save(fn); } } void QRImageWidget::copyImage() { if (!pixmap()) return; QApplication::clipboard()->setImage(exportImage()); } void QRImageWidget::contextMenuEvent(QContextMenuEvent *event) { if (!pixmap()) return; contextMenu->exec(event->globalPos()); } ReceiveRequestDialog::ReceiveRequestDialog(const Config *configIn, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveRequestDialog), model(0), config(configIn) { ui->setupUi(this); #ifndef USE_QRCODE ui->btnSaveAs->setVisible(false); ui->lblQRCode->setVisible(false); #endif connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage())); } ReceiveRequestDialog::~ReceiveRequestDialog() { delete ui; } void ReceiveRequestDialog::setModel(WalletModel *_model) { this->model = _model; if (_model) connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(update())); // update the display unit if necessary update(); } void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info) { this->info = _info; // Display addresses with currently configured encoding. this->info.address = GUIUtil::convertToConfiguredAddressFormat(*config, this->info.address); update(); } void ReceiveRequestDialog::update() { if (!model) return; QString target = info.label; if (target.isEmpty()) target = info.address; setWindowTitle(tr("Request payment to %1").arg(target)); QString uri = GUIUtil::formatBitcoinURI(*config, info); ui->btnSaveAs->setEnabled(false); QString html; html += ""; html += "" + tr("Payment information") + "
"; html += "" + tr("URI") + ": "; html += "" + GUIUtil::HtmlEscape(uri) + "
"; html += "" + tr("Address") + ": " + GUIUtil::HtmlEscape(info.address) + "
"; if (info.amount != Amount::zero()) html += "" + tr("Amount") + ": " + BitcoinUnits::formatHtmlWithUnit( model->getOptionsModel()->getDisplayUnit(), info.amount) + "
"; if (!info.label.isEmpty()) html += "" + tr("Label") + ": " + GUIUtil::HtmlEscape(info.label) + "
"; if (!info.message.isEmpty()) html += "" + tr("Message") + ": " + GUIUtil::HtmlEscape(info.message) + "
"; if (model->isMultiwallet()) { html += "" + tr("Wallet") + ": " + GUIUtil::HtmlEscape(model->getWalletName()) + "
"; } ui->outUri->setText(html); #ifdef USE_QRCODE int fontSize = config->UseCashAddrEncoding() ? 10 : 12; ui->lblQRCode->setText(""); if (!uri.isEmpty()) { // limit URI length if (uri.length() > MAX_URI_LENGTH) { ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce " "the text for label / message.")); } else { QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1); if (!code) { ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); return; } QImage qrImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); qrImage.fill(0xffffff); uint8_t *p = code->data; for (int y = 0; y < code->width; y++) { for (int x = 0; x < code->width; x++) { qrImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); p++; } } QRcode_free(code); QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE + 20, QImage::Format_RGB32); qrAddrImage.fill(0xffffff); QPainter painter(&qrAddrImage); painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE)); QFont font = GUIUtil::fixedPitchFont(); font.setPixelSize(fontSize); painter.setFont(font); QRect paddedRect = qrAddrImage.rect(); paddedRect.setHeight(QR_IMAGE_SIZE + 12); painter.drawText(paddedRect, Qt::AlignBottom | Qt::AlignCenter, info.address); painter.end(); ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage)); ui->btnSaveAs->setEnabled(true); } } #endif } void ReceiveRequestDialog::on_btnCopyURI_clicked() { GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(*config, info)); } void ReceiveRequestDialog::on_btnCopyAddress_clicked() { GUIUtil::setClipboard(info.address); } diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index e1cc999f50..306a87a73f 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,71 +1,71 @@ // Copyright (c) 2011-2016 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_RECEIVEREQUESTDIALOG_H #define BITCOIN_QT_RECEIVEREQUESTDIALOG_H -#include "walletmodel.h" +#include #include #include #include #include class Config; namespace Ui { class ReceiveRequestDialog; } QT_BEGIN_NAMESPACE class QMenu; QT_END_NAMESPACE /* Label widget for QR code. This image can be dragged, dropped, copied and * saved * to disk. */ class QRImageWidget : public QLabel { Q_OBJECT public: explicit QRImageWidget(QWidget *parent = 0); QImage exportImage(); public Q_SLOTS: void saveImage(); void copyImage(); protected: virtual void mousePressEvent(QMouseEvent *event) override; virtual void contextMenuEvent(QContextMenuEvent *event) override; private: QMenu *contextMenu; }; class ReceiveRequestDialog : public QDialog { Q_OBJECT public: explicit ReceiveRequestDialog(const Config *configIn, QWidget *parent = 0); ~ReceiveRequestDialog(); void setModel(WalletModel *model); void setInfo(const SendCoinsRecipient &info); private Q_SLOTS: void on_btnCopyURI_clicked(); void on_btnCopyAddress_clicked(); void update(); private: Ui::ReceiveRequestDialog *ui; WalletModel *model; SendCoinsRecipient info; const Config *config; }; #endif // BITCOIN_QT_RECEIVEREQUESTDIALOG_H diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 3ed0543acf..bce5a63378 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -1,278 +1,277 @@ // Copyright (c) 2011-2016 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 "signverifymessagedialog.h" -#include "ui_signverifymessagedialog.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include // For strMessageMagic +#include -#include "addressbookpage.h" -#include "guiutil.h" -#include "platformstyle.h" -#include "walletmodel.h" - -#include "dstencode.h" -#include "init.h" -#include "validation.h" // For strMessageMagic -#include "wallet/wallet.h" +#include #include #include -#include - SignVerifyMessageDialog::SignVerifyMessageDialog( const PlatformStyle *_platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::SignVerifyMessageDialog), model(0), platformStyle(_platformStyle) { ui->setupUi(this); ui->addressBookButton_SM->setIcon( platformStyle->SingleColorIcon(":/icons/address-book")); ui->pasteButton_SM->setIcon( platformStyle->SingleColorIcon(":/icons/editpaste")); ui->copySignatureButton_SM->setIcon( platformStyle->SingleColorIcon(":/icons/editcopy")); ui->signMessageButton_SM->setIcon( platformStyle->SingleColorIcon(":/icons/edit")); ui->clearButton_SM->setIcon( platformStyle->SingleColorIcon(":/icons/remove")); ui->addressBookButton_VM->setIcon( platformStyle->SingleColorIcon(":/icons/address-book")); ui->verifyMessageButton_VM->setIcon( platformStyle->SingleColorIcon(":/icons/transaction_0")); ui->clearButton_VM->setIcon( platformStyle->SingleColorIcon(":/icons/remove")); ui->signatureOut_SM->setPlaceholderText( tr("Click \"Sign Message\" to generate signature")); GUIUtil::setupAddressWidget(ui->addressIn_SM, this); GUIUtil::setupAddressWidget(ui->addressIn_VM, this); ui->addressIn_SM->installEventFilter(this); ui->messageIn_SM->installEventFilter(this); ui->signatureOut_SM->installEventFilter(this); ui->addressIn_VM->installEventFilter(this); ui->messageIn_VM->installEventFilter(this); ui->signatureIn_VM->installEventFilter(this); ui->signatureOut_SM->setFont(GUIUtil::fixedPitchFont()); ui->signatureIn_VM->setFont(GUIUtil::fixedPitchFont()); } SignVerifyMessageDialog::~SignVerifyMessageDialog() { delete ui; } void SignVerifyMessageDialog::setModel(WalletModel *_model) { this->model = _model; } void SignVerifyMessageDialog::setAddress_SM(const QString &address) { ui->addressIn_SM->setText(address); ui->messageIn_SM->setFocus(); } void SignVerifyMessageDialog::setAddress_VM(const QString &address) { ui->addressIn_VM->setText(address); ui->messageIn_VM->setFocus(); } void SignVerifyMessageDialog::showTab_SM(bool fShow) { ui->tabWidget->setCurrentIndex(0); if (fShow) this->show(); } void SignVerifyMessageDialog::showTab_VM(bool fShow) { ui->tabWidget->setCurrentIndex(1); if (fShow) this->show(); } void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() { if (model && model->getAddressTableModel()) { AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { setAddress_SM(dlg.getReturnValue()); } } } void SignVerifyMessageDialog::on_pasteButton_SM_clicked() { setAddress_SM(QApplication::clipboard()->text()); } void SignVerifyMessageDialog::on_signMessageButton_SM_clicked() { if (!model) return; /* Clear old signature to ensure users don't get confused on error with an * old signature displayed */ ui->signatureOut_SM->clear(); CTxDestination destination = DecodeDestination( ui->addressIn_SM->text().toStdString(), model->getChainParams()); if (!IsValidDestination(destination)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText( tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } const CKeyID *keyID = boost::get(&destination); if (!keyID) { ui->addressIn_SM->setValid(false); ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText( tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); return; } WalletModel::UnlockContext ctx(model->requestUnlock()); if (!ctx.isValid()) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(tr("Wallet unlock was cancelled.")); return; } CKey key; if (!model->wallet().getPrivKey(*keyID, key)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText( tr("Private key for the entered address is not available.")); return; } CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->messageIn_SM->document()->toPlainText().toStdString(); std::vector vchSig; if (!key.SignCompact(ss.GetHash(), vchSig)) { ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_SM->setText(QString("") + tr("Message signing failed.") + QString("")); return; } ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }"); ui->statusLabel_SM->setText(QString("") + tr("Message signed.") + QString("")); ui->signatureOut_SM->setText( QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size()))); } void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked() { GUIUtil::setClipboard(ui->signatureOut_SM->text()); } void SignVerifyMessageDialog::on_clearButton_SM_clicked() { ui->addressIn_SM->clear(); ui->messageIn_SM->clear(); ui->signatureOut_SM->clear(); ui->statusLabel_SM->clear(); ui->addressIn_SM->setFocus(); } void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() { if (model && model->getAddressTableModel()) { AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { setAddress_VM(dlg.getReturnValue()); } } } void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked() { CTxDestination destination = DecodeDestination( ui->addressIn_VM->text().toStdString(), model->getChainParams()); if (!IsValidDestination(destination)) { ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText( tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again.")); return; } if (!boost::get(&destination)) { ui->addressIn_VM->setValid(false); ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText( tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again.")); return; } bool fInvalid = false; std::vector vchSig = DecodeBase64( ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid); if (fInvalid) { ui->signatureIn_VM->setValid(false); ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText( tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again.")); return; } CHashWriter ss(SER_GETHASH, 0); ss << strMessageMagic; ss << ui->messageIn_VM->document()->toPlainText().toStdString(); CPubKey pubkey; if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) { ui->signatureIn_VM->setValid(false); ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText( tr("The signature did not match the message digest.") + QString(" ") + tr("Please check the signature and try again.")); return; } if (!(CTxDestination(pubkey.GetID()) == destination)) { ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }"); ui->statusLabel_VM->setText(QString("") + tr("Message verification failed.") + QString("")); return; } ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }"); ui->statusLabel_VM->setText(QString("") + tr("Message verified.") + QString("")); } void SignVerifyMessageDialog::on_clearButton_VM_clicked() { ui->addressIn_VM->clear(); ui->signatureIn_VM->clear(); ui->messageIn_VM->clear(); ui->statusLabel_VM->clear(); ui->addressIn_VM->setFocus(); } bool SignVerifyMessageDialog::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::FocusIn) { if (ui->tabWidget->currentIndex() == 0) { /* Clear status message on focus change */ ui->statusLabel_SM->clear(); /* Select generated signature */ if (object == ui->signatureOut_SM) { ui->signatureOut_SM->selectAll(); return true; } } else if (ui->tabWidget->currentIndex() == 1) { /* Clear status message on focus change */ ui->statusLabel_VM->clear(); } } return QDialog::eventFilter(object, event); } diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp index 8187530a95..e410cf5ce7 100644 --- a/src/qt/transactiondescdialog.cpp +++ b/src/qt/transactiondescdialog.cpp @@ -1,26 +1,26 @@ // Copyright (c) 2011-2016 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 "transactiondescdialog.h" -#include "ui_transactiondescdialog.h" +#include +#include -#include "transactiontablemodel.h" +#include #include TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *parent) : QDialog(parent), ui(new Ui::TransactionDescDialog) { ui->setupUi(this); setWindowTitle( tr("Details for %1") .arg(idx.data(TransactionTableModel::TxIDRole).toString())); QString desc = idx.data(TransactionTableModel::LongDescriptionRole).toString(); ui->detailText->setHtml(desc); } TransactionDescDialog::~TransactionDescDialog() { delete ui; } diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 70bfb9f318..82f899e4ff 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -1,211 +1,209 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) -#include "config/bitcoin-config.h" +#include #endif -#include "utilitydialog.h" +#include -#include "ui_helpmessagedialog.h" - -#include "bitcoingui.h" -#include "clientmodel.h" -#include "guiconstants.h" -#include "guiutil.h" -#include "intro.h" -#include "paymentrequestplus.h" - -#include "clientversion.h" -#include "init.h" -#include "interfaces/node.h" -#include "util.h" - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include +#include + /** "Help message" or "About" dialog box */ HelpMessageDialog::HelpMessageDialog(interfaces::Node &node, QWidget *parent, bool about) : QDialog(parent), ui(new Ui::HelpMessageDialog) { ui->setupUi(this); QString version = tr(PACKAGE_NAME) + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion()); /** * On x86 add a bit specifier to the version so that users can distinguish * between 32 and 64 bit builds. On other architectures, 32/64 bit may be more * ambiguous. */ #if defined(__x86_64__) version += " " + tr("(%1-bit)").arg(64); #elif defined(__i386__) version += " " + tr("(%1-bit)").arg(32); #endif if (about) { setWindowTitle(tr("About %1").arg(tr(PACKAGE_NAME))); /// HTML-format the license message from the core QString licenseInfo = QString::fromStdString(LicenseInfo()); QString licenseInfoHTML = licenseInfo; // Make URLs clickable QRegExp uri("<(.*)>", Qt::CaseSensitive, QRegExp::RegExp2); uri.setMinimal(true); // use non-greedy matching licenseInfoHTML.replace(uri, "\\1"); // Replace newlines with HTML breaks licenseInfoHTML.replace("\n", "
"); ui->aboutMessage->setTextFormat(Qt::RichText); ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); text = version + "\n" + licenseInfo; ui->aboutMessage->setText(version + "

" + licenseInfoHTML); ui->aboutMessage->setWordWrap(true); ui->helpMessage->setVisible(false); } else { setWindowTitle(tr("Command-line options")); QString header = tr("Usage:") + "\n" + " bitcoin-qt [" + tr("command-line options") + "] " + "\n"; QTextCursor cursor(ui->helpMessage->document()); cursor.insertText(version); cursor.insertBlock(); cursor.insertText(header); cursor.insertBlock(); std::string strUsage = node.helpMessage(HelpMessageMode::BITCOIN_QT); const bool showDebug = gArgs.GetBoolArg("-help-debug", false); strUsage += HelpMessageGroup(tr("UI Options:").toStdString()); if (showDebug) { strUsage += HelpMessageOpt( "-allowselfsignedrootcertificates", strprintf("Allow self signed root certificates (default: %d)", DEFAULT_SELFSIGNED_ROOTCERTS)); } strUsage += HelpMessageOpt( "-choosedatadir", strprintf(tr("Choose data directory on startup (default: %d)") .toStdString(), DEFAULT_CHOOSE_DATADIR)); strUsage += HelpMessageOpt( "-lang=", tr("Set language, for example \"de_DE\" (default: system locale)") .toStdString()); strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString()); strUsage += HelpMessageOpt("-rootcertificates=", tr("Set SSL root certificates for payment " "request (default: -system-)") .toStdString()); strUsage += HelpMessageOpt( "-splash", strprintf( tr("Show splash screen on startup (default: %d)").toStdString(), DEFAULT_SPLASHSCREEN)); strUsage += HelpMessageOpt( "-resetguisettings", tr("Reset all settings changed in the GUI").toStdString()); if (showDebug) { strUsage += HelpMessageOpt( "-uiplatform", strprintf("Select platform to customize UI for (one of " "windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM)); } QString coreOptions = QString::fromStdString(strUsage); text = version + "\n" + header + "\n" + coreOptions; QTextTableFormat tf; tf.setBorderStyle(QTextFrameFormat::BorderStyle_None); tf.setCellPadding(2); QVector widths; widths << QTextLength(QTextLength::PercentageLength, 35); widths << QTextLength(QTextLength::PercentageLength, 65); tf.setColumnWidthConstraints(widths); QTextCharFormat bold; bold.setFontWeight(QFont::Bold); for (const QString &line : coreOptions.split("\n")) { if (line.startsWith(" -")) { cursor.currentTable()->appendRows(1); cursor.movePosition(QTextCursor::PreviousCell); cursor.movePosition(QTextCursor::NextRow); cursor.insertText(line.trimmed()); cursor.movePosition(QTextCursor::NextCell); } else if (line.startsWith(" ")) { cursor.insertText(line.trimmed() + ' '); } else if (line.size() > 0) { // Title of a group if (cursor.currentTable()) cursor.currentTable()->appendRows(1); cursor.movePosition(QTextCursor::Down); cursor.insertText(line.trimmed(), bold); cursor.insertTable(1, 2, tf); } } ui->helpMessage->moveCursor(QTextCursor::Start); ui->scrollArea->setVisible(false); ui->aboutLogo->setVisible(false); } } HelpMessageDialog::~HelpMessageDialog() { delete ui; } void HelpMessageDialog::printToConsole() { // On other operating systems, the expected action is to print the message // to the console. fprintf(stdout, "%s\n", qPrintable(text)); } void HelpMessageDialog::showOrPrint() { #if defined(WIN32) // On Windows, show a message box, as there is no stderr/stdout in windowed // applications exec(); #else // On other operating systems, print help text to console printToConsole(); #endif } void HelpMessageDialog::on_okButton_accepted() { close(); } /** "Shutdown" window */ ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(new QLabel( tr("%1 is shutting down...").arg(tr(PACKAGE_NAME)) + "

" + tr("Do not shut down the computer until this window disappears."))); setLayout(layout); } QWidget *ShutdownWindow::showShutdownWindow(BitcoinGUI *window) { if (!window) return nullptr; // Show a simple window indicating shutdown status QWidget *shutdownWindow = new ShutdownWindow(); shutdownWindow->setWindowTitle(window->windowTitle()); // Center shutdown window at where main window was const QPoint global = window->mapToGlobal(window->rect().center()); shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2); shutdownWindow->show(); return shutdownWindow; } void ShutdownWindow::closeEvent(QCloseEvent *event) { event->ignore(); }