From 48208883de8397dbd13bec351e71fe62d5cd5db1 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 3 Jun 2011 15:16:11 +0200 Subject: [PATCH] Finish implementation of address book --- gui/include/addresstablemodel.h | 13 +++++-- gui/include/editaddressdialog.h | 3 ++ gui/src/addressbookdialog.cpp | 16 ++++++--- gui/src/addresstablemodel.cpp | 64 ++++++++++++++++++++++++++++++--- gui/src/bitcoingui.cpp | 7 +--- gui/src/editaddressdialog.cpp | 32 ++++++++++++++--- 6 files changed, 113 insertions(+), 22 deletions(-) diff --git a/gui/include/addresstablemodel.h b/gui/include/addresstablemodel.h index f9ccab4eb..189026097 100644 --- a/gui/include/addresstablemodel.h +++ b/gui/include/addresstablemodel.h @@ -13,10 +13,10 @@ public: explicit AddressTableModel(QObject *parent = 0); ~AddressTableModel(); - enum { + enum ColumnIndex { Label = 0, /* User specified label */ Address = 1 /* Bitcoin address */ - } ColumnIndex; + }; enum { TypeRole = Qt::UserRole @@ -25,13 +25,22 @@ public: static const QString Send; /* Send addres */ static const QString Receive; /* Receive address */ + /* Overridden methods 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); 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()); + /* Add an address to the model. + Returns true on success, false otherwise. + */ + bool addRow(const QString &type, const QString &label, const QString &address); + + /* Update address list from core. Invalidates any indices. + */ void updateList(); private: AddressTablePriv *priv; diff --git a/gui/include/editaddressdialog.h b/gui/include/editaddressdialog.h index 3d8a5dcf8..dd7766951 100644 --- a/gui/include/editaddressdialog.h +++ b/gui/include/editaddressdialog.h @@ -29,10 +29,13 @@ public: void setModel(AddressTableModel *model); void loadRow(int row); + void saveCurrentRow(); private: Ui::EditAddressDialog *ui; QDataWidgetMapper *mapper; + Mode mode; + AddressTableModel *model; }; #endif // EDITADDRESSDIALOG_H diff --git a/gui/src/addressbookdialog.cpp b/gui/src/addressbookdialog.cpp index 3f8e38152..9b9e9bbc8 100644 --- a/gui/src/addressbookdialog.cpp +++ b/gui/src/addressbookdialog.cpp @@ -100,7 +100,10 @@ void AddressBookDialog::on_editButton_clicked() EditAddressDialog::EditReceivingAddress); dlg.setModel(model); dlg.loadRow(indexes.at(0).row()); - dlg.exec(); + if(dlg.exec()) + { + dlg.saveCurrentRow(); + } } void AddressBookDialog::on_newAddressButton_clicked() @@ -110,7 +113,10 @@ void AddressBookDialog::on_newAddressButton_clicked() EditAddressDialog::NewSendingAddress : EditAddressDialog::NewReceivingAddress); dlg.setModel(model); - dlg.exec(); + if(dlg.exec()) + { + dlg.saveCurrentRow(); + } } void AddressBookDialog::on_tabWidget_currentChanged(int index) @@ -130,9 +136,9 @@ void AddressBookDialog::on_deleteButton_clicked() { QTableView *table = getCurrentTable(); QModelIndexList indexes = table->selectionModel()->selectedRows(); - - foreach (QModelIndex index, indexes) { - table->model()->removeRow(index.row()); + if(!indexes.isEmpty()) + { + table->model()->removeRow(indexes.at(0).row()); } } diff --git a/gui/src/addresstablemodel.cpp b/gui/src/addresstablemodel.cpp index 1cacd08fe..fbb2eb528 100644 --- a/gui/src/addresstablemodel.cpp +++ b/gui/src/addresstablemodel.cpp @@ -13,6 +13,7 @@ struct AddressTableEntry Sending, Receiving }; + Type type; QString label; QString address; @@ -128,21 +129,31 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu { if(!index.isValid()) return false; + AddressTableEntry *rec = static_cast(index.internalPointer()); if(role == Qt::EditRole) { switch(index.column()) { case Label: - /* TODO */ + SetAddressBookName(rec->address.toStdString(), value.toString().toStdString()); + rec->label = value.toString(); break; case Address: - /* TODO */ /* Double-check that we're not overwriting receiving address */ - /* Note that changing address changes index in map */ + if(rec->type == AddressTableEntry::Sending) + { + /* Remove old entry */ + CWalletDB().EraseName(rec->address.toStdString()); + /* Add new entry with new address */ + SetAddressBookName(value.toString().toStdString(), rec->label.toStdString()); + + rec->address = value.toString(); + } break; } - /* emit dataChanged(index, index); */ + emit dataChanged(index, index); + return true; } return false; @@ -179,3 +190,48 @@ void AddressTableModel::updateList() priv->refreshAddressTable(); endResetModel(); } + +bool AddressTableModel::addRow(const QString &type, const QString &label, const QString &address) +{ + std::string strLabel = label.toStdString(); + std::string strAddress = address.toStdString(); + + if(type == Send) + { + /* Check for duplicate */ + CRITICAL_BLOCK(cs_mapAddressBook) + { + if(mapAddressBook.count(strAddress)) + { + return false; + } + } + } else if(type == Receive) + { + /* Generate a new address to associate with given label */ + strAddress = PubKeyToAddress(GetKeyFromKeyPool()); + } else + { + return false; + } + /* Add entry and update list */ + SetAddressBookName(strAddress, strLabel); + updateList(); + return true; +} + +bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent) +{ + Q_UNUSED(parent); + AddressTableEntry *rec = priv->index(row); + if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving) + { + /* Can only remove one row at a time, and cannot remove rows not in model. + Also refuse to remove receiving addresses. + */ + return false; + } + CWalletDB().EraseName(rec->address.toStdString()); + updateList(); + return true; +} diff --git a/gui/src/bitcoingui.cpp b/gui/src/bitcoingui.cpp index a7f236803..ba5b1d99a 100644 --- a/gui/src/bitcoingui.cpp +++ b/gui/src/bitcoingui.cpp @@ -240,12 +240,7 @@ void BitcoinGUI::addressbookClicked() { AddressBookDialog dlg; dlg.setTab(AddressBookDialog::SendingTab); - /* if an address accepted, do a 'send' to specified address */ - if(dlg.exec()) - { - SendCoinsDialog send(0, dlg.getReturnValue()); - send.exec(); - } + dlg.exec(); } void BitcoinGUI::receivingAddressesClicked() diff --git a/gui/src/editaddressdialog.cpp b/gui/src/editaddressdialog.cpp index 6c0148d9d..ddc7292cc 100644 --- a/gui/src/editaddressdialog.cpp +++ b/gui/src/editaddressdialog.cpp @@ -4,11 +4,11 @@ #include "guiutil.h" #include -#include +#include EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) : QDialog(parent), - ui(new Ui::EditAddressDialog), mapper(0) + ui(new Ui::EditAddressDialog), mapper(0), mode(mode), model(0) { ui->setupUi(this); @@ -33,7 +33,7 @@ EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) : } mapper = new QDataWidgetMapper(this); - + mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); } EditAddressDialog::~EditAddressDialog() @@ -43,7 +43,7 @@ EditAddressDialog::~EditAddressDialog() void EditAddressDialog::setModel(AddressTableModel *model) { - qDebug() << "setModel " << model; + this->model = model; mapper->setModel(model); mapper->addMapping(ui->labelEdit, AddressTableModel::Label); mapper->addMapping(ui->addressEdit, AddressTableModel::Address); @@ -51,6 +51,28 @@ void EditAddressDialog::setModel(AddressTableModel *model) void EditAddressDialog::loadRow(int row) { - qDebug() << "loadRow " << row; mapper->setCurrentIndex(row); } + +void EditAddressDialog::saveCurrentRow() +{ + switch(mode) + { + case NewReceivingAddress: + case NewSendingAddress: + if(!model->addRow( + mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive, + ui->labelEdit->text(), + ui->addressEdit->text())) + { + QMessageBox::warning(this, windowTitle(), + tr("The address %1 is already in the address book.").arg(ui->addressEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + } + break; + case EditReceivingAddress: + case EditSendingAddress: + mapper->submit(); + break; + } +}