changeset 1204:6d29a99c38aa draft

Merge branch 'master' of https://github.com/laanwj/bitcoin-qt
author Celil <celil.kj@gmail.com>
date Mon, 18 Jul 2011 15:45:55 -0700
parents 58653a806684 (current diff) 9ba11f138fcc (diff)
children 2090f589f996
files bitcoin-qt.pro src/qt/res/icons/editdelete.png
diffstat 35 files changed, 937 insertions(+), 334 deletions(-) [+]
line wrap: on
line diff
--- a/README.rst
+++ b/README.rst
@@ -3,7 +3,7 @@
 
 **Warning** **Warning** **Warning**
 
-Pre-alpha stuff! I'm using this client myself on the production network, and I haven't noticed any glitches, but remember: always backup your wallet.
+Alpha version! I'm using this client myself on the production network, and I haven't noticed any glitches, but remember: always backup your wallet.
 Testing on the testnet is recommended.
 
 This has been implemented:
@@ -28,6 +28,8 @@
 
 - Progress bar on initial block download
 
+- Sendmany support in UI (send to multiple recipients as well)
+
 This has to be done:
 
 - Start at system start
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -84,7 +84,9 @@
     src/qt/overviewpage.h \
     src/qt/csvmodelwriter.h \
     src/qt/qtwin.h \
-    src/crypter.h
+    src/crypter.h \
+    src/qt/sendcoinsentry.h \
+    src/qt/qvalidatedlineedit.h
 SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
     src/qt/transactiontablemodel.cpp \
     src/qt/addresstablemodel.cpp \
@@ -124,7 +126,9 @@
     src/qt/overviewpage.cpp \
     src/qt/csvmodelwriter.cpp \
     src/qt/qtwin.cpp \
-    src/crypter.cpp
+    src/crypter.cpp \
+    src/qt/sendcoinsentry.cpp \
+    src/qt/qvalidatedlineedit.cpp
 
 RESOURCES += \
     src/qt/bitcoin.qrc
@@ -135,7 +139,8 @@
     src/qt/forms/aboutdialog.ui \
     src/qt/forms/editaddressdialog.ui \
     src/qt/forms/transactiondescdialog.ui \
-    src/qt/forms/overviewpage.ui
+    src/qt/forms/overviewpage.ui \
+    src/qt/forms/sendcoinsentry.ui
 
 CODECFORTR = UTF-8
 TRANSLATIONS = src/qt/locale/bitcoin_nl.ts src/qt/locale/bitcoin_de.ts
--- a/doc/assets-attribution.txt
+++ b/doc/assets-attribution.txt
@@ -14,7 +14,7 @@
 License: Creative Commons Attribution (by)
 Site: http://findicons.com/icon/163938/book_open
 
-Icon: src/qt/res/icons/connect*.png
+Icon: src/qt/res/icons/connect*.png, src/qt/res/icons/synced.png
 Icon Pack: Human-O2
 Designer: schollidesign
 License: GNU/GPL
@@ -29,7 +29,7 @@
 Icon: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png,
       src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png,
       src/qt/res/icons/add.png, src/qt/res/icons/edit.png,
-      src/qt/res/icons/editdelete.png
+      src/qt/res/icons/remove.png (edited)
 Designer: http://www.everaldo.com
 Icon Pack: Crystal SVG
 License: LGPL
@@ -52,9 +52,8 @@
 License: Creative Commons Attribution No Derivatives (by-nd)
 Site: http://findicons.com/icon/175944/home?id=176221#
 
