sending support
authorWladimir J. van der Laan <laanwj@gmail.com>
Mon, 30 May 2011 18:20:12 +0000 (20:20 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Mon, 30 May 2011 18:20:12 +0000 (20:20 +0200)
gui/include/bitcoingui.h
gui/include/clientmodel.h
gui/include/sendcoinsdialog.h
gui/src/bitcoingui.cpp
gui/src/clientmodel.cpp
gui/src/sendcoinsdialog.cpp

index 80c24a3..955d7b4 100644 (file)
@@ -67,6 +67,7 @@ private slots:
 
     void newAddressClicked();
     void copyClipboardClicked();
+    void error(const QString &title, const QString &message);
 };
 
 #endif
index a5613e3..828c80f 100644 (file)
@@ -9,18 +9,35 @@ class ClientModel : public QObject
 public:
     explicit ClientModel(QObject *parent = 0);
 
+    enum StatusCode
+    {
+        OK,
+        InvalidAmount,
+        InvalidAddress,
+        AmountExceedsBalance,
+        AmountWithFeeExceedsBalance,
+        Aborted,
+        MiscError
+    };
+
     qint64 getBalance();
     QString getAddress();
     int getNumConnections();
     int getNumBlocks();
     int getNumTransactions();
 
+    qint64 getTransactionFee();
+
+    StatusCode sendCoins(const QString &payTo, qint64 payAmount);
+
 signals:
     void balanceChanged(qint64 balance);
     void addressChanged(const QString &address);
     void numConnectionsChanged(int count);
     void numBlocksChanged(int count);
     void numTransactionsChanged(int count);
+    /* Asynchronous error notification */
+    void error(const QString &title, const QString &message);
 
 public slots:
 
index 95dd34b..f73c38d 100644 (file)
@@ -6,6 +6,7 @@
 namespace Ui {
     class SendCoinsDialog;
 }
+class ClientModel;
 
 class SendCoinsDialog : public QDialog
 {
@@ -15,8 +16,11 @@ public:
     explicit SendCoinsDialog(QWidget *parent = 0, const QString &address = "");
     ~SendCoinsDialog();
 
+    void setModel(ClientModel *model);
+
 private:
     Ui::SendCoinsDialog *ui;
+    ClientModel *model;
 
 private slots:
     void on_buttonBox_rejected();
index b409744..66a3edd 100644 (file)
@@ -31,6 +31,7 @@
 #include <QLocale>
 #include <QSortFilterProxyModel>
 #include <QClipboard>
+#include <QMessageBox>
 
 #include <QDebug>
 
@@ -160,6 +161,9 @@ void BitcoinGUI::setModel(ClientModel *model)
 
     setAddress(model->getAddress());
     connect(model, SIGNAL(addressChanged(QString)), this, SLOT(setAddress(QString)));
+
+    /* Report errors from network/worker thread */
+    connect(model, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
 }
 
 void BitcoinGUI::createTrayIcon()
@@ -226,6 +230,7 @@ QWidget *BitcoinGUI::createTabs()
 void BitcoinGUI::sendcoinsClicked()
 {
     SendCoinsDialog dlg;
+    dlg.setModel(model);
     dlg.exec();
 }
 
@@ -296,3 +301,11 @@ void BitcoinGUI::setNumTransactions(int count)
 {
     labelTransactions->setText(QLocale::system().toString(count)+" "+tr("transaction(s)", "", count));
 }
+
+void BitcoinGUI::error(const QString &title, const QString &message)
+{
+    /* Report errors from network/worker thread */
+    QMessageBox::critical(this, title,
+        message,
+        QMessageBox::Ok, QMessageBox::Ok);
+}
index e355676..be8b0b4 100644 (file)
@@ -51,6 +51,11 @@ int ClientModel::getNumTransactions()
     return numTransactions;
 }
 
+qint64 ClientModel::getTransactionFee()
+{
+    return nTransactionFee;
+}
+
 void ClientModel::update()
 {
     emit balanceChanged(getBalance());
@@ -59,3 +64,51 @@ void ClientModel::update()
     emit numBlocksChanged(getNumBlocks());
     emit numTransactionsChanged(getNumTransactions());
 }
