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)
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;
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);
}
break;
}
-
return true;
}
return false;
return QVariant();
}
-Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const
+Qt::ItemFlags AddressTableModel::flags(const QModelIndex &index) const
{
if(!index.isValid())
return 0;
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);
{
return QString();
}
+
// Add entry
{
LOCK(wallet->cs_wallet);
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);
/** 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.
break;
case EditReceivingAddress:
setWindowTitle(tr("Edit receiving address"));
- ui->addressEdit->setDisabled(true);
+ ui->addressEdit->setEnabled(false);
break;
case EditSendingAddress:
setWindowTitle(tr("Edit sending address"));
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);
{
if(!model)
return false;
+
switch(mode)
{
case NewReceivingAddress:
{
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();
};
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();
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;
{
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"));
{
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)
// 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));
}