-Icon: src/qt/res/icons/synced.png, 
-      src/qt/res/icons/notsynced.png
-Icon Pack: Gloss: Basic
-Designer: Momenticons
-License: Creative Commons Attribution (by) 
-Site: http://www.momenticons.com/
+Icon:  scripts/img/reload.xcf (modified),src/qt/res/movies/update_spinner.mng
+Icon Pack: Kids
+Designer: Everaldo (Everaldo Coelho)
+License: GNU/GPL 
+Site: http://findicons.com/icon/17102/reload?id=17102
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c3ce165adbad91ba5e4c7013b12f8df92219401d
GIT binary patch
literal 28597
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
Ib^h%C0UOjkZ2$lO
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9a45b1bd1d5de4d3801647de10bb3eb3f0ef7079
GIT binary patch
literal 905
zc$@)=19tq0P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00001b5ch_0Itp)
z=>Px#24YJ`L;%$Q)d1DSt(w*V000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipe`
z4*)R3E!{T&00Rk0L_t(I%cYZBY?E~u#()2>U)PVZcJ1mq)&ZRg44oUNgv0|woF-tV
zi9v6?BOIcMF%cGTR3HI0ieLgp18jhR9E1=LTMXMci3P$s216a-Hkxgn9qD0fJKFW@
zzP}e{OHsJuy?URE=RG~|0}mOddyqw?#9d507B2*<=2Vnb+47Bfkw{7a5n$}U1=MU{
zv*c=;rmko{dHACRvz^7s!FFPS3q(UVX}L7eyuLp6eyN*l{sH7TM~o*9`{bMj3oF*2
zI9T^VBIuLD{TIm$bqK2|OrAMLo*JVwkc`iJTfPAJCRT72=FM5R=K0UfBDDPLt)IM=
z3|=JaZ{bd$E%W7(?tPp02kZWh-VJ&R^cj^NVJmer|Hlg)0nz|0d+G7oo~Bju`k|-g
ztpn4Iz%h>ue(#d*DSQXm03LHAfU-~5h|@-cB2mQBi3z%TqWT+)l+|`~7>5=YPA!Br
zXGE@jRaAPr<X=4ju14bkgip2cLoy?aYMv3UQ*E>WD8O}Z`)zN5HiX?0Lm?vpvG<Jh
zwOpn->&8}~+FG&6wCyMB4OdaV$kM`8-TSSo8x4v)_n8P*&E-SD2{5(9r2@+i9@=wF
zPmf4LPssCUkA?wHwt`w^dBH~a6jlO7c$9xz+ElTms{B2F$8kB>c}(`TeIt8*+bsQO
zYi0Gbg&#W|LX1C>wrfw_j;`+hLI3SQ6T>nCkRCOZH)|e!_sRS}pGx$fkz*mRFefgd
z-MuW`_K|6Of6@1u0CMv*-6SJ3>$lXdi$r^8U+L&;wOiF#Ds9N~t%2XiM6%|^@=-_8
zqyUd-AtsxX!kL?Kd~t%ES%+Z8&pVg<X1Xo;SO2&%<ZbW!HKnIg&pnZ|aOr%lG=~Ja
z<}}+IGglgY`f)`ee7cqW69sIu92f)9*H3OKIXtT{txi%$(M%}>V^RnSAR61H|CJ5A
zj3GPk>#VX;lRy!Rcdr%ay6Z&RXi{XdLCDsx#PB<>Q4dU~+;$H~Jiw(EU@A}yWPo0m
fgTXt||GV)Yvg<xvW;_hj00000NkvXXu0mjfG*Ozd
new file mode 100755
--- /dev/null
+++ b/scripts/make_spinner.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# W.J. van der Laan, 2011
+# Make spinning .mng animation from a .png
+# Requires imagemagick 6.7+
+from __future__ import division
+from os import path
+from PIL import Image
+from subprocess import Popen
+
+SRC='img/reload_scaled.png'
+DST='../src/qt/res/movies/update_spinner.mng'
+TMPDIR='/tmp'
+TMPNAME='tmp-%03i.png'
+NUMFRAMES=35
+FRAMERATE=10.0
+CONVERT='convert'
+CLOCKWISE=True
+
+im_src = Image.open(SRC)
+
+if CLOCKWISE:
+    im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT)
+
+def frame_to_filename(frame):
+    return path.join(TMPDIR, TMPNAME % frame)
+
+frame_files = []
+for frame in xrange(NUMFRAMES):
+    rotation = (frame + 0.5) / NUMFRAMES * 360.0
+    if CLOCKWISE:
+        rotation = -rotation
+    im_new = im_src.rotate(rotation, Image.BICUBIC)
+    outfile = frame_to_filename(frame)
+    im_new.save(outfile, 'png')
+    frame_files.append(outfile)
+
+p = Popen([CONVERT, "-delay", str(FRAMERATE), "-dispose", "2"] + frame_files + [DST])
+p.communicate()
+
+
+
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -32,7 +32,7 @@
 map<uint256, CBlockIndex*> mapBlockIndex;
 uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
 CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
-const int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain
+int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain
 const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
 CBlockIndex* pindexGenesisBlock = NULL;
 int nBestHeight = -1;
@@ -1869,6 +1869,10 @@
         pfrom->fSuccessfullyConnected = true;
 
         printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
+        if(pfrom->nStartingHeight > nTotalBlocksEstimate)
+        {
+            nTotalBlocksEstimate = pfrom->nStartingHeight;
+        }
     }
 
 
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -1,5 +1,6 @@
 #include "addresstablemodel.h"
 #include "guiutil.h"
+#include "walletmodel.h"
 
 #include "headers.h"
 
@@ -72,8 +73,8 @@
     }
 };
 
-AddressTableModel::AddressTableModel(CWallet *wallet, QObject *parent) :
-    QAbstractTableModel(parent),wallet(wallet),priv(0)
+AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) :
+    QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0)
 {
     columns << tr("Label") << tr("Address");
     priv = new AddressTablePriv(wallet);
@@ -150,6 +151,8 @@
         return false;
     AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
 
+    editStatus = OK;
+
     if(role == Qt::EditRole)
     {
         switch(index.column())
@@ -160,8 +163,11 @@
             break;
         case Address:
             // Refuse to set invalid address
-            if(!validateAddress(value.toString()))
+            if(!walletModel->validateAddress(value.toString()))
+            {
+                editStatus = INVALID_ADDRESS;
                 return false;
+            }
             // Double-check that we're not overwriting receiving address
             if(rec->type == AddressTableEntry::Sending)
             {
@@ -240,13 +246,22 @@
     std::string strLabel = label.toStdString();
     std::string strAddress = address.toStdString();
 
+    editStatus = OK;
+
+
     if(type == Send)
     {
+        if(!walletModel->validateAddress(address))
+        {
+            editStatus = INVALID_ADDRESS;
+            return QString();
+        }
         // Check for duplicate
         CRITICAL_BLOCK(wallet->cs_mapAddressBook)
         {
             if(wallet->mapAddressBook.count(strAddress))
             {
+                editStatus = DUPLICATE_ADDRESS;
                 return QString();
             }
         }
@@ -291,13 +306,6 @@
 
 }
 
-bool AddressTableModel::validateAddress(const QString &address)
-{
-    uint160 hash160 = 0;
-
-    return AddressToHash160(address.toStdString(), hash160);
-}
-
 /* Look up label for address in address book, if not found return empty string.
  */
 QString AddressTableModel::labelForAddress(const QString &address) const
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -6,12 +6,13 @@
 
 class AddressTablePriv;
 class CWallet;
+class WalletModel;
 
 class AddressTableModel : public QAbstractTableModel
 {
     Q_OBJECT
 public:
-    explicit AddressTableModel(CWallet *wallet, QObject *parent = 0);
+    explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0);
     ~AddressTableModel();
 
     enum ColumnIndex {
@@ -19,9 +20,16 @@
         Address = 1  /* Bitcoin address */
     };
 
-    enum {
+    enum RoleIndex {
         TypeRole = Qt::UserRole
-    } RoleIndex;
+    };
+
+    // Return status of last edit/insert operation
+    enum EditStatus {
+        OK = 0,
+        INVALID_ADDRESS = 1,
+        DUPLICATE_ADDRESS = 2
+    };
 
     static const QString Send; /* Send addres */
     static const QString Receive; /* Receive address */
@@ -45,10 +53,6 @@
      */
     void updateList();
 
-    /* Check address for validity
-     */
-    bool validateAddress(const QString &address);
-
     /* Look up label for address in address book, if not found return empty string.
      */
     QString labelForAddress(const QString &address) const;
@@ -58,10 +62,14 @@
      */
     int lookupAddress(const QString &address) const;
 
+    EditStatus getEditStatus() const { return editStatus; }
+
 private:
+    WalletModel *walletModel;
     CWallet *wallet;
     AddressTablePriv *priv;
     QStringList columns;
+    EditStatus editStatus;
 
 signals:
     void defaultAddressChanged(const QString &address);
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -25,14 +25,16 @@
         <file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file>
         <file alias="toolbar_testnet">res/icons/toolbar_testnet.png</file>
         <file alias="edit">res/icons/edit.png</file>
-        <file alias="editdelete">res/icons/editdelete.png</file>
         <file alias="history">res/icons/history.png</file>
         <file alias="overview">res/icons/overview.png</file>
         <file alias="export">res/icons/export.png</file>
         <file alias="synced">res/icons/synced.png</file>
-        <file alias="notsynced">res/icons/notsynced.png</file>
+        <file alias="remove">res/icons/remove.png</file>
     </qresource>
     <qresource prefix="/images">
         <file alias="about">res/images/about.png</file>
     </qresource>
+    <qresource prefix="/movies">
+        <file alias="update_spinner">res/movies/update_spinner.mng</file>
+    </qresource>
 </RCC>
--- a/src/qt/bitcoinaddressvalidator.cpp
+++ b/src/qt/bitcoinaddressvalidator.cpp
@@ -57,5 +57,11 @@
         }
     }
 
+    // Empty address is "intermediate" input
+    if(input.isEmpty())
+    {
+        state = QValidator::Intermediate;
+    }
+
     return state;
 }
--- a/src/qt/bitcoinamountfield.cpp
+++ b/src/qt/bitcoinamountfield.cpp
@@ -1,4 +1,5 @@
 #include "bitcoinamountfield.h"
+#include "qvalidatedlineedit.h"
 
 #include <QLabel>
 #include <QLineEdit>
@@ -9,12 +10,12 @@
 BitcoinAmountField::BitcoinAmountField(QWidget *parent):
         QWidget(parent), amount(0), decimals(0)
 {
-    amount = new QLineEdit(this);
+    amount = new QValidatedLineEdit(this);
     amount->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this));
     amount->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
     amount->installEventFilter(this);
     amount->setMaximumWidth(100);
-    decimals = new QLineEdit(this);
+    decimals = new QValidatedLineEdit(this);
     decimals->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this));
     decimals->setMaxLength(8);
     decimals->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
@@ -29,8 +30,9 @@
     layout->addStretch(1);
     layout->setContentsMargins(0,0,0,0);
 
+    setLayout(layout);
+
     setFocusPolicy(Qt::TabFocus);
-    setLayout(layout);
     setFocusProxy(amount);
 
     // If one if the widgets changes, the combined content changes as well
@@ -53,10 +55,28 @@
     }
 }
 
+bool BitcoinAmountField::validate()
+{
+    bool valid = true;
+    if(amount->text().isEmpty())
+    {
+        amount->setValid(false);
+        valid = false;
+    }
+    if(decimals->text().isEmpty())
+    {
+        decimals->setValid(false);
+        valid = false;
+    }
+    return valid;
+}
+
 QString BitcoinAmountField::text() const
 {
     if(amount->text().isEmpty() || decimals->text().isEmpty())
+    {
         return QString();
+    }
     return amount->text() + QString(".") + decimals->text();
 }
 
@@ -75,3 +95,10 @@
     }
     return false;
 }
+
+QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
+{
+    QWidget::setTabOrder(prev, amount);
+    QWidget::setTabOrder(amount, decimals);
+    return decimals;
+}
--- a/src/qt/bitcoinamountfield.h
+++ b/src/qt/bitcoinamountfield.h
@@ -4,7 +4,7 @@
 #include <QWidget>
 
 QT_BEGIN_NAMESPACE
-class QLineEdit;
+class QValidatedLineEdit;
 QT_END_NAMESPACE
 
 // Coin amount entry widget with separate parts for whole
@@ -18,6 +18,10 @@
 
     void setText(const QString &text);
     QString text() const;
+    bool validate();
+    // Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907)
+    // Hence we have to set it up manually
+    QWidget *setupTabChain(QWidget *prev);
 
 signals:
     void textChanged();
@@ -27,8 +31,8 @@
     bool eventFilter(QObject *object, QEvent *event);
 
 private:
-    QLineEdit *amount;
-    QLineEdit *decimals;
+    QValidatedLineEdit *amount;
+    QValidatedLineEdit *decimals;
 };
 
 
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -36,6 +36,7 @@
 #include <QProgressBar>
 #include <QStackedWidget>
 #include <QDateTime>
+#include <QMovie>
 
 #include <QDebug>
 
@@ -55,10 +56,14 @@
 
     // Menus
     QMenu *file = menuBar()->addMenu("&File");
-    file->addAction(optionsAction);
+    file->addAction(sendCoinsAction);
+    file->addAction(receiveCoinsAction);
     file->addSeparator();
     file->addAction(quitAction);
     
+    QMenu *settings = menuBar()->addMenu("&Settings");
+    settings->addAction(optionsAction);
+
     QMenu *help = menuBar()->addMenu("&Help");
     help->addAction(aboutAction);
     
@@ -103,17 +108,35 @@
     // Create status bar
     statusBar();
 
+    // Status bar "Connections" notification
+    QFrame *frameConnections = new QFrame();
+    frameConnections->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+    frameConnections->setMinimumWidth(150);
+    frameConnections->setMaximumWidth(150);
+    QHBoxLayout *frameConnectionsLayout = new QHBoxLayout(frameConnections);
+    frameConnectionsLayout->setContentsMargins(3,0,3,0);
+    frameConnectionsLayout->setSpacing(3);
+    labelConnectionsIcon = new QLabel();
+    labelConnectionsIcon->setToolTip(tr("Number of connections to other clients"));
+    frameConnectionsLayout->addWidget(labelConnectionsIcon);
     labelConnections = new QLabel();
-    labelConnections->setFrameStyle(QFrame::Panel | QFrame::Sunken);
-    labelConnections->setMinimumWidth(150);
-    labelConnections->setMaximumWidth(150);
     labelConnections->setToolTip(tr("Number of connections to other clients"));
+    frameConnectionsLayout->addWidget(labelConnections);
+    frameConnectionsLayout->addStretch();
 
+    // Status bar "Blocks" notification
+    QFrame *frameBlocks = new QFrame();
+    frameBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+    frameBlocks->setMinimumWidth(150);
+    frameBlocks->setMaximumWidth(150);
+    QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
+    frameBlocksLayout->setContentsMargins(3,0,3,0);
+    frameBlocksLayout->setSpacing(3);
+    labelBlocksIcon = new QLabel();
+    frameBlocksLayout->addWidget(labelBlocksIcon);
     labelBlocks = new QLabel();
-    labelBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken);
-    labelBlocks->setMinimumWidth(150);
-    labelBlocks->setMaximumWidth(150);
-    labelBlocks->setToolTip(tr("Number of blocks in the block chain"));
+    frameBlocksLayout->addWidget(labelBlocks);
+    frameBlocksLayout->addStretch();
 
     // Progress bar for blocks download
     progressBarLabel = new QLabel(tr("Synchronizing with network..."));
@@ -124,11 +147,13 @@
 
     statusBar()->addWidget(progressBarLabel);
     statusBar()->addWidget(progressBar);
-    statusBar()->addPermanentWidget(labelConnections);
-    statusBar()->addPermanentWidget(labelBlocks);
+    statusBar()->addPermanentWidget(frameConnections);
+    statusBar()->addPermanentWidget(frameBlocks);
 
     createTrayIcon();
 
+    syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
+
     gotoOverviewPage();
 }
 
@@ -281,37 +306,39 @@
     case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
     default: icon = ":/icons/connect_4"; break;
     }
-    labelConnections->setTextFormat(Qt::RichText);
-    labelConnections->setText("<img src=\""+icon+"\"> " + tr("%n connection(s)", "", count));
+    labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(16,16));
+    labelConnections->setText(tr("%n connection(s)", "", count));
 }
 
 void BitcoinGUI::setNumBlocks(int count)
 {
     int total = clientModel->getTotalBlocksEstimate();
+    QString tooltip;
+
     if(count < total)
     {
         progressBarLabel->setVisible(true);
         progressBar->setVisible(true);
         progressBar->setMaximum(total);
         progressBar->setValue(count);
+        tooltip = tr("Downloaded %1 of %2 blocks of transaction history.").arg(count).arg(total);
     }
     else
     {
         progressBarLabel->setVisible(false);
         progressBar->setVisible(false);
+        tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count);
     }
 
     QDateTime now = QDateTime::currentDateTime();
     QDateTime lastBlockDate = clientModel->getLastBlockDate();
     int secs = lastBlockDate.secsTo(now);
     QString text;
-    QString icon = ":/icons/notsynced";
 
-    // "Up to date" icon, and outdated icon
-    if(secs < 30*60)
+    // Represent time from last generated block in human readable text
+    if(secs < 60)
     {
-        text = "Up to date";
-        icon = ":/icons/synced";
+        text = tr("%n second(s) ago","",secs);
     }
     else if(secs < 60*60)
     {
@@ -326,9 +353,33 @@
         text = tr("%n day(s) ago","",secs/(60*60*24));
     }
 
-    labelBlocks->setText("<img src=\""+icon+"\"> " + text);
-    labelBlocks->setToolTip(tr("Downloaded %n block(s) of transaction history. Last block was generated %1.", "", count)
-                            .arg(QLocale::system().toString(lastBlockDate)));
+    // In the label we want to be less specific
+    QString labelText = text;
+    bool spinning = true;
+    if(secs < 30*60)
+    {
+        labelText = "Up to date";
+        spinning = false;
+    }
+
+    tooltip += QString("\n");
+    tooltip += tr("Last received block was generated %1.").arg(text);
+
+    if(spinning)
+    {
+        labelBlocksIcon->setMovie(syncIconMovie);
+        syncIconMovie->start();
+    }
+    else
+    {
+        labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(16,16));
+    }
+    labelBlocks->setText(labelText);
+
+    labelBlocksIcon->setToolTip(tooltip);
+    labelBlocks->setToolTip(tooltip);
+    progressBarLabel->setToolTip(tooltip);
+    progressBar->setToolTip(tooltip);
 }
 
 void BitcoinGUI::error(const QString &title, const QString &message)
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -57,6 +57,7 @@
     QLabel *labelConnections;
     QLabel *labelConnectionsIcon;
     QLabel *labelBlocks;
+    QLabel *labelBlocksIcon;
     QLabel *progressBarLabel;
     QProgressBar *progressBar;
 
@@ -74,6 +75,8 @@
     QSystemTrayIcon *trayIcon;
     TransactionView *transactionView;
 
+    QMovie *syncIconMovie;
+
     void createActions();
     QWidget *createTabs();
     void createTrayIcon();
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -10,7 +10,8 @@
 #include <QDateTime>
 
 ClientModel::ClientModel(CWallet *wallet, QObject *parent) :
-    QObject(parent), wallet(wallet), optionsModel(0)
+    QObject(parent), wallet(wallet), optionsModel(0),
+    cachedNumConnections(0), cachedNumBlocks(0)
 {
     // Until signal notifications is built into the bitcoin core,
     //  simply update everything after polling using a timer.
@@ -38,11 +39,16 @@
 
 void ClientModel::update()
 {
-    // Plainly emit all signals for now. To be more efficient this should check
-    //   whether the values actually changed first, although it'd be even better if these
-    //   were events coming in from the bitcoin core.
-    emit numConnectionsChanged(getNumConnections());
-    emit numBlocksChanged(getNumBlocks());
+    int newNumConnections = getNumConnections();
+    int newNumBlocks = getNumBlocks();
+
+    if(cachedNumConnections != newNumConnections)
+        emit numConnectionsChanged(newNumConnections);
+    if(cachedNumBlocks != newNumBlocks)
+        emit numBlocksChanged(newNumBlocks);
+
+    cachedNumConnections = newNumConnections;
+    cachedNumBlocks = newNumBlocks;
 }
 
 bool ClientModel::isTestNet() const
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -42,6 +42,9 @@
 
     OptionsModel *optionsModel;
 
+    int cachedNumConnections;
+    int cachedNumBlocks;
+
 signals:
     void numConnectionsChanged(int count);
     void numBlocksChanged(int count);
--- a/src/qt/editaddressdialog.cpp
+++ b/src/qt/editaddressdialog.cpp
@@ -79,23 +79,22 @@
 
 void EditAddressDialog::accept()
 {
-    if(mode == NewSendingAddress || mode == EditSendingAddress)
+    if(saveCurrentRow().isEmpty())
     {
-        // For sending addresses, check validity
-        // Not needed for receiving addresses, as those are generated
-        if(!model->validateAddress(ui->addressEdit->text()))
+        switch(model->getEditStatus())
         {
+        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::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);
             return;
         }
-    }
-    if(saveCurrentRow().isEmpty())
-    {
-        QMessageBox::warning(this, windowTitle(),
-            tr("The entered address \"%1\" is already in the address book.").arg(ui->addressEdit->text()),
-            QMessageBox::Ok, QMessageBox::Ok);
+
         return;
     }
     QDialog::accept();
--- a/src/qt/forms/addressbookpage.ui
+++ b/src/qt/forms/addressbookpage.ui
@@ -89,7 +89,7 @@
        </property>
        <property name="icon">
         <iconset resource="../bitcoin.qrc">
-         <normaloff>:/icons/editdelete</normaloff>:/icons/editdelete</iconset>
+         <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
        </property>
       </widget>
      </item>
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -15,146 +15,46 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <spacer name="verticalSpacer_2">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeType">
-      <enum>QSizePolicy::Preferred</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>12</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item>
-    <layout class="QGridLayout" name="gridLayout">
-     <property name="spacing">
-      <number>12</number>
+    <widget class="QScrollArea" name="scrollArea">
+     <property name="widgetResizable">
+      <bool>true</bool>
      </property>
-     <item row="5" column="0">
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>A&amp;mount:</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy">
-        <cstring>payAmount</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="label_2">
-       <property name="text">
-        <string>Pay &amp;To:</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy">
-        <cstring>payTo</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="5" column="1">
-      <widget class="BitcoinAmountField" name="payAmount"/>
-     </item>
-     <item row="4" column="1">
-      <layout class="QHBoxLayout" name="horizontalLayout_2">
-       <property name="spacing">
+     <widget class="QWidget" name="scrollAreaWidgetContents">
+      <property name="geometry">
+       <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>666</width>
+        <height>162</height>
+       </rect>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <property name="margin">
         <number>0</number>
        </property>
        <item>
-        <widget class="QLineEdit" name="addAsLabel">
-         <property name="enabled">
-          <bool>true</bool>
-         </property>
-         <property name="toolTip">
-          <string>Enter a label for this address to add it to your address book</string>
+        <layout class="QVBoxLayout" name="entries">
+         <property name="spacing">
+          <number>6</number>
          </property>
-        </widget>
-       </item>
-      </layout>
-     </item>
-     <item row="4" column="0">
-      <widget class="QLabel" name="label_4">
-       <property name="text">
-        <string>&amp;Label:</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-       <property name="buddy">
-        <cstring>addAsLabel</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="1">
-      <layout class="QHBoxLayout" name="horizontalLayout_3">
-       <property name="spacing">
-        <number>0</number>
-       </property>
-       <item>
-        <widget class="QLineEdit" name="payTo">
-         <property name="toolTip">
-          <string>The address to send the payment to  (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
-         </property>
-         <property name="maxLength">
-          <number>34</number>
-         </property>
-        </widget>
+        </layout>
        </item>
        <item>
-        <widget class="QPushButton" name="addressBookButton">
-         <property name="toolTip">
-          <string>Look up adress in address book</string>
-         </property>
-         <property name="text">
-          <string/>
-         </property>
-         <property name="icon">
-          <iconset resource="../bitcoin.qrc">
-           <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
-         </property>
-         <property name="shortcut">
-          <string>Alt+A</string>
-         </property>
-         <property name="autoDefault">
-          <bool>false</bool>
-         </property>
-         <property name="flat">
-          <bool>false</bool>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
          </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="pasteButton">
-         <property name="toolTip">
-          <string>Paste address from system clipboard</string>
-         </property>
-         <property name="text">
-          <string/>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
          </property>
-         <property name="icon">
-          <iconset resource="../bitcoin.qrc">
-           <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
-         </property>
-         <property name="shortcut">
-          <string>Alt+P</string>
-         </property>
-         <property name="autoDefault">
-          <bool>false</bool>
-         </property>
-        </widget>
+        </spacer>
        </item>
       </layout>
-     </item>
-    </layout>
+     </widget>
+    </widget>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
@@ -162,6 +62,17 @@
       <number>12</number>
      </property>
      <item>
+      <widget class="QPushButton" name="addButton">
+       <property name="text">
+        <string>&amp;Add recipient...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="../bitcoin.qrc">
+         <normaloff>:/icons/add</normaloff>:/icons/add</iconset>
+       </property>
+      </widget>
+     </item>
+     <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
@@ -199,37 +110,8 @@
      </item>
     </layout>
    </item>
-   <item>
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
   </layout>
  </widget>
- <customwidgets>
-  <customwidget>
-   <class>BitcoinAmountField</class>
-   <extends>QLineEdit</extends>
-   <header>bitcoinamountfield.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <tabstops>
-  <tabstop>payTo</tabstop>
-  <tabstop>addressBookButton</tabstop>
-  <tabstop>pasteButton</tabstop>
-  <tabstop>addAsLabel</tabstop>
-  <tabstop>payAmount</tabstop>
-  <tabstop>sendButton</tabstop>
- </tabstops>
  <resources>
   <include location="../bitcoin.qrc"/>
  </resources>
new file mode 100644
--- /dev/null
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SendCoinsEntry</class>
+ <widget class="QFrame" name="SendCoinsEntry">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>729</width>
+    <height>136</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <property name="frameShape">
+   <enum>QFrame::StyledPanel</enum>
+  </property>
+  <property name="frameShadow">
+   <enum>QFrame::Sunken</enum>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <property name="spacing">
+    <number>12</number>
+   </property>
+   <item row="5" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>A&amp;mount:</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+     </property>
+     <property name="buddy">
+      <cstring>payAmount</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Pay &amp;To:</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+     </property>
+     <property name="buddy">
+      <cstring>payTo</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="1">
+    <widget class="BitcoinAmountField" name="payAmount"/>
+   </item>
+   <item row="4" column="1">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QValidatedLineEdit" name="addAsLabel">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="toolTip">
+        <string>Enter a label for this address to add it to your address book</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="label_4">
+     <property name="text">
+      <string>&amp;Label:</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+     </property>
+     <property name="buddy">
+      <cstring>addAsLabel</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1">
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QValidatedLineEdit" name="payTo">
+       <property name="toolTip">
+        <string>The address to send the payment to  (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string>
+       </property>
+       <property name="maxLength">
+        <number>34</number>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="addressBookButton">
+       <property name="toolTip">
+        <string>Look up adress in address book</string>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../bitcoin.qrc">
+         <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset>
+       </property>
+       <property name="shortcut">
+        <string>Alt+A</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+       <property name="flat">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pasteButton">
+       <property name="toolTip">
+        <string>Paste address from system clipboard</string>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../bitcoin.qrc">
+         <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset>
+       </property>
+       <property name="shortcut">
+        <string>Alt+P</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="deleteButton">
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../bitcoin.qrc">
+         <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>BitcoinAmountField</class>
+   <extends>QLineEdit</extends>
+   <header>bitcoinamountfield.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>QValidatedLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>qvalidatedlineedit.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
--- a/src/qt/guiconstants.h
+++ b/src/qt/guiconstants.h
@@ -2,7 +2,7 @@
 #define GUICONSTANTS_H
 
 /* milliseconds between model updates */
-static const int MODEL_UPDATE_DELAY = 250;
+static const int MODEL_UPDATE_DELAY = 500;
 
 /* size of cache */
 static const unsigned int WALLET_CACHE_SIZE = 100;
new file mode 100644
--- /dev/null
+++ b/src/qt/qvalidatedlineedit.cpp
@@ -0,0 +1,37 @@
+#include "qvalidatedlineedit.h"
+
+QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) :
+    QLineEdit(parent), valid(true)
+{
+    connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid()));
+}
+
+void QValidatedLineEdit::setValid(bool valid)
+{
+    if(valid == this->valid)
+    {
+        return;
+    }
+
+    if(valid)
+    {
+        setStyleSheet("");
+    }
+    else
+    {
+        setStyleSheet("background:#FF8080");
+    }
+    this->valid = valid;
+}
+
+void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
+{
+    // Clear invalid flag on focus
+    setValid(true);
+    QLineEdit::focusInEvent(evt);
+}
+
+void QValidatedLineEdit::markValid()
+{
+    setValid(true);
+}
new file mode 100644
--- /dev/null
+++ b/src/qt/qvalidatedlineedit.h
@@ -0,0 +1,27 @@
+#ifndef QVALIDATEDLINEEDIT_H
+#define QVALIDATEDLINEEDIT_H
+
+#include <QLineEdit>
+
+// Line edit that can be marked as "invalid". When marked as invalid,
+// it will get a red background until it is focused.
+class QValidatedLineEdit : public QLineEdit
+{
+    Q_OBJECT
+public:
+    explicit QValidatedLineEdit(QWidget *parent = 0);
+
+protected:
+    void focusInEvent(QFocusEvent *evt);
+
+private:
+    bool valid;
+
+public slots:
+    void setValid(bool valid);
+
+private slots:
+    void markValid();
+};
+
+#endif // QVALIDATEDLINEEDIT_H
deleted file mode 100644
index 945d221eeaa3cf0ffabbf288d7da7541adf05ddf..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a44b6d130b5aeeccc3641a6c0b831d83d9c03235
GIT binary patch
literal 1224
zc$@*q1ULJMP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipe_
z3ndRC4ewL{00c-$L_t(o!?l;oZyZGshrjCXnb{p@AHhOFh(km`+z5&kaX{q6Kaf9z
z1Ls7DBNECXaNz{v0A~bek}DyJ0up&3L=r_750Tge<7e#c?kWzmUXQUMHp;d%>fTaM
z*H^#luIUvsW52EXtN;<j1Tk>xa5xGAfdX%y)wLB?-df-Hnqj{ai%$cmkDcbs@iUaJ
zL@|_1B9llYNn|pY=Dud|?hH%stUXx(1WwGJpd%fUB@&IpL?T%tOEW(D)KL!7_6=Zw
znljSS*twF3lRnuPN7Hlw1jw36+C<-0Ad*mW)2mJg0BZoY705fJ-?C-P(*h8(W}?Pj
zdq72r#0Ee!V$(>0f@&t_xWoCRA1je_8Yk?D0|+T^E1;5zTS~|_M7G@Q*r_OxGck`^
z(T`8SmPN*=-~a&fVcC7D>h(T)_SEaIq6*r)Z8jdOVwO-<35WWIY6XDWWRBVPJTn{J
zxpeJEFS?<46cAAq-#8ps-Yl}dD7+cexpS|5@cya8FTQ}PVlkm9VWw!xSk92rq$fp4
z<FV$+SaL>U<j)Hi%c14tUX6g^h<FPGHt=Qyz?+ePFRR|UKnTOZvFFj08^<}LDPmbC
zzqg)=<CH+P=|>5)0a&^AEq`6PiUSY<GXe!jY|=8eAwn?2!5}E?jylE$L=}q})zktQ
zwG>du30+-f;j0U*UBA&p*>co|a4j3soRpBwEXRoDv@7bJs*E9YtU$_aK3HJ!@;5A9
zzk!c&N961QktOc1DG<yI9gSK}6P9ffwWic4q>AN;#mw^UJ1ktj%KF{gI1JyCSN{Wo
zNjh2zBp`2YHaq`cqPCoPwD6F{pKf#i%2h^xJj4MWPauQXjvR+^DN6r<aR#Xk(bNIY
z@0Tuf<mAaF>X?X+)>ytb$MW3Itj^7`^2@KpwYA-!ClRo{A-4K9L=-4m5DJ7W!Ve#R
z!rjlmAapud&aBVRKem8q<82p&dkjRL*osC069qh*i;HY>u(lUO7WT}4+GB5Mvj_ae
zW!0Apkskl6wd<}cfLIE611C-8bCPg?LkJ>>87od!qHs~njJNx<uZY<*Ky#FKMGC+X
z;K5_&yaC+YaN#-NyT_2<Kfg5pz3lf^JbSi}^g(8KeroGbQ-_*vs3}8%JreHSyvxG*
zr6>P6ZeKJ6p<fQ@mwjf68S0{@@)b!F_oi|u%-cEx467l->M;FkK(FXg7d2hqWg|bD
z(v_^$dS#!%7+_cp8B_yi!VKM_W+g387oc<{y`o3I>@%na+e(yu>Y~Pv{B!}jp{6cs
zW{Q~xqy^C{d*qEgU4Txg==$yi<WO;le%T*G3|T8z544^;&}4B0S5WwZ(v?)cL)Uj3
zHOd~t>M(UtPY-|y4u=;{aAEQkzJZx3YUY>c545Bl<nQ^@X9qa%s6y4K;7h8|p$Zk9
mqJwvyTfg06{=LP0ulYCqI3>_6%<2LF0000<MNUMnLSTX?Av50q
index 910fc396eded0241ddb2e19678f1406a815e163f..8e428b6a7033b6ee8b06116f47ba1069461ba232
GIT binary patch
literal 698
zc$@*c0!96aP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iOY`
z6$LxP;VzZ{00KHmL_t(I%hi)jXp#XO#vk9;uXH+{P0gvB8cvqk*!pr5%Z+u2pdjdr
z!JxXtuA^PH(I*7O4j%d<s!K_Oyo?B(w3665M5&9+U2LYdP06pB@2l_Y+sWt?I@bU6
z9R9z<^Z!2&@L!Geyj13%cl$gc&z$SFs}%sqzlG(O<f@DP7ko}*&u*<uYj9{cA7AQ>
zKPP_J8b{;r;Fc>o&DfqZvo^JLTb|CNKo<~*`PGr++%Y~e!ISNGY&~Mt7zP_e>vmlh
zOm$Eb)x|n&nA~6(b`JSBs`S<}n+FLorowmdB;tveYPe3Cj*3saI@Q<O)opFfatR?2
zaFvDoNgn{%Z?sxYIS)KDsdN^WW5CoHJPh5%i`ewyDg_sH4l(|x1eNELOby}`K@v)A
zGAf76H!)_{8_a#?-Wjb_rem1`XokR}pcm1Va5z=MUivIn0D$Cr5nta}9nl+e1W%NO
zPSGUc$TfL?d-r6sOs3&@3`$G^-Zx%+$VOj&EMlNMj!fMm$pui(JIY<#yD6KfA%luA
zh88t;@Wn+5&1FHcCCt1HU@4P&nkZslVHAb$56lOEDvNvRW%)sqQUibhBV0q7TLsI@
zVm=&0ES;N9(>VNj1k}$TA^@Po;Bh!wS!Q!KG+_%A=zyxW6T#OaL=w3NIU0u&!@t7c
zf>fPFP1Hwg?K(?Ol_o)b5y2mPhlOPPR=$Fh?@xgJQ^0t2p?9Oppuj7k5Ig}NwJLBm
gM`1KH_^%i2EBplCVa-Qb`~Uy|07*qoM6N<$f@i}q$p8QV
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..99b1b141350f531553046b7f2c22ae916467e68f
GIT binary patch
literal 27707
zc$}1*V{~TCw(n!xwrzK8+qTV4I@S~0b~=1w8y$D-j%_=+@80|Dd+t4B+&kV~W7L{8
z>cgt_Vg72)|EyY33W`#QaCmSaARq(^(&DOrS(N|k<{<xfgJ-zculviwsY|FTfd69#
zF5v6y3q`8q`L8jov$T%eUsn2`U2@D$@UH=ssEC-{*FRe!ElAKmW=!Rz#Q!w|tNpa`
zkC#ZQiYS1Bfc<L`xK}}kgug7J%>VH*Fi?LziSNElKtRB@WW+_(c_zBmelRSU5PW?a
zwqbj1^4e3^l`{=rbWQ4&nI}oRH|ng7FK}=sr!SURhc)2Rn{x&Xp~c0iHN~*l(Kc3I
zh+8&e+$K@P9QwU&`kY9-Hd?(2ZhhODd3qC=IePIU4*X(apaE}z+~YpM!jSmjUmwxG
z;sGVfX#^x5df>udGA=U_)WpLeGq}4Z(K6I9hEj|=4}MP~5jM<~?D{Ohu)eAMX6l8q
zD~z|RkN^0@QG7*I$55!;_hr|diPEwqN6PV>Gn9#k=S1z&Iadr(^Rvp+4E$k-XH_q_
z5gqUTF|oW}2kPuJ_B|(3Zbih@6QPN3O*mlzu7%B|iV*Eo-M_*6)S*Tw&fU^vbgv6n
zNXc;)HB4$(w>cVP-)mar;-)*HpT*?Fl%qXni~_~y8<u4KFpN;jP1>t$O}!Ce@Tp$n
z<|_nNG+57XXFcnRfV}*x+J*ddGIw+#?z9SV#Gn<Jw(CBWh^iqT?Y*dUGs3JuLzM&Z
zCbF-y^e3L)dLFG()ozqb05TIf1IkT*F-@Fxrs@D07f53wswZ}I^INy~m~kJCsgo4Z
z&mPp<%eyK8f&jIUdGg$qKkB@gXy@7HrUNE*`lCDp#J3#WCOFx&0zQE~6Uv;6<XT16
z2g;Dd5tr*GPNmqk>LzkL32}&&qmm8|T)bz=;zM-ITA7m!quRp0wNNw~bOQ5&3oaDS
znp6D%U05uml%n{~VIQbZ4cff;R)O|Um6wX>D!(n=1w*h;$2ey`{_s=X3bQ@;8klu>
z#^$Ka9KW+EsD4$w+VosXY6iiz;+r=q&a!gxpTmb_cOJ3AiQ5}G!v2GrcsH=vqbUOR
z)2w(kV;qE+wCQ{1*<kdp;3K^Dx>C{a#Q<El?RmW+6#Yavyj=4Nlj?X;d#gQTT(2II
zpr@p<+kLq({C5c1FXfbCh#as@5+*~?m&{q^EPotXQO^Nfs6E-50HJ4SmnvKylW^@n
z|A0Y8LQ%X{)HwLBA?QCS0pCQ&TlxRNG5;?(n$_&2)m2dPd^ddSmZjcQxwYog5GFLf
z+Y7l)nIekIr_4nyREX0zGq6ptu?C30Ncl<O(&?s{G6~MHEQ!W&aB{FVXzCI-wfrIr
zDk$?>)1YlC`s8rV81!S`!nN!HzZR0G(z#ujNeH#HzA=p{`V0yJn^pp)W+G^)n^sKd
zm5x>85|_H1ZYIH_XF!1oBnu#M#R_Jl$I=C+Z`;q~4W(zJzLC2q8U=nBG@}D#ZhTCs
z0rWc=TTAfpifRfgBFaXx3g5a#5VXwN({}IXTI<Fa8qL0i@o*IEaf$@t5{%Z=HU~A4
zJF8?P<&L2mJ1o!m61J^1Y)isaI8w@N`Bfkf`k28#dVb5)p~tS&YGFd3=;Df;kqCn}
z{1TB#6PO4jw1RFY47;2kTqDUNuIzip(YX6#5Jlnau009-hJ~JG#nLtSDH39cUNUBk
z6R!6sWHa+4A>;xAJIk75`F91g*S3+?^UQ;-QWkbq$fCWZo=@o5dk-3FY#MtQo`Uh8
z+qdl<u>QR#+9AdI1e8DOXEFJ<t!4(bmI&uM%5j>o*K*C|UqH#QkTn|rB7W%JxMovp
zY2hg8p*c;w34yrB!$E`=aMNr;B+WLnjI|p)`@7)Zv$7dF)+L9)OcAlvlq>qXLulJU
z%bAf2n&QmTAL}$UOnum<#3lW1^J2kxn7L-;1v!BhA{0r10rD)BS$^W=g6Ks|Ti~s)
zvX{Y_1{N)<M{0tCj+JTj-FWEVrYQz18k2ZTJX-9<+Y<p#361{MAQa-lo@Eq73=Y-3
zR+Ez*>J74BX<R=DAZ;lr?lJnFTfc9YpB;x?l1=OTOH|iQ{^3|vMl%st!~N5RwRv9Y
zeDk3ZBDZFVd>%BhDZv8xkyeSkN^;7RQ{l2J#O>IB{3B17grw2(>w=&5{Rau}2g?Sn
zVrbeP>4HN$JZ$UufJwKr#IDx}Keji<{v+@I0OJ42z|_AODE*6pWEC9$-XB|zalGa8
zHUI^)UCQQ?g}L7gF>|W4suS`_Vdh2F;_AUBKK(;YBu=G|<TrET?s!vZN1MubswaI3
zMUnbx9ja)(ty6MAG_c<Yc&-hnee#aFppC&%Al`|Gs3!QwKn7D$tmdZ>pm1>U0<T_#
zX}WL+)u_UwZIQocS^$Q~hz-{EjXuoRbc#%?GcrUt!2@U^BD<$~O8LSb;%j4{zjv0N
zMbkv-(r3Y{%GJxn1_z(e{chPu$tsHet?Qq8-ibeRg~!mSr>$O2K8<W9Zmx}GM6(Un
zeuzK?y|Je#2Twpzt(=PzBxu>{0JufcsaJV88}H_sO_f3JQn#gC(gf|$)7sbxyb(km
zEz#5%T!?NdG-OK0Z;xwA=o~v_cfw%%uE-uZ8r*%QEdS_AMHZO5sk-~*@!3uAfP+Ku
zY)#($VDvCF2s^M(%Q6=bKc~pew>{H;mXVLjZf~Rb8j=s6Gl+!NyLj!~^j+v@{_uPj
zEM}R$g7q?I<HLjs7&S0k*bk0}{%HGI3~N*6oNr6h#S-fMNw|p(Tv7$}K3<orhq1Lx
zsLIqu*C2{%nyU~BN>0&5ZJ^M$5b1arDk;y;G%Ek}8}LQsI-T-El$=L7MZ6N2IM6OB
zS3R9zdV~06!mSm(Cr73&Y@di0@pc<|wIW8cIW$_R3VWI4YEe}TKKm(7+S1_MAQ_tJ
zV!1~Fsu*x?#@xxs8n&GTaXi*5+;aOoS<p*vJOk|pAFlQ0;2pszpQ8nHqgqlpw-)95
zOI<qigg0^uf<Jb6L<N+Tl+urA&?Z+4OjDj@pOFjHlzQ77(oQjt>Nz31>BqTdl2vO5
zJ2rGDy;Y-|DzTHm5MNngo^$D!V9X9Z8Za|DYpte2<7MZr0Uch-k3cPqN+5dbo%*QQ
zF(C&V-lKu!r)?`E1z5ICui=hU0wOk_!00IP-}U~5e@6g4>3I_jp|1(1j+2EcPEJmd
zc}*<#yWmJm?%Z?_&RJ|?S?92O<u;c2@#=aGgTqpmXgDi-dIQ7y<09BJw#>AQLTL!V
zfxKE*K394o#+=;N#OPD*9ski2KX%~P4;tH>hR+v@Puydw(7p?_Un&%VbewS>)N~oi
z4zFnm90zS+F`#)&+k~V+^CPyVo}zM0#>ipp9*;a*yAi3_EuL~-&sLcP5&>cGp`HRp
z$dSwfqKg~S;JJR>8#9VvsdUMk^9DO?;o;&0#}x!y&Ftqn5_uBDFfS#HGGfY}W%_R2
zq7SlI_&%1j6|pkih|pavk(s<6FMmc*#X#c_y$WW&6XP10tB8$RxU2j~ygHuT{wDq&
z7jKLIz@gxzO%(^V9PR4AEG$N*h}683*Ug$v3xzI>g;2SoxLXoFAm~B!*t*X|5@)Jz
z?_SH>hCAsM7z^xo7UW&)@DfIkG1{`L*UoeRNh0a{!5M0hDz@jxI2o(n2-L#_vaJ0;
zth%Cm3yl--0>OfK7G~=qbyk&|Qd(Fk1ad+;rI$Rxoy)+>=^;t4r^ZzB65<PK)b%5u
zqAYOdWMBf?{4G1#iNV&QBjZ;Pcy4~fz0tR88|`y@o~gRW(*|WyPWj|XA<hW33@n#2
z;b1k%(#Kv4jCdI{H%F@ygnnNDRa|DdxdW%pv56J)xcO8hc|ic7LWe^VLGLL*&4;-@
z7SwBQ2koW%Mcy|N3v;DDK+;ou;}GWDA+XuJya+(=wWfwG7^HOeu7E>11L2qDQA;e`
z5O6|P+;$?L#Pn6s(E${!cg4BL8cPAv5fdx(oZmrGOz?v$%Im9gtg6Rv-pizK0(3L7
ztF;cTx)|DZtWkJwxoeuxrddS_j%h<o>`iyDYvA$nWn8+>7}5-79O9HBW#7src6CB{
zZ18hp;7w9q>%tJAtsG-ADMBQ^cHY2)8L`8z>PtWWE(9C@f*|!D8o>o8z`u8E=Z~}3
zv`fS~Y3>u3C>?EklN!)w{C5ne9c>n`z5O^==S@UwLKf{ob9!{wy;h+H{6)C6-5*@b
zTU9r^jd?<wGW*x}n-9UQt0$kltGintkVg>kHN&QspcR)EwD)vgSPnECz97b@ptGZo
z0t#KI7o;Wim`J6Ub6ZL7wGBwDk(g&U=Tb?~+~*+iDK}TdHyVAL-Mu~gPS`r|4fpZi
z!td$e_^8iq9nwrjk#RIpF$vgE-`$)b-b76|Y}%eELU5GRv!~5ku{{?@rXeAp&5z~V
zAb^<+sTi_YKV6^Q^7DpkN#abte(!5-c5kJ*DbY$BoRa_rCtM*S=C1e7#$~XgY1h5o
zx1bviB!&GTc|Hc<Beo80RU-Bm7CQNZITYjeTOZZm>h{KcyS_8_4CvY`KtrM17b%ML
zi!#1z+ZXH!o3Tv$)y~tovHLy{Zd4$Hi!XukFksA$L*pxLpSHnWrO<S8)73_hLV|{1
zhTB!qQN^k26-w6haWh(|#k~zXf=F&(K&Zfb47D!VoBC8vfm3(L0ef1!F{Fc$jAy_K
zGvMA=<;4`xp^Xk#O@jtpo_lWXiDxFQi`OD@NTE7m7P!#YUikQ!dZMKcE{2!{<NLu2
zW`+C0$xqQT1{A4&x{5cB$cv8bWv)0Dhd1>?qyY(?PiXb9OCi&&Iuwl%Tsk2`nc(T&
z>YZkSbnGE>D!E03lqAa%cbo(pV2$OZtHRxt&7ilvFrj+|TnC!-a3&RDf4<(yJhT4l
zQv?Hs423i7p$0HJ-Y(G`V;fORYdcZ7ltfjY)Fy0~vhT84VT&w0a=|7K6iCkq+FO`y
zfkRJf5nL$9B(#P_jHQf*9Hc^*CXDPQnCPpGn{i9(jpT%8?;+C?RI!c%(nyA8MbGW&
z^Jp1o?26`3y1vDtM}uC1vD2xWL%DFFc}C`)5HMvwFmD<~B;nE}uvf(XT^P3hTNC^<
zA9C92Il28*Xl<{Qcgv~-=!`3?g+kgE$ru(Ae^!XY41qa?ML~&J(8IHhO^^T&e^_Si
zA~L9t-=@*>vQ{9_i%FDTT&#<;7QHXNxcqtgcH}etcAet}@_9$nf=*4UhvHi><*he6
zw}yt)9z>iSULq-MQb4`$J+V!pxBeAvZ{q;zuL|f^B|*)Vjwi44!sw$XAayCu{B0%#
zjUQF*Ug&R`$&m9JOK=HazAjgx<4}3jdV>A*Fwd@L_tMUbX&Mgq;7YElVO40SGdLVu
zZc0##Bs`27ArN)Qm+?!0Xk}wE(361T#xCUB^fx)NAqDl+&9gs_!i^sT$b;=2a$I}Q
zd`S4?^VDq|Lf%qAfuINVaDuo^7>WyFxPrY7LoY8fA%uf%cu%|~W5PiL>0TZcY{uZ}
z_^iCFhf7%5`#4tl{i@%6io-@S@uc3L1(5lhPnpj<Vr3{1mqw0h_srv#p|*F$Ia^v5
zCi!HCsw*$Cw)Z5;jFGXq*X@Djljt6dvgZy=hJ42dr&DwNgScc>Ou}0A#8$@j8~Dra
zcnbnQf8%y@19&_^rt7#-vsWCVGifKY_X?+%cgYTXJP~F}NJtT6on!hIp=7^`2Z^yI
z7qvY*twU#yvO^$=NpwMRCmsTYnk~J#qce?p-#oWe?^S39K*4~B*CAPRb#a&`s;>Kl
zND^1Z<{@+$gXs{D>9^?uk9WzxF081@geys0Z(!F8Qq3{~Xa;8KoPK;SYSKEKd_K=X
z!Gu}m5ics7BB;8hgm=Zhdv>6_6pb{fq+SBfARO71TI0lxGI^}=Gq>}&x2md$z%3X<
z$I4Byo%^6P7ttwZ!~o#h8JrUhCV3%qYr^i|%IJ%R*?~z}*C<ETLV4^G!3Lp1<{B1y
zlaHzN&K{>wNDmtR0o9cR9w=-gk}&a7d>1c}rK0G+rqT*SwDb2xfx@rc=gf`axV8&{
zL#uz6hm-$<2NMjztCp+v;VB2ct8}(IEJHe=xNQ~0iKwORL`8zU!o&a>8)LF+hpsst
z6NPFz=HR_lO1iR@NEv`KYM+yF%GD<6K`bG+$EhSO{EM%5+V}EEU<UrWH+1k|>L+_t
z!i>N#G8r(z$S_f7V-I>epnxc3p{rXY%uNKvNYjWYoadK325cXd2ll?uSkW8jNzdlm
zz&)3TyS>Y;V5jI0tR^#f=q>C-Vv8f`a?ue)17%?*==`HqmOzidE!z~Hhe{|ZN$MV&
zW$0W(Q^e0x<6ro+q-xrXeLc`EINOxQ)J0bCzd5waFDMta2Tj2Afm->F;*wom0?1QC
z_ImKF&C8);EBhf{Gj;ydNpLAt&@LGDUSzxg^}Bns;15cyk;|VDd(TIn_jkxEGb7h+
zAV`{hPo9+2{88V^sIuZr)SpM}M=05wpB_nU7w%B1%vaP-EeU+eB*g*{*+8of33=<^
z=h(oJ4)$u!Y&>EBV5Erm(<E(ysSxG#m>H-}>}9-X%Ni-@n+Ln5M-Y9`035#}E)l%z
zUzK^cBn0*yfSM_#-iduxNEE2$A?07gw#IPMtooGW;Bm^Azzs5KbIT$SArIu^YfR{7
z+LXcz!vfUNGi5dB=HyicQ#^$Oc-ZGG5n(BX;jm~AzbxmkjGT^SdAw^#7JAhctwJ_D
zD5D}i+fhU!PUujhzjl8U_}Jmf!*4xANi|ee8G!@2)eA=9u%5$XaO~%cd^q@34FTW3
z^VySzvM*Ed;jpbD4f6R;%HKL-!O$)`rC+S;KmQUHc>IMHF|ol)Z7~e(g*|rI`)lYR
z@ZFmN!xK|)S6mFobHQ?Zr|lP*uA|5GIOuOP@-T4ZT;~Qs2t9h!UPt7cSQ8zV{1km|
zsTD%voegELuZqGRS@xfd-5(>Xd3BHa<KNKAI6868nZGrf<lezjQ@b62$<AX07BfOy
zTS4)p?WU1&yHyTZ0*&6_L*{V>LPV>N{$nzH{?ZOO{sFy&m%rNwPq_3Fvoe|L<T+Rs
zrpP%OFzD3;(4&H3*b(?(6cF8PCxSJwGEJjw?&45Ybu;!cZA0<MO4PlLPZqi_ND$eN
z^97&1cV6<2x`hJ2T%Pp@jCB}BdZQuq>v@S0qpHny6~qIDFBuxYjWn|)6C#CL(-Hoa
zRyfbjdb{(1WVgqG17Y4ri3YrCqWV-c+OV*{->538$VnzOHC2HKGM!vcxcs)I4=V6r
zXR!#$=ffVUhjgyzgK2IId9L+(22busK)eYQfAH94e@t9qDpy?7RV&sE4Gn~<4^jZ!
zQtcbjRq$vH_C2Krt!3V%uPm&sm6sng(Q-s==7#O3l;uTe=p?}sTK4J+K@0S1Bu6rq
zJr|2aeOMSyB!?_|3ortcC}gto$alfL`9y4&9VW(fnwi62^^OuTlA!g~0;P@G+O*;2
z)+C8E^;1nF<{*zGiT0=}7YjL4$1$uRx>xdJRx_neK`TtbzmsAS?YQ-oN(x>+m~X_u
zHBKo+y3nIWw{^5peUB2ig<KC6VCxdxa+GCH39;~M<bOct=Hc-G+2;Y_DKNLmY5A>&
z&`lakDg!1yObu9S5qRF;oA%@U2{&@%NZG=ng;2MDum?e19}!HBtUcdDbS@7!+$Jpy
zEy@tMT}cN9%<CJLq$f}vwsG-+i64<n({pOF#HAJqG*e=gpIOY>tBIK^=Ib76OM)QS
z0EcYUsE<JmL_d&!e|=>0>{gj_@~DRg=W}T0zv*`_eT!Q?7xjh7Q(T!HI?C=iy(v<!
z806}E;e(1xX{f)_K?|39HYirMsee@Nwis&f2+qaJQ9jMS*R?lG&O=3P<`Evw)Fnj{
zav6jQ+luL&6u3a<j8FiHhZb%$_8mTVo6^E4ZKaoWthgvmaOcW;yq736@7epqWZy%~
z-z2ocdr+4@E<VJ?l%6p7fk?&Zg8`lEv2kgSIfKn&5b*6CBDWLw#)J7<?C+AX`!6zT
z{!36?9=%^)dPz+iv?-2SXxVE<X{SuCE3(s$peZ)H7pc!h`&3%!REKk1sm`0oWv62d
zsIcNwF@87U;yU=WPF5cL_OTJ$w5X}KCDgNZaVIcyboZC4c!Iwc!j3=$bApb%^`Izn
zpa@-OlT3o>Mh}o8!3sJ$vK78SrxN_-oTE&%Ze(i9v_k0xYQ)Fz=0@qO69k%u<$P>_
zD$lrp%JV@+fJ)86NM0^zKwD9*6!Pf~SsbO<WY!4UmSa>xYYdm!vP_nF(a0I7rlIer
z=Bq8oZhV>BsX#SCfV@a~JY)soY2Hs=88)5hkNW!f>)hH}f)lV}9#i}@<<j)PU?3Rb
zD%4BygKF^A1Px(35HyXd{uS~J#+T6k7es-tx}s(uSc}?<7R5-dAMWm`DFb~E@4yc3
zdR-)ByV#^R<in50N{H^9HrgsGG_e94eh^@0{3y7>+Ag{IX<>``#h-7AtakhsK;yd$
zHObADv#6t@mWA1bRW?UA4bTG~gy)XPRtg{q7;PTV`%SaaxG-U&bRx~|8R172KD*-e
zo3nC|&k3q6RdmBrA#8s_gj429&RBMeEYEH8PYnEXxLw>>le`3aEL{C7TA<Mo0Bo`+
zaiwJ!Bv_vmR8QJZqr=4H32C0^!`Yo%j^H7P;M{6k8&}MiS%>4Jkd>g<W+5ZZ6X>cT
zK?imurS&Uu7ztYbTYIBf*y?!N_3?Nx^K(+(jG5R12hZNSHzU%0i(hk7!+kl;X}Jcz
z99dDLGrpoH_0G$)GA7~;Qb(V~x#hNMNRX!5*qp6yh_m}~yJpV}y@XY~Lj^Ne5kOwy
z#O>RYu*aXor;u-p?1hP>oQZ#wg9f2^v}Q(GQz6!GbC1B^4P0fg&baeKN{B-fYWCn^
z+=U47v2)vHAWT|Q%$Fm_;jGqvIJXHB91zXHe?3dV0?Wy{HBm_z<-hHzIMSoH*TjB;
zq#)y^s||qk{aqyP{;jd?q%l-51liy4p89L!H=A`hy$mqPOJJrNs%x5vZKZ7z!ZYCT
zqY^R;>UCDdWYBD2$!KVY-O=yb@pO;lhbE)gnkN_J8Ipg+5G75Y#8rlUtAKx+&UNd(
z%67YafifN|pg~E9AkXCZVoD$QLM(;TRM#yirc`2SVwBDqv-1-|eb1HV2RvVeXd)&)
z)v(+*W7T)_n4d~(iq?cLLOpvce+Na35~8;***+F^sz1lv%<6!eN9Tf!YtBM-K}c4e
zlY^TdqAXiX5KA~`)`zTAyMox6iJ}$n1oyA@+<ukocB%iCPY!3zRh}0QgJxlh9=0e|
zNgcXd<w2!0e+MQ>_{@3GZ)cCb+cuSnUv)ol8O7L$4(@q=-oY+QqT3@NC$KWBXyQWU
zo|IwE8p2pb0_g;9S`5Ah@18uWijds6dGcKF@k*`59lrvZ6M-jh^wY-ACG2JUic(e=
zgQp(7`Z;Exe}avpCUO7S$L>+TSyCt-f!kt|8#}ZF_EYkjww0xuo$)dQ^-RC9&x=+%
z9PS*|WD530&P%f)75P*<b9NPAa>$;_Op%CQXWd_GERfYulzKERarcB8WJ#-;KiB=R
zII;BU*KbQ%JtJ3Ei=z$0-ZAe|8nKFct}vXe(|Ilm7&1d@nganSMQa$n(uK^bQAfW{
zmpm`l2xNCeY+{s2h#0AKoIR84;p~=6#sJnl<8rF75Ey0@R9lc&_O7@6)!1QSUXBYl
zm4_D-m$*P8xCw!ySW(4ZGuv<61{G!o<cH_ePf3djVW`mRIkC97KlC3~)p{Am6cA@u
zgm>%-hf$5TBNb*4y)aza)jn`KzLiK<Ek*`l$kt}4@?Y~0-srn+hRH4EU6Zs$#zXQL
z)D7*hVfl`OwJ+gQ)^Rx^{lbbGLaRLGt}TmPEp-i7sWR|OVS^FOq_M%T)sEYHRM1vy
zy3B3OTV+mT`TDe)6J4X`QrFP-U*k{?VBIlsE^rxDo#Y<y$8JJGa7F$P!$$1CkK??q
z43`%TnhmzvJIe}nXkpXP=rY4ik+EkN7~mKDMAD4QDpjP_?=cXERmt-$%AzZ2Osvgo
zbb>x<hP5@Ppev+b);v1Ae!SBF4@Y^e!kv0D@1}S`@Nwe7f~v?N+QxTa&fpPtzG66b
zPQ8$j&utsF$vs`K?P0!9(HlO6pybLhM6!I(N$L>N`a)|_uiZ+o>fmWjnk~_Qj5Ef`
zn(`1NeA{4^KmBfx;^B0w)Kq!YX{8jbpo$bjF7phv(BnnWz*8NiQBJ{6#7gTUFEC7_
zX_2&ajJFz%bBF^X)aKpP04}p$QK|);XFMvjs6q4jFGyF!eK1_0rkyyc+zvNlK=L@x
zBQho>V|zb8Qu^6Uv4mJUw0Y6OI0dxqYD?dCVYEk79yK|}R0A~R6}ec~&T*t^h8V75
zGKz`~ZJH+CFuunPYRUTOJ_A=6y{hRkK&a|@dHr6C@#Jby9O$-a%D_QK@7A9oOc+p#
zeszo>lTC{vqpE!~eU`cy5@U(Q1`h9#DM{@tn;Qd5vAQiKid|N>($(T1Lu*oPi+ncg
z*%ldAW|6t}@ICsjc8Nv>Hil_WwX=!-S2$NW7(PM>-m1^bcQ?K7z)|Fx{Eag6Eu0Jh
zOad#3Mmsc@00Obu_su~v8{dHeU+R*nZVHra7;{lvAK2Z?%h5M1OJ8<Y(H)og!GjF2
zc#AR_o>OMVzOf@5LR9Y%%E;@moFLQRJ9>S?P)th(jd?1)d@*MEw<?P&e3Qrf-GXAW
zMau&${NxRvHWoo^8@d^5S}?ZupbK2CY1CCV1l7pehIlGPuj_X5igAq3XQZeEXy=6X
zIb=$qM($fkCoBCD4#_Z_8k!SE`75V~oU-q8^L%@IXPMNgs}3JWy-~0w^b4G>1U4J-
z%#Q5}QWDSU%6_%%68IonL*94xnplabw1`jaomD@Pa_#8jiCP<3?^j^n@U`u+!|N>Y
z3;r$=JO4)Ff0t&v+lxE*oc}~g9$B<?O<Mw3MJc-(YE&4<fr|sgwwUx}I))=nOOD@L
zMVXjsJpmof8>>ks8NK2M57NwgdH#mern-UweouZvZvr!oS9d-=Aa?yEnxcAk*Fpp!
zwC>hW_~99H#P-IGeS5A10>emXb(Hn^)kE8oDqmv<cY#h$NQn*IB+Ln{i(+0TcxNE|
zmoM)t-4px)B7;TrU+4`qG%DDGR`zBjJsf@coc8Bc3A+`1@XcEs)}|&{Cgf#H0g5He
zC8qEsT*}V|qysm$^yl=gLwOy0d_yYdC&WZN-+z~rTybE`y7sU69mTN~VJ`+IFZy-4
zi<ZzTw2q=$FvQ){xvQy>A0J#Kn^<+z{%pj7nvq1cxUYZ}6}tN2?~KHWfwXxvNkPc=
zvygVai=%FdnOKg6`^~R2x$5ncl5)(xN5qftyD-U*n_`>^NLQr+bo+giMU8or&M7E<
zY#uG@d1Js3TMSu$WKXTPo;zF?FnfqxBw>P6o61Z~C;l)cE+ds;mW9^%bl4uL-MX?T
zFq#nNz-Hgq;2ZY5nKoS3Zcqp!>^cJ}&<Hgy)9PI#nj(FvF|eRBdZSe|Ci+|GnUzL{
z{WH=QkMZ|vmk+W*wnGrTNjEjYnEWLgx$-bDu~A6FT?7|M*lVzLSO(e9WnnbZ*`O}|
z+=IB@(JWEcAtm=8K1^~mckWv`1-3OAJ1`1y65gU~-jG2n;_JHb9Ub(OfFg{WA?S8@
zB476U)0S#E5;i#fgW~qE-|qv%3uxTPGM-P28ADiLN4B)NElFW(BNxw=Tq@iZ<Jn)F
zk60m|-WKz@3QGnw-_=T^5G=pW-Oves*7y1II{BB;6RRvo{Nx(0W}xl4cG6l3Qy)k}
z6!7c=YV|)eY>8zjrxwKsqIf0`9z3tv1F`xf>#2ovifdzX8Kw|U*$&lOFhc&|1w)J*
zKUlqjhkRh0;}Z-U{)hG1Sk-^kqqbVxqqCWsedKb}!?06wvSKN6QA@&Y44sq2EyyZT
z5Xmq_rqEzxamu_!(3w*UcfwpP@Y1jhWos7HMJXu}8oN^9Tj!r_ga~wfwtw*EJPFMB
zc+Y^>8`R5?JUTC_5fKlO3ML4blC8+#+#Y9xg!9VDQ@+g*g_x>?E|swOGAPLKi+u*b
zkeMeWVZ+A@E+(vGj=r+#LDD}%)VEF=UeFxozhN)!yu&J+(v!3#wypgVQNMAn3<^Q_
zxNKufh)W$laYBFqGsBALgtW(SMPV`%3To1?8HX^!)Y%cQ(SEDdEh5yQv{hk`zL+sm
zyz@b+UyiC@7Fo{-UY15>FwH0Oq<_FxB05O#;KRp6(Dd1zd&7@BwIRSI%vYgdO0^t?
zzY2d5%|Z%VfZSCc?(bLKX*dUAPNpzUZyn+*sv>o1Kk=U(J;w2={H2K@{$v;(bPGf?
zO~a!zfOczxc$Ue~s-MSovf`Ur)pOZ6;Y*(|h7Z%%qMz8j=fVlFWZjqA#%f7Az62RN
z!wg~tRV1@K6_?{N6xgc_j%9S@3X5C2r>Pi5rl1NF&1}Yf_=OHDY(4g1M4)N<x%eCx
z%WPm}ysi`2yMU{R57!4^%E%0SHbJse-82n!5t$sH8q&A$pNpQ1fxl2^y5E8ZhQYG%
zXvi>_aRVYYghdu(DdWE5f>R#e39S>b%8$&<CSu`X;ba#`*T&z6p((Hj_2SVAxr6w3
zk7~nT&j#dX8_#WJ*zre*C2Hp#@XCtlw`K&*kZ+#O{USX#*|9~(?_G9N*|d!n<5ay!
zp~DM6FdA*0ah!%Ga+xT?bg&zB#_cq}jpJ06;x{xY_*lx1%4#p?VSm(aylzKEe)E~1
zWBfd|!shqf4$)74Y0i_bp1#qhVVXSAplj?b+8?DC=n@Dvf$m300kCCFC?fs}8HP+d
z4Cg|C5{oyi`90|_cjtsvfGd_%uax|EdHD112;nQ8tb!r5)jBoR-dd(Ot9{UrsW4&k
zf=4L}SP?6JWiH`hA26{ltsI_A5fxEmy-m%m(++zchs!oDgS50<RSkiZ8`c=Xn9UWe
z5x4t>v@yZk>l+Z^cEu|M0zYE;;k?nlAPE)%D(}mmpb`Z0IVwOwg3V@frpwJ1ED<8y
zj-hB>*Y~#TUG!qK!Rh->(oP9~e<j-=smmwGT+fDN5JJ0v#-lqdNsRm|LNv;zQxO&F
z=O;_j0$!9Bn~Vs?!R_+9#AG)D3O0^Ia?%O;w#_(^5F0AJK016wWU!Ep>5pdgL$fV5
zL8a$#kZ!3@{YwUJui)T$P6`*lFKB)Nt7h7t%n6o^%Ud8_Sk?NWL$0{V+yahGT_raW
z;*a4-o{*6l_T-zNCHO&k^}YaF)a3d#)PY_OIp+f1IN7k8@hFkN*x2SD)2rK3xr|yu
zSXkzWhlfX7=m2r4;13EwYI#9w5g#L!@oHlrxjB)yhZXZrjZcG#3A9zVT=UB$g%rC7
z^!3U>>n^3DIds!rasnux=+(kTa*K=<lv16c=b;9UNld3$gy61rNi;8Skr6cMkI~bJ
z8p=IT&_735rqJAT*~3r)r3AZvOM|3X@B~=S#9j%SRHEEHlrFt!Y=jqS7Me!#H7mze
zzoJ(meZVD#ntBMzfDyu*9->YY(6k;BB*}d)2JKTRg=yTa{i!h@&B^AW%=^Z~i{qNM
zNNXTR_$P-+5T^3y!kvCRIYw&fI~9XO%+*@_xH($0E$>|LaG4rw&ZWk$$&#Vy4_t?^
zwh8xHQ#@-p!Aj%rRyP(1p6cSUv;r?y3`ofvvF%RvvQdK`hR+=Xm<k_9vpnh{;h(DF
zYTUNja1n!|ese)2IiDqvx|+ee{m*;W^6`4yDVaVUA4^k3*uxU5PIGg~Rh4(bwyU2S
z3ZS1%Qff-!SQ8}!EJX2x+c$0SXk~6~X_)tjXgjzBrJPyte;0@Af8${DmxjO)bjmDe
zzsvE7vy7FSF36bJKW52dl+A7_C=C-qr3%85d@1h7LeQ1hjp-+5N|cCZ#}qrTZl`Ed
z&dSo&6#-<JXEA2zn8Z!-$7U9#&IZ9h<z4v^ALYFn1mXsxu3#Z@L|%Ye!c)7FJ<llD
z8i4SpSCVp)!Kj8lhH5f|hq3M?5VgX1enitmBZYh*H|#)ag2rKmV4m4j3l87^5rpd|
zt{q5MqJlHv$@qd!HWTsphSwjFL<7e5p|TH}#gZd!Boscxp#W1vqB92~jszI+0{BD*
zKB)>G!@HMM`QQDbo73{mx6CQr5M_Y+9x`djp7{IE??0jVCs|hv@&Q3~2XQh*fgl-s
z2#pP@1X&D=whTPSt9yHtQH>%=ze#*f%?8oV>*jaP(g?(RuzLf}Bs{F88;Z}h;6-`i
zLz8*x$((qNayomIPN?*`Nqg8tfsJ!1pFKTm9QQ8Ul$z>G0=#<03{fytb70;50S)k3
zWExKEuB`lSzKs{Zz<Be#QdWWfJ#a$nOA?odSOQBd)IcNK1(6zcu*5x$7W!YC?FDbm
z;iR#ae=hTRy-dg5&&%SXV6Mq_uZaLv%>~(TFl>qhw62--Tdj)lHUK-40AGrI`)IK4
zIn1<m1d6iCn}JDj8hj?Q*)8;>GNEGd&`e|z?4`tC=^&=$LC-0D?EKp!IF2)c3|s_{
ze%%tJEeXd5aI>a69I$hZhfVeQ%w{f4p@%iCv^`tGdKg3t3PzBrB@bqCxbvkK<fYTz
zB34h<_U`BEW)rzI9&$looiT2}H@JvzlDI<JM8Q+oA;6Qa@wM+F7X3?@E1EcwD)8bq
z0gbGs%Qkq=hf~_A<%EYu1_S*}>^*iu(IJFkksnYT2NVMEDsIr0?=X6M8n_48==_|Y
zle4imRrlXNZpP1+Z{IG{jLtTiNa?i3c^Rp!U6*3OL=*ca<_CF&h0%rKaS~)pktoDE
zf45`+?!cQ0ab^1K>)`%lKztceO>hEwuK17q@+YQwdG^}~+?ZRBi^!^hoZ~hG?EDff
zicL(Wl{KFv=GB;7F*Rth)}}~6^9~w>RBK936`WMLY<;}xd9Mx0)%*24FW>z2H{blN
zH!yn;gP!k{femwOG#-#(OF0|oq`USY=2EhxUisiTP^8PD56Ll5k+^v7OEnm_Av_!S
zXlrf-(EPAN*n!$py5M0xtT}Puj^>`CJSo&+B7eYYQpwX-#(w<LuRb8<n&<J1=V#X#
zld8tvDN&8o9_$CaUE||R=lm>CHUfF1N8|{@$T$viuiwCk7@xd(l;|dE&wpgRB6RN}
zQ*PZmP{@8^4kKIaGaw|WX&B8ySkK2o8;Gu}silH7rdUg{?=7h>my82gwQxHCf8Un*
z*oF(xQLX_!3P!Lye~M~cRbk$3@i(aGV0>jFp4RjTDrI7CegJ8~VWXT4JhL)y3E7fE
z43&@s2X=a})Xn@ozcW!X)~GbeEGJAHFi`30;`1&oW5z%btfhBsZ!=FvSguf^fs=b4
z^^6X(j~me`Xwr~1h`lq``8q<*EFwg%$YIMi-Ahmp`(3kb%0DxVjr~b7EXFWOu4j%5
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
KH!aP>>VE-e@O{Vt
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -1,43 +1,40 @@
 #include "sendcoinsdialog.h"
 #include "ui_sendcoinsdialog.h"
 #include "walletmodel.h"
-#include "addresstablemodel.h"
 #include "guiutil.h"
-
 #include "addressbookpage.h"
 #include "optionsmodel.h"
+#include "sendcoinsentry.h"
 
-#include <QApplication>
-#include <QClipboard>
+
 #include <QMessageBox>
 #include <QLocale>
 #include <QDebug>
-#include <QMessageBox>
 
-SendCoinsDialog::SendCoinsDialog(QWidget *parent, const QString &address) :
+SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
     QDialog(parent),
     ui(new Ui::SendCoinsDialog),
     model(0)
 {
     ui->setupUi(this);
-#if QT_VERSION >= 0x040700
-    ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
-    ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
-#endif
-
-    GUIUtil::setupAddressWidget(ui->payTo, this);
 
-    // Set initial send-to address if provided
-    if(!address.isEmpty())
-    {
-        ui->payTo->setText(address);
-        ui->payAmount->setFocus();
-    }
+    addEntry();
+
+    connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
 }
 
 void SendCoinsDialog::setModel(WalletModel *model)
 {
     this->model = model;
+
+    for(int i = 0; i < ui->entries->count(); ++i)
+    {
+        SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+        if(entry)
+        {
+            entry->setModel(model);
+        }
+    }
 }
 
 SendCoinsDialog::~SendCoinsDialog()
@@ -47,26 +44,38 @@
 
 void SendCoinsDialog::on_sendButton_clicked()
 {
-    bool valid;
-    QString payAmount = ui->payAmount->text();
-    QString label;
-    qint64 payAmountParsed;
+    QList<SendCoinsRecipient> recipients;
+    bool valid = true;
+    for(int i = 0; i < ui->entries->count(); ++i)
+    {
+        SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+        if(entry)
+        {
+            if(entry->validate())
+            {
+                recipients.append(entry->getValue());
+            }
+            else
+            {
+                valid = false;
+            }
+        }
+    }
 
-    valid = GUIUtil::parseMoney(payAmount, &payAmountParsed);
-
-    if(!valid || payAmount.isEmpty())
+    if(!valid || recipients.isEmpty())
     {
-        QMessageBox::warning(this, tr("Send Coins"),
-            tr("Must fill in an amount to pay."),
-            QMessageBox::Ok, QMessageBox::Ok);
         return;
     }
 
-    // Add address to address book under label, if specified
-    label = ui->addAsLabel->text();
+    // Format confirmation message
+    QStringList formatted;
+    foreach(const SendCoinsRecipient &rcp, recipients)
+    {
+        formatted.append(tr("%1 BTC to %2 (%3)").arg(GUIUtil::formatMoney(rcp.amount), rcp.label, rcp.address));
+    }
 
     QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
-                          tr("Are you sure you want to send %1 BTC to %2 (%3)?").arg(GUIUtil::formatMoney(payAmountParsed), label, ui->payTo->text()),
+                          tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))),
           QMessageBox::Yes|QMessageBox::Cancel,
           QMessageBox::Cancel);
 
@@ -75,32 +84,45 @@
         return;
     }
 
-    switch(model->sendCoins(ui->payTo->text(), payAmountParsed, label))
+    WalletModel::SendCoinsReturn sendstatus = model->sendCoins(recipients);
+    switch(sendstatus.status)
     {
     case WalletModel::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 WalletModel::InvalidAmount:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("The amount to pay must be larger than 0."),
             QMessageBox::Ok, QMessageBox::Ok);
-        ui->payAmount->setFocus();
         break;
     case WalletModel::AmountExceedsBalance:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("Amount exceeds your balance"),
             QMessageBox::Ok, QMessageBox::Ok);
