Merge pull request #9 from CryptoManiac/current v0.4.4.7-nvc-bugfix4
author0xDEADFACE <masmfan@gmail.com>
Sun, 23 Feb 2014 17:27:08 +0000 (09:27 -0800)
committer0xDEADFACE <masmfan@gmail.com>
Sun, 23 Feb 2014 17:27:08 +0000 (09:27 -0800)
Merge some address book related fixes from upstream

src/qt/addresstablemodel.cpp
src/qt/addresstablemodel.h
src/qt/editaddressdialog.cpp
src/qt/editaddressdialog.h
src/rpcwallet.cpp
src/wallet.cpp

index e65d391..03b09cd 100644 (file)
@@ -69,6 +69,8 @@ public:
                                   QString::fromStdString(address.ToString())));
             }
         }
+        // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order
+        qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
     }
 
     void updateEntry(const QString &address, const QString &label, bool isMine, int status)
@@ -208,7 +210,7 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const
     return QVariant();
 }
 
-bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role)
+bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
 {
     if(!index.isValid())
         return false;
@@ -221,18 +223,36 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
         switch(index.column())
         {
         case Label:
+            // Do nothing, if old label == new label
+            if(rec->label == value.toString())
+            {
+                editStatus = NO_CHANGES;
+                return false;
+            }
             wallet->SetAddressBookName(CBitcoinAddress(rec->address.toStdString()).Get(), value.toString().toStdString());
-            rec->label = value.toString();
             break;
         case Address:
+            // Do nothing, if old address == new address
+            if(CBitcoinAddress(rec->address.toStdString()) == CBitcoinAddress(value.toString().toStdString()))
+            {
+                editStatus = NO_CHANGES;
+                return false;
+            }
             // Refuse to set invalid address, set error status and return false
-            if(!walletModel->validateAddress(value.toString()))
+            else if(!walletModel->validateAddress(value.toString()))
             {
                 editStatus = INVALID_ADDRESS;
                 return false;
             }
+            // Check for duplicate addresses to prevent accidental deletion of addresses, if you try
+            // to paste an existing address over another address (with a different label)
+            else if(wallet->mapAddressBook.count(CBitcoinAddress(value.toString().toStdString()).Get()))
+            {
+                editStatus = DUPLICATE_ADDRESS;
+                return false;
+            }
             // Double-check that we're not overwriting a receiving address
-            if(rec->type == AddressTableEntry::Sending)
+            else if(rec->type == AddressTableEntry::Sending)
             {
                 {
                     LOCK(wallet->cs_wallet);
@@ -244,7 +264,6 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
             }
             break;
         }
-
         return true;
     }
     return false;
@@ -262,7 +281,7 @@ QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation,
     return QVariant();
 }
 
-Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const
+Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const
 {
     if(!index.isValid())
         return 0;
@@ -279,7 +298,7 @@ Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const
     return retval;
 }
 
-QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const
+QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &parent) const
 {
     Q_UNUSED(parent);
     AddressTableEntry *data = priv->index(row);
@@ -345,6 +364,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
     {
         return QString();
     }
+
     // Add entry
     {
         LOCK(wallet->cs_wallet);
@@ -353,7 +373,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
     return QString::fromStdString(strAddress);
 }
 
-bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent)
+bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent)
 {
     Q_UNUSED(parent);
     AddressTableEntry *rec = priv->index(row);
index 42974e3..ae3e3b2 100644 (file)
@@ -29,26 +29,27 @@ public:
 
     /** Return status of edit/insert operation */
     enum EditStatus {
-        OK,
-        INVALID_ADDRESS,   /**< Unparseable address */
-        DUPLICATE_ADDRESS,  /**< Address already in address book */
-        WALLET_UNLOCK_FAILURE, /**< Wallet could not be unlocked to create new receiving address */
-        KEY_GENERATION_FAILURE /**< Generating a new public key for a receiving address failed */
+        OK,                     /**< Everything ok */
+        NO_CHANGES,             /**< No changes were made during edit operation */
+        INVALID_ADDRESS,        /**< Unparseable address */
+        DUPLICATE_ADDRESS,      /**< Address already in address book */
+        WALLET_UNLOCK_FAILURE,  /**< Wallet could not be unlocked to create new receiving address */
+        KEY_GENERATION_FAILURE  /**< Generating a new public key for a receiving address failed */
     };
 
-    static const QString Send; /**< Specifies send address */
-    static const QString Receive; /**< Specifies receive address */
+    static const QString Send;      /**< Specifies send address */
+    static const QString Receive;   /**< Specifies receive address */
 
     /** @name Methods overridden from QAbstractTableModel
         @{*/
     int rowCount(const QModelIndex &parent) const;
     int columnCount(const QModelIndex &parent) const;
     QVariant data(const QModelIndex &index, int role) const;
-    bool setData(const QModelIndex & index, const QVariant & value, int role);
+    bool setData(const QModelIndex &index, const QVariant &value, int role);
     QVariant headerData(int section, Qt::Orientation orientation, int role) const;
-    QModelIndex index(int row, int column, const QModelIndex & parent) const;
-    bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex());
-    Qt::ItemFlags flags(const QModelIndex & index) const;
+    QModelIndex index(int row, int column, const QModelIndex &parent) const;
+    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+    Qt::ItemFlags flags(const QModelIndex &index) const;
     /*@}*/
 
     /* Add an address to the model.
index 409316a..776487c 100644 (file)
@@ -25,7 +25,7 @@ EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) :
         break;
     case EditReceivingAddress:
         setWindowTitle(tr("Edit receiving address"));
-        ui->addressEdit->setDisabled(true);
+        ui->addressEdit->setEnabled(false);
         break;
     case EditSendingAddress:
         setWindowTitle(tr("Edit sending address"));
@@ -44,6 +44,9 @@ EditAddressDialog::~EditAddressDialog()
 void EditAddressDialog::setModel(AddressTableModel *model)
 {
     this->model = model;
+    if(!model)
+        return;
+
     mapper->setModel(model);
     mapper->addMapping(ui->labelEdit, AddressTableModel::Label);
     mapper->addMapping(ui->addressEdit, AddressTableModel::Address);
@@ -58,6 +61,7 @@ bool EditAddressDialog::saveCurrentRow()
 {
     if(!model)
         return false;
+
     switch(mode)
     {
     case NewReceivingAddress:
@@ -82,35 +86,39 @@ void EditAddressDialog::accept()
 {
     if(!model)
         return;
+
     if(!saveCurrentRow())
     {
         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);
+        case AddressTableModel::OK:
+            // Failed with unknown reason. Just reject.
+            break;
+        case AddressTableModel::NO_CHANGES:
+            // No changes were made during edit operation. Just reject.
             break;
         case AddressTableModel::INVALID_ADDRESS:
             QMessageBox::warning(this, windowTitle(),
                 tr("The entered address \"%1\" is not a valid NovaCoin address.").arg(ui->addressEdit->text()),
                 QMessageBox::Ok, QMessageBox::Ok);
-            return;
+            break;
+        case AddressTableModel::DUPLICATE_ADDRESS:
+            QMessageBox::warning(this, windowTitle(),
+                tr("The entered address \"%1\" is already in the address book.").arg(ui->addressEdit->text()),
+                QMessageBox::Ok, QMessageBox::Ok);
+            break;
         case AddressTableModel::WALLET_UNLOCK_FAILURE:
             QMessageBox::critical(this, windowTitle(),
                 tr("Could not unlock wallet."),
                 QMessageBox::Ok, QMessageBox::Ok);
-            return;
+            break;
         case AddressTableModel::KEY_GENERATION_FAILURE:
             QMessageBox::critical(this, windowTitle(),
                 tr("New key generation failed."),
                 QMessageBox::Ok, QMessageBox::Ok);
-            return;
-        case AddressTableModel::OK:
-            // Failed with unknown reason. Just reject.
             break;
-        }
 
+        }
         return;
     }
     QDialog::accept();
index 7ec053f..0e4183b 100644 (file)
@@ -27,15 +27,17 @@ public:
     };
 
     explicit EditAddressDialog(Mode mode, QWidget *parent = 0);
-    ~EditAddressDialog();    
+    ~EditAddressDialog();
 
     void setModel(AddressTableModel *model);
     void loadRow(int row);
 
-    void accept();
-
     QString getAddress() const;
     void setAddress(const QString &address);
+
+public slots:
+    void accept();
+
 private:
     bool saveCurrentRow();
 
index c6a4302..184894c 100644 (file)
@@ -1001,6 +1001,13 @@ Value listreceivedbyaccount(const Array& params, bool fHelp)
     return ListReceived(params, true);
 }
 
+static void MaybePushAddress(Object & entry, const CTxDestination &dest)
+{
+    CBitcoinAddress addr;
+    if (addr.Set(dest))
+        entry.push_back(Pair("address", addr.ToString()));
+}
+
 void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret)
 {
     int64 nGeneratedImmature, nGeneratedMature, nFee;
@@ -1039,7 +1046,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
         {
             Object entry;
             entry.push_back(Pair("account", strSentAccount));
-            entry.push_back(Pair("address", CBitcoinAddress(s.first).ToString()));
+            MaybePushAddress(entry, s.first);
 
             if (wtx.GetDepthInMainChain() < 0) {
                 entry.push_back(Pair("category", "conflicted"));
@@ -1067,7 +1074,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
             {
                 Object entry;
                 entry.push_back(Pair("account", account));
-                entry.push_back(Pair("address", CBitcoinAddress(r.first).ToString()));
+                MaybePushAddress(entry, r.first);
                 if (wtx.IsCoinBase())
                 {
                     if (wtx.GetDepthInMainChain() < 1)
index bdcbc0c..b7451e9 100644 (file)
@@ -778,22 +778,35 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l
     // Sent/received.
     BOOST_FOREACH(const CTxOut& txout, vout)
     {
+        bool fIsMine;
+        // Only need to handle txouts if AT LEAST one of these is true:
+        //   1) they debit from us (sent)
+        //   2) the output is to us (received)
+        if (nDebit > 0)
+        {
+            // Don't report 'change' txouts
+            if (pwallet->IsChange(txout))
+                continue;
+            fIsMine = pwallet->IsMine(txout);
+        }
+        else if (!(fIsMine = pwallet->IsMine(txout)))
+            continue;
+
+        // In either case, we need to get the destination address
         CTxDestination address;
-        vector<unsigned char> vchPubKey;
         if (!ExtractDestination(txout.scriptPubKey, address))
         {
             printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
                    this->GetHash().ToString().c_str());
+            address = CNoDestination();
         }
 
-        // Don't report 'change' txouts
-        if (nDebit > 0 && pwallet->IsChange(txout))
-            continue;
-
+        // If we are debited by the transaction, add the output as a "sent" entry
         if (nDebit > 0)
             listSent.push_back(make_pair(address, txout.nValue));
 
-        if (pwallet->IsMine(txout))
+        // If we are receiving the output, add it as a "received" entry
+        if (fIsMine)
             listReceived.push_back(make_pair(address, txout.nValue));
     }