+
+ClientModel::StatusCode ClientModel::sendCoins(const QString &payTo, qint64 payAmount)
+{
+    uint160 hash160 = 0;
+    bool valid = false;
+
+    if(!AddressToHash160(payTo.toUtf8().constData(), hash160))
+    {
+        return InvalidAddress;
+    }
+
+    if(payAmount <= 0)
+    {
+        return InvalidAmount;
+    }
+
+    if(payAmount > getBalance())
+    {
+        return AmountExceedsBalance;
+    }
+
+    if((payAmount + nTransactionFee) > getBalance())
+    {
+        return AmountWithFeeExceedsBalance;
+    }
+
+    CRITICAL_BLOCK(cs_main)
+    {
+        // Send to bitcoin address
+        CWalletTx wtx;
+        CScript scriptPubKey;
+        scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
+
+        std::string strError = SendMoney(scriptPubKey, payAmount, wtx, true);
+        if (strError == "")
+            return OK;
+        else if (strError == "ABORTED")
+            return Aborted;
+        else
+        {
+            emit error(tr("Sending..."), QString::fromStdString(strError));
+            return MiscError;
+        }
+    }
+
+    return OK;
+}
+
index 123b930..398e236 100644 (file)
@@ -1,5 +1,6 @@
 #include "sendcoinsdialog.h"
 #include "ui_sendcoinsdialog.h"
+#include "clientmodel.h"
 
 #include "addressbookdialog.h"
 #include "bitcoinaddressvalidator.h"
@@ -15,7 +16,8 @@
 
 SendCoinsDialog::SendCoinsDialog(QWidget *parent, const QString &address) :
     QDialog(parent),
-    ui(new Ui::SendCoinsDialog)
+    ui(new Ui::SendCoinsDialog),
+    model(0)
 {
     ui->setupUi(this);
 
@@ -35,6 +37,11 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent, const QString &address) :
     }
 }
 
+void SendCoinsDialog::setModel(ClientModel *model)
+{
+    this->model = model;
+}
+
 SendCoinsDialog::~SendCoinsDialog()
 {
     delete ui;
@@ -42,35 +49,50 @@ SendCoinsDialog::~SendCoinsDialog()
 
 void SendCoinsDialog::on_sendButton_clicked()
 {
-    QByteArray payTo = ui->payTo->text().toUtf8();
-    uint160 payToHash = 0;
-    int64 payAmount = 0.0;
-    bool valid = false;
+    bool valid;
+    QString payAmount = ui->payAmount->text();
+    qint64 payAmountParsed;
 
-    if(!AddressToHash160(payTo.constData(), payToHash))
+    valid = ParseMoney(payAmount.toStdString(), payAmountParsed);
+
+    if(!valid)
     {
-        QMessageBox::warning(this, tr("Warning"),
-                                       tr("The recepient address is not valid, please recheck."),
-                                       QMessageBox::Ok,
-                                       QMessageBox::Ok);
-        ui->payTo->setFocus();
+        QMessageBox::warning(this, tr("Send Coins"),
+            tr("The amount to pay must be a valid number."),
+            QMessageBox::Ok, QMessageBox::Ok);
         return;
     }
-    valid = ParseMoney(ui->payAmount->text().toStdString(), payAmount);
 
-    if(!valid || payAmount <= 0)
+    switch(model->sendCoins(ui->payTo->text(), payAmountParsed))
     {
-        QMessageBox::warning(this, tr("Warning"),
-                                       tr("The amount to pay must be a valid number larger than 0."),
-                                       QMessageBox::Ok,
-                                       QMessageBox::Ok);
+    case ClientModel::InvalidAddress:
+        QMessageBox::warning(this, tr("Send Coins"),
+            tr("The recepient address is not valid, please recheck."),
+            QMessageBox::Ok, QMessageBox::Ok);
+        ui->payTo->setFocus();
+        break;
+    case ClientModel::InvalidAmount:
+        QMessageBox::warning(this, tr("Send Coins"),
+            tr("The amount to pay must be larger than 0."),
+            QMessageBox::Ok, QMessageBox::Ok);
         ui->payAmount->setFocus();
-        return;
+        break;
+    case ClientModel::AmountExceedsBalance:
+        QMessageBox::warning(this, tr("Send Coins"),
+            tr("Amount exceeds your balance"),
+            QMessageBox::Ok, QMessageBox::Ok);
+        ui->payAmount->setFocus();
+        break;
+    case ClientModel::AmountWithFeeExceedsBalance:
+        QMessageBox::warning(this, tr("Send Coins"),
+            tr("Total exceeds your balance when the %1 transaction fee is included").
+                arg(QString::fromStdString(FormatMoney(model->getTransactionFee()))),
+            QMessageBox::Ok, QMessageBox::Ok);
+        ui->payAmount->setFocus();
+        break;
     }
-    qDebug() << "Pay " << payAmount;
-
     /* TODO: send command to core, once this succeeds do accept() */
-    accept();
+    //accept();
 }
 
 void SendCoinsDialog::on_pasteButton_clicked()