-        ui->payAmount->setFocus();
         break;
     case WalletModel::AmountWithFeeExceedsBalance:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("Total exceeds your balance when the %1 transaction fee is included").
-            arg(GUIUtil::formatMoney(model->getOptionsModel()->getTransactionFee())),
+            arg(GUIUtil::formatMoney(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"),
             QMessageBox::Ok, QMessageBox::Ok);
-        ui->payAmount->setFocus();
+        break;
+    case WalletModel::TransactionCreationFailed:
+        QMessageBox::warning(this, tr("Send Coins"),
+            tr("Error: Transaction creation failed  "),
+            QMessageBox::Ok, QMessageBox::Ok);
+        break;
+        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."),
+            QMessageBox::Ok, QMessageBox::Ok);
         break;
     case WalletModel::OK:
         accept();
@@ -108,34 +130,23 @@
     }
 }
 
-void SendCoinsDialog::on_pasteButton_clicked()
-{
-    // Paste text from clipboard into recipient field
-    ui->payTo->setText(QApplication::clipboard()->text());
-}
-
-void SendCoinsDialog::on_addressBookButton_clicked()
-{
-    AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this);
-    dlg.setModel(model->getAddressTableModel());
-    if(dlg.exec())
-    {
-        ui->payTo->setText(dlg.getReturnValue());
-        ui->payAmount->setFocus();
-    }
-}
-
-void SendCoinsDialog::on_payTo_textChanged(const QString &address)
-{
-    ui->addAsLabel->setText(model->getAddressTableModel()->labelForAddress(address));
-}
-
 void SendCoinsDialog::clear()
 {
-    ui->payTo->setText(QString());
-    ui->addAsLabel->setText(QString());
-    ui->payAmount->setText(QString());
-    ui->payTo->setFocus();
+    // Remove entries until only one left
+    while(ui->entries->count() > 1)
+    {
+        delete ui->entries->takeAt(0)->widget();
+    }
+
+    // Reset the entry that is left to empty
+    SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
+    if(entry)
+    {
+        entry->clear();
+    }
+
+    updateRemoveEnabled();
+
     ui->sendButton->setDefault(true);
 }
 
