aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/addressbookpage.cpp1
-rw-r--r--src/qt/bitcoin.cpp58
-rw-r--r--src/qt/bitcoingui.cpp13
-rw-r--r--src/qt/bitcoingui.h3
-rw-r--r--src/qt/forms/verifymessagedialog.ui149
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/qrcodedialog.cpp1
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/rpcconsole.h3
-rw-r--r--src/qt/sendcoinsdialog.cpp10
-rw-r--r--src/qt/verifymessagedialog.cpp75
-rw-r--r--src/qt/verifymessagedialog.h36
12 files changed, 351 insertions, 9 deletions
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index dfc85c66d6..d314e62b5a 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -324,6 +324,7 @@ void AddressBookPage::on_showQRCode_clicked()
QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();
QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}
#endif
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index cf115c48f1..ab0a37abff 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -129,6 +129,53 @@ static void handleRunawayException(std::exception *e)
exit(1);
}
+/** Help message for Bitcoin-Qt, shown with --help. */
+class HelpMessageBox: public QMessageBox
+{
+public:
+ HelpMessageBox(QWidget *parent = 0);
+
+ void exec();
+private:
+ QString header;
+ QString coreOptions;
+ QString uiOptions;
+};
+#include <QSpacerItem>
+#include <QGridLayout>
+HelpMessageBox::HelpMessageBox(QWidget *parent):
+ QMessageBox(parent)
+{
+ header = tr("Bitcoin-Qt") + " " + tr("version") + " " +
+ QString::fromStdString(FormatFullVersion()) + "\n\n" +
+ tr("Usage:") + "\n" +
+ " bitcoin-qt [options] " + "\n";
+ coreOptions = QString::fromStdString(HelpMessage());
+ uiOptions = tr("UI options") + ":\n" +
+ " -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
+ " -min " + tr("Start minimized") + "\n" +
+ " -splash " + tr("Show splash screen on startup (default: 1)") + "\n";
+
+ setWindowTitle(tr("Bitcoin-Qt"));
+ setTextFormat(Qt::PlainText);
+ // setMinimumWidth is ignored for QMessageBox so put in nonbreaking spaces to make it wider.
+ QChar em_space(0x2003);
+ setText(header + QString(em_space).repeated(40));
+ setDetailedText(coreOptions + "\n" + uiOptions);
+}
+
+void HelpMessageBox::exec()
+{
+#if defined(WIN32)
+ // On windows, show a message box, as there is no stderr in windowed applications
+ QMessageBox::exec();
+#else
+ // On other operating systems, the expected action is to print the message to the console.
+ QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions;
+ fprintf(stderr, "%s", strUsage.toStdString().c_str());
+#endif
+}
+
#ifdef WIN32
#define strncasecmp strnicmp
#endif
@@ -218,6 +265,15 @@ int main(int argc, char *argv[])
if (translator.load(lang_territory, ":/translations/"))
app.installTranslator(&translator);
+ // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
+ // but before showing splash screen.
+ if (mapArgs.count("-?") || mapArgs.count("--help"))
+ {
+ HelpMessageBox help;
+ help.exec();
+ return 1;
+ }
+
QSplashScreen splash(QPixmap(":/images/splash"), 0);
if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
{
@@ -238,7 +294,7 @@ int main(int argc, char *argv[])
BitcoinGUI window;
guiref = &window;
- if(AppInit2(argc, argv))
+ if(AppInit2())
{
{
// Put this in a block, so that the Model objects are cleaned up before
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index ae9bf2a4b9..6b97d97656 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -9,6 +9,7 @@
#include "addressbookpage.h"
#include "sendcoinsdialog.h"
#include "messagepage.h"
+#include "verifymessagedialog.h"
#include "optionsdialog.h"
#include "aboutdialog.h"
#include "clientmodel.h"
@@ -257,6 +258,8 @@ void BitcoinGUI::createActions()
changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
openRPCConsoleAction = new QAction(tr("&Debug window"), this);
openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console"));
+ verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
+ verifyMessageAction->setToolTip(tr("Verify a message signature"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
@@ -266,6 +269,7 @@ void BitcoinGUI::createActions()
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
+ connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(verifyMessage()));
}
void BitcoinGUI::createMenuBar()
@@ -285,6 +289,7 @@ void BitcoinGUI::createMenuBar()
#ifndef FIRST_CLASS_MESSAGING
file->addAction(messageAction);
#endif
+ file->addAction(verifyMessageAction);
file->addSeparator();
file->addAction(quitAction);
@@ -408,6 +413,7 @@ void BitcoinGUI::createTrayIcon()
trayIconMenu->addAction(openRPCConsoleAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(messageAction);
+ trayIconMenu->addAction(verifyMessageAction);
#ifndef FIRST_CLASS_MESSAGING
trayIconMenu->addSeparator();
#endif
@@ -839,6 +845,13 @@ void BitcoinGUI::changePassphrase()
dlg.exec();
}
+void BitcoinGUI::verifyMessage()
+{
+ VerifyMessageDialog *dlg = new VerifyMessageDialog(walletModel->getAddressTableModel(), this);
+ dlg->setAttribute(Qt::WA_DeleteOnClose);
+ dlg->show();
+}
+
void BitcoinGUI::unlockWallet()
{
if(!walletModel)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index bc3c9a1dfc..88e6d064d7 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -79,6 +79,7 @@ private:
QAction *sendCoinsAction;
QAction *addressBookAction;
QAction *messageAction;
+ QAction *verifyMessageAction;
QAction *aboutAction;
QAction *receiveCoinsAction;
QAction *optionsAction;
@@ -163,6 +164,8 @@ private slots:
void backupWallet();
/** Change encrypted wallet passphrase */
void changePassphrase();
+ /** Verify a message signature */
+ void verifyMessage();
/** Ask for pass phrase to unlock wallet temporarily */
void unlockWallet();
diff --git a/src/qt/forms/verifymessagedialog.ui b/src/qt/forms/verifymessagedialog.ui
new file mode 100644
index 0000000000..6b7f94258b
--- /dev/null
+++ b/src/qt/forms/verifymessagedialog.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VerifyMessageDialog</class>
+ <widget class="QDialog" name="VerifyMessageDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>494</width>
+ <height>342</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Verify Signed Message</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Enter the message and signature below (be careful to correctly copy newlines, spaces, tabs, and other invisible characters), and press apply to obtain the bitcoin address used to sign the message.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="edMessage"/>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lnSig">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="placeholderText">
+ <string>Signature</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lnAddress">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="placeholderText">
+ <string>Address</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblStatus">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="copyToClipboard">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Copy the currently selected address to the system clipboard</string>
+ </property>
+ <property name="text">
+ <string>&amp;Copy Address</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="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>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Close</set>
+ </property>
+ <property name="centerButtons">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>VerifyMessageDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>VerifyMessageDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 23e6576772..22c0bfeebe 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -257,7 +257,7 @@ bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
{
QWidget *widget = static_cast<QWidget*>(obj);
QString tooltip = widget->toolTip();
- if(!Qt::mightBeRichText(tooltip) && tooltip.size() > size_threshold)
+ if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt/>") && !Qt::mightBeRichText(tooltip))
{
// Prefix <qt/> to make sure Qt detects this as rich text
// Escape the current message as HTML and replace \n by <br>
diff --git a/src/qt/qrcodedialog.cpp b/src/qt/qrcodedialog.cpp
index d8e2007a2f..32e5462cee 100644
--- a/src/qt/qrcodedialog.cpp
+++ b/src/qt/qrcodedialog.cpp
@@ -15,7 +15,6 @@ QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enabl
{
ui->setupUi(this);
setWindowTitle(QString("%1").arg(address));
- setAttribute(Qt::WA_DeleteOnClose);
ui->chkReqPayment->setVisible(enableReq);
ui->lnReqAmount->setVisible(enableReq);
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 33b09952b7..51051f72f0 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -11,6 +11,7 @@
#include <QTextEdit>
#include <QKeyEvent>
#include <QUrl>
+#include <QScrollBar>
#include <boost/tokenizer.hpp>
@@ -262,6 +263,8 @@ void RPCConsole::on_lineEdit_returnPressed()
history.removeFirst();
// Set pointer to end of history
historyPtr = history.size();
+ // Scroll console view to end
+ scrollToEnd();
}
}
@@ -315,3 +318,9 @@ void RPCConsole::on_openDebugLogfileButton_clicked()
{
GUIUtil::openDebugLogfile();
}
+
+void RPCConsole::scrollToEnd()
+{
+ QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar();
+ scrollbar->setValue(scrollbar->maximum());
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 9c4fab497e..0a7b10f4a2 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -44,7 +44,8 @@ public slots:
void setNumBlocks(int count);
/** Go forward or back in history */
void browseHistory(int offset);
-
+ /** Scroll console view to end */
+ void scrollToEnd();
signals:
// For RPC command executor
void stopExecutor();
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index b4029aa0d2..f6a3047a2b 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -130,28 +130,28 @@ void SendCoinsDialog::on_sendButton_clicked()
break;
case WalletModel::AmountExceedsBalance:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Amount exceeds your balance"),
+ tr("The amount exceeds your balance."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::AmountWithFeeExceedsBalance:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Total exceeds your balance when the %1 transaction fee is included").
+ tr("The total exceeds your balance when the %1 transaction fee is included.").
arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendstatus.fee)),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::DuplicateAddress:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Duplicate address found, can only send to each address once in one send operation"),
+ tr("Duplicate address found, can only send to each address once per send operation."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::TransactionCreationFailed:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Error: Transaction creation failed "),
+ tr("Error: Transaction creation failed."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::TransactionCommitFailed:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."),
+ tr("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::Aborted: // User aborted, nothing to do
diff --git a/src/qt/verifymessagedialog.cpp b/src/qt/verifymessagedialog.cpp
new file mode 100644
index 0000000000..8842908718
--- /dev/null
+++ b/src/qt/verifymessagedialog.cpp
@@ -0,0 +1,75 @@
+#include "verifymessagedialog.h"
+#include "ui_verifymessagedialog.h"
+
+#include <string>
+#include <vector>
+
+#include <QDialogButtonBox>
+#include <QAbstractButton>
+#include <QClipboard>
+#include <QMessageBox>
+
+#include "main.h"
+#include "wallet.h"
+#include "walletmodel.h"
+#include "addresstablemodel.h"
+#include "guiutil.h"
+
+VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::VerifyMessageDialog),
+ model(addressModel)
+{
+ ui->setupUi(this);
+
+ GUIUtil::setupAddressWidget(ui->lnAddress, this);
+}
+
+VerifyMessageDialog::~VerifyMessageDialog()
+{
+ delete ui;
+}
+
+bool VerifyMessageDialog::checkAddress()
+{
+ CDataStream ss(SER_GETHASH, 0);
+ ss << strMessageMagic;
+ ss << ui->edMessage->document()->toPlainText().toStdString();
+ uint256 hash = Hash(ss.begin(), ss.end());
+
+ bool invalid = true;
+ std::vector<unsigned char> vchSig = DecodeBase64(ui->lnSig->text().toStdString().c_str(), &invalid);
+
+ if(invalid)
+ {
+ QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature could not be decoded. Please check the signature and try again."));
+ return false;
+ }
+
+ CKey key;
+ if(!key.SetCompactSignature(hash, vchSig))
+ {
+ QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature did not match the message digest. Please check the signature and try again."));
+ return false;
+ }
+
+ CBitcoinAddress address(key.GetPubKey());
+ QString qStringAddress = QString::fromStdString(address.ToString());
+ ui->lnAddress->setText(qStringAddress);
+ ui->copyToClipboard->setEnabled(true);
+
+ QString label = model->labelForAddress(qStringAddress);
+ ui->lblStatus->setText(label.isEmpty() ? tr("Address not found in address book.") : tr("Address found in address book: %1").arg(label));
+ return true;
+}
+
+void VerifyMessageDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ if(ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole)
+ checkAddress();
+}
+
+void VerifyMessageDialog::on_copyToClipboard_clicked()
+{
+ QApplication::clipboard()->setText(ui->lnAddress->text());
+}
diff --git a/src/qt/verifymessagedialog.h b/src/qt/verifymessagedialog.h
new file mode 100644
index 0000000000..6a641f7731
--- /dev/null
+++ b/src/qt/verifymessagedialog.h
@@ -0,0 +1,36 @@
+#ifndef VERIFYMESSAGEDIALOG_H
+#define VERIFYMESSAGEDIALOG_H
+
+#include <QDialog>
+
+class AddressTableModel;
+
+QT_BEGIN_NAMESPACE
+class QAbstractButton;
+QT_END_NAMESPACE
+
+namespace Ui {
+ class VerifyMessageDialog;
+}
+
+class VerifyMessageDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent = 0);
+ ~VerifyMessageDialog();
+
+private slots:
+ void on_buttonBox_clicked(QAbstractButton *button);
+
+ void on_copyToClipboard_clicked();
+
+private:
+ bool checkAddress();
+
+ Ui::VerifyMessageDialog *ui;
+ AddressTableModel *model;
+};
+
+#endif // VERIFYMESSAGEDIALOG_H