Finish implementation of address book
authorWladimir J. van der Laan <laanwj@gmail.com>
Fri, 3 Jun 2011 13:16:11 +0000 (15:16 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Fri, 3 Jun 2011 13:16:11 +0000 (15:16 +0200)
gui/include/addresstablemodel.h
gui/include/editaddressdialog.h
gui/src/addressbookdialog.cpp
gui/src/addresstablemodel.cpp
gui/src/bitcoingui.cpp
gui/src/editaddressdialog.cpp

index f9ccab4..1890260 100644 (file)
@@ -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;
index 3d8a5dc..dd77669 100644 (file)
@@ -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
index 3f8e381..9b9e9bb 100644 (file)
@@ -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());
     }
 }
 
index 1cacd08..fbb2eb5 100644 (file)
@@ -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<AddressTableEntry*>(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;
+}
index a7f2368..ba5b1d9 100644 (file)
@@ -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()
index 6c0148d..ddc7292 100644 (file)
@@ -4,11 +4,11 @@
 #include "guiutil.h"
 
 #include <QDataWidgetMapper>
-#include <QDebug>
+#include <QMessageBox>
 
 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;
+    }
+}