@@ -148,3 +159,52 @@
 {
     clear();
 }
+
+void SendCoinsDialog::addEntry()
+{
+    SendCoinsEntry *entry = new SendCoinsEntry(this);
+    entry->setModel(model);
+    ui->entries->addWidget(entry);
+    connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*)));
+
+    updateRemoveEnabled();
+
+    // Focus the field, so that entry can start immediately
+    entry->clear();
+}
+
+void SendCoinsDialog::updateRemoveEnabled()
+{
+    // Remove buttons are enabled as soon as there is more than one send-entry
+    bool enabled = (ui->entries->count() > 1);
+    for(int i = 0; i < ui->entries->count(); ++i)
+    {
+        SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+        if(entry)
+        {
+            entry->setRemoveEnabled(enabled);
+        }
+    }
+    setupTabChain(0);
+}
+
+void SendCoinsDialog::removeEntry(SendCoinsEntry* entry)
+{
+    delete entry;
+    updateRemoveEnabled();
+}
+
+QWidget *SendCoinsDialog::setupTabChain(QWidget *prev)
+{
+    for(int i = 0; i < ui->entries->count(); ++i)
+    {
+        SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
+        if(entry)
+        {
+            prev = entry->setupTabChain(prev);
+        }
+    }
+    QWidget::setTabOrder(prev, ui->addButton);
+    QWidget::setTabOrder(ui->addButton, ui->sendButton);
+    return ui->sendButton;
+}
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -7,31 +7,37 @@
     class SendCoinsDialog;
 }
 class WalletModel;
+class SendCoinsEntry;
 
 class SendCoinsDialog : public QDialog
 {
     Q_OBJECT
 
 public:
-    explicit SendCoinsDialog(QWidget *parent = 0, const QString &address = "");
+    explicit SendCoinsDialog(QWidget *parent = 0);
     ~SendCoinsDialog();
 
     void setModel(WalletModel *model);
 
+    // Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907)
+    // Hence we have to set it up manually
+    QWidget *setupTabChain(QWidget *prev);
+
 public slots:
     void clear();
     void reject();
     void accept();
+    void addEntry();
+    void updateRemoveEnabled();
 
 private:
     Ui::SendCoinsDialog *ui;
     WalletModel *model;
 
 private slots:
-    void on_payTo_textChanged(const QString &address);
-    void on_addressBookButton_clicked();
-    void on_pasteButton_clicked();
     void on_sendButton_clicked();
+
+    void removeEntry(SendCoinsEntry* entry);
 };
 
 #endif // SENDCOINSDIALOG_H
new file mode 100644
--- /dev/null
+++ b/src/qt/sendcoinsentry.cpp
@@ -0,0 +1,119 @@
+#include "sendcoinsentry.h"
+#include "ui_sendcoinsentry.h"
+#include "guiutil.h"
+#include "addressbookpage.h"
+#include "walletmodel.h"
+#include "addresstablemodel.h"
+
+#include "qapplication.h"
+#include "qclipboard.h"
+
+#include <QDebug>
+
+SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
+    QFrame(parent),
+    ui(new Ui::SendCoinsEntry),
+    model(0)
+{
+    ui->setupUi(this);
+
+#if QT_VERSION >= 0x040700
+    ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+    ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
+#endif
+    setFocusPolicy(Qt::TabFocus);
+    setFocusProxy(ui->payTo);
+
+    GUIUtil::setupAddressWidget(ui->payTo, this);
+}
+
+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()
+{
+    AddressBookPage dlg(AddressBookPage::ForSending, 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)
+{
+    ui->addAsLabel->setText(model->getAddressTableModel()->labelForAddress(address));
+}
+
+void SendCoinsEntry::setModel(WalletModel *model)
+{
+    this->model = model;
+}
+
+void SendCoinsEntry::setRemoveEnabled(bool enabled)
+{
+    ui->deleteButton->setEnabled(enabled);
+}
+
+void SendCoinsEntry::clear()
+{
+    ui->payTo->clear();
+    ui->addAsLabel->clear();
+    ui->payAmount->setText(QString());
+    ui->payTo->setFocus();
+}
+
+void SendCoinsEntry::on_deleteButton_clicked()
+{
+    emit removeEntry(this);
+}
+
+bool SendCoinsEntry::validate()
+{
+    // Check input validity
+    bool retval = true;
+
+    if(!ui->payAmount->validate())
+    {
+        retval = false;
+    }
+
+    if(!ui->payTo->hasAcceptableInput() ||
+       (model && !model->validateAddress(ui->payTo->text())))
+    {
+        ui->payTo->setValid(false);
+        retval = false;
+    }
+
+    return retval;
+}
+
+SendCoinsRecipient SendCoinsEntry::getValue()
+{
+    SendCoinsRecipient rv;
+
+    rv.address = ui->payTo->text();
+    rv.label = ui->addAsLabel->text();
+    GUIUtil::parseMoney(ui->payAmount->text(), &rv.amount);
+
+    return rv;
+}
+
+QWidget *SendCoinsEntry::setupTabChain(QWidget *prev)
+{
+    QWidget::setTabOrder(prev, ui->payTo);
+    QWidget::setTabOrder(ui->payTo, ui->addressBookButton);
+    QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton);
+    QWidget::setTabOrder(ui->pasteButton, ui->deleteButton);
+    QWidget::setTabOrder(ui->deleteButton, ui->addAsLabel);
+    return ui->payAmount->setupTabChain(ui->addAsLabel);
+}
new file mode 100644
--- /dev/null
+++ b/src/qt/sendcoinsentry.h
@@ -0,0 +1,45 @@
+#ifndef SENDCOINSENTRY_H
+#define SENDCOINSENTRY_H
+
+#include <QFrame>
+
+namespace Ui {
+    class SendCoinsEntry;
+}
+class WalletModel;
+class SendCoinsRecipient;
+
+class SendCoinsEntry : public QFrame
+{
+    Q_OBJECT
+
+public:
+    explicit SendCoinsEntry(QWidget *parent = 0);
+    ~SendCoinsEntry();
+
+    void setModel(WalletModel *model);
+    bool validate();
+    SendCoinsRecipient getValue();
+    // Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907)
+    // Hence we have to set it up manually
+    QWidget *setupTabChain(QWidget *prev);
+
+public slots:
+    void setRemoveEnabled(bool enabled);
+    void clear();
+
+signals:
+    void removeEntry(SendCoinsEntry *entry);
+
+private slots:
+    void on_deleteButton_clicked();
+    void on_payTo_textChanged(const QString &address);
+    void on_addressBookButton_clicked();
+    void on_pasteButton_clicked();
+
+private:
+    Ui::SendCoinsEntry *ui;
+    WalletModel *model;
+};
+
+#endif // SENDCOINSENTRY_H
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -7,10 +7,12 @@
 #include "headers.h"
 
 #include <QTimer>
+#include <QSet>
 
 WalletModel::WalletModel(CWallet *wallet, QObject *parent) :
     QObject(parent), wallet(wallet), optionsModel(0), addressTableModel(0),
-    transactionTableModel(0)
+    transactionTableModel(0),
+    cachedBalance(0), cachedUnconfirmedBalance(0), cachedNumTransactions(0)
 {
     // Until signal notifications is built into the bitcoin core,
     //  simply update everything after polling using a timer.
@@ -45,72 +47,122 @@
 
 void WalletModel::update()
 {
-    // Plainly emit all signals for now. To be more efficient this should check
-    //   whether the values actually changed first, although it'd be even better if these
-    //   were events coming in from the bitcoin core.
-    emit balanceChanged(getBalance(), wallet->GetUnconfirmedBalance());
-    emit numTransactionsChanged(getNumTransactions());
+    qint64 newBalance = getBalance();
+    qint64 newUnconfirmedBalance = getUnconfirmedBalance();
+    int newNumTransactions = getNumTransactions();
+
+    if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance)
+        emit balanceChanged(newBalance, newUnconfirmedBalance);
+
+    if(cachedNumTransactions != newNumTransactions)
+        emit numTransactionsChanged(newNumTransactions);
+
+    cachedBalance = newBalance;
+    cachedUnconfirmedBalance = newUnconfirmedBalance;
+    cachedNumTransactions = newNumTransactions;
 
     addressTableModel->update();
 }
 
-WalletModel::StatusCode WalletModel::sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs)
+bool WalletModel::validateAddress(const QString &address)
 {
     uint160 hash160 = 0;
-    bool valid = false;
+
+    return AddressToHash160(address.toStdString(), hash160);
+}
 
-    if(!AddressToHash160(payTo.toUtf8().constData(), hash160))
+WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients)
+{
+    qint64 total = 0;
+    QSet<QString> setAddress;
+    QString hex;
+
+    if(recipients.empty())
     {
-        return InvalidAddress;
+        return OK;
     }
 
-    if(payAmount <= 0)
+    // Pre-check input data for validity
+    foreach(const SendCoinsRecipient &rcp, recipients)
     {
-        return InvalidAmount;
+        uint160 hash160 = 0;
+
+        if(!AddressToHash160(rcp.address.toUtf8().constData(), hash160))
+        {
+            return InvalidAddress;
+        }
+        setAddress.insert(rcp.address);
+
+        if(rcp.amount <= 0)
+        {
+            return InvalidAmount;
+        }
+        total += rcp.amount;
     }
 
-    if(payAmount > getBalance())
+    if(recipients.size() > setAddress.size())
+    {
+        return DuplicateAddress;
+    }
+
+    if(total > getBalance())
     {
         return AmountExceedsBalance;
     }
 
-    if((payAmount + nTransactionFee) > getBalance())
+    if((total + nTransactionFee) > getBalance())
     {
-        return AmountWithFeeExceedsBalance;
+        return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
     }
 
     CRITICAL_BLOCK(cs_main)
+    CRITICAL_BLOCK(wallet->cs_mapWallet)
     {
-        // Send to bitcoin address
-        CWalletTx wtx;
-        CScript scriptPubKey;
-        scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
+        // Sendmany
+        std::vector<std::pair<CScript, int64> > vecSend;
+        foreach(const SendCoinsRecipient &rcp, recipients)
+        {
+            CScript scriptPubKey;
+            scriptPubKey.SetBitcoinAddress(rcp.address.toStdString());
+            vecSend.push_back(make_pair(scriptPubKey, rcp.amount));
+        }
 
-        std::string strError = wallet->SendMoney(scriptPubKey, payAmount, wtx, true);
-        if (strError == "")
+        CWalletTx wtx;
+        CReserveKey keyChange(wallet);
+        int64 nFeeRequired = 0;
+        bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
+
+        if(!fCreated)
         {
-            // OK
+            if((total + nFeeRequired) > wallet->GetBalance())
+            {
+                return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired);
+            }
+            return TransactionCreationFailed;
         }
-        else if (strError == "ABORTED")
+        if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString(), NULL))
         {
             return Aborted;
         }
-        else
+        if(!wallet->CommitTransaction(wtx, keyChange))
         {
-            emit error(tr("Sending..."), QString::fromStdString(strError));
-            return MiscError;
+            return TransactionCommitFailed;
         }
+        hex = QString::fromStdString(wtx.GetHash().GetHex());
     }
 
     // Add addresses that we've sent to to the address book
-    std::string strAddress = payTo.toStdString();
-    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
+    foreach(const SendCoinsRecipient &rcp, recipients)
     {
-        if (!wallet->mapAddressBook.count(strAddress))
-            wallet->SetAddressBookName(strAddress, addToAddressBookAs.toStdString());
+        std::string strAddress = rcp.address.toStdString();
+        CRITICAL_BLOCK(wallet->cs_mapAddressBook)
+        {
+            if (!wallet->mapAddressBook.count(strAddress))
+                wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
+        }
     }
 
-    return OK;
+    return SendCoinsReturn(OK, 0, hex);
 }
 
 OptionsModel *WalletModel::getOptionsModel()
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -8,6 +8,13 @@
 class TransactionTableModel;
 class CWallet;
 
+struct SendCoinsRecipient
+{
+    QString address;
+    QString label;
+    qint64 amount;
+};
+
 // Interface to a Bitcoin wallet
 class WalletModel : public QObject
 {
@@ -22,6 +29,9 @@
         InvalidAddress,
         AmountExceedsBalance,
         AmountWithFeeExceedsBalance,
+        DuplicateAddress,
+        TransactionCreationFailed,
+        TransactionCommitFailed,
         Aborted,
         MiscError
     };
@@ -34,8 +44,25 @@
     qint64 getUnconfirmedBalance() const;
     int getNumTransactions() const;
 
-    /* Send coins */
-    StatusCode sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs=QString());
+    // Check address for validity
+    bool validateAddress(const QString &address);
+
+    // Return status record for SendCoins
+    // fee is used in case status is "AmountWithFeeExceedsBalance"
+    // hex is filled with the transaction hash if status is "OK"
+    struct SendCoinsReturn
+    {
+        SendCoinsReturn(StatusCode status,
+                         qint64 fee=0,
+                         QString hex=QString()):
+            status(status), fee(fee), hex(hex) {}
+        StatusCode status;
+        qint64 fee;
+        QString hex;
+    };
+
+    // Send coins to list of recipients
+    SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients);
 private:
     CWallet *wallet;
 
@@ -46,6 +73,10 @@
     AddressTableModel *addressTableModel;
     TransactionTableModel *transactionTableModel;
 
+    qint64 cachedBalance;
+    qint64 cachedUnconfirmedBalance;
+    qint64 cachedNumTransactions;
+
 signals:
     void balanceChanged(qint64 balance, qint64 unconfirmedBalance);
     void numTransactionsChanged(int count);
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -30,6 +30,7 @@
 #endif
 
 #ifdef __WXMSW__
+#include <windows.h>
 // This is used to attempt to keep keying material out of swap
 // Note that VirtualLock does not provide this as a guarantee on Windows,
 // but, in practice, memory that has been VirtualLock'd almost never gets written to