diff --git a/src/libwalletqt/AddressBook.cpp b/src/libwalletqt/AddressBook.cpp index 4e34e135..d51fecc0 100644 --- a/src/libwalletqt/AddressBook.cpp +++ b/src/libwalletqt/AddressBook.cpp @@ -46,58 +46,85 @@ int AddressBook::errorCode() const return m_addressBookImpl->errorCode(); } -QList AddressBook::getAll(bool update) const +void AddressBook::getAll() { qDebug(__FUNCTION__); emit refreshStarted(); - if(update) - m_rows.clear(); + { + QWriteLocker locker(&m_lock); - if (m_rows.empty()){ + m_rows.clear(); for (auto &abr: m_addressBookImpl->getAll()) { m_rows.append(abr); } } emit refreshFinished(); - return m_rows; - } -Monero::AddressBookRow * AddressBook::getRow(int index) const +bool AddressBook::getRow(int index, std::function callback) const { - return m_rows.at(index); + QReadLocker locker(&m_lock); + + if (index < 0 || index >= m_rows.size()) + { + return false; + } + + callback(*m_rows.value(index)); + return true; } -bool AddressBook::addRow(const QString &address, const QString &payment_id, const QString &description) const +bool AddressBook::addRow(const QString &address, const QString &payment_id, const QString &description) { // virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0; - bool r = m_addressBookImpl->addRow(address.toStdString(), payment_id.toStdString(), description.toStdString()); + bool result; - if(r) - getAll(true); + { + QWriteLocker locker(&m_lock); - return r; + result = m_addressBookImpl->addRow(address.toStdString(), payment_id.toStdString(), description.toStdString()); + } + + if (result) + { + getAll(); + } + + return result; } -bool AddressBook::deleteRow(int rowId) const +bool AddressBook::deleteRow(int rowId) { - bool r = m_addressBookImpl->deleteRow(rowId); + bool result; + + { + QWriteLocker locker(&m_lock); + + result = m_addressBookImpl->deleteRow(rowId); + } // Fetch new data from wallet2. - getAll(true); + if (result) + { + getAll(); + } - return r; + return result; } quint64 AddressBook::count() const { + QReadLocker locker(&m_lock); + return m_rows.size(); } int AddressBook::lookupPaymentID(const QString &payment_id) const { + QReadLocker locker(&m_lock); + return m_addressBookImpl->lookupPaymentID(payment_id.toStdString()); } diff --git a/src/libwalletqt/AddressBook.h b/src/libwalletqt/AddressBook.h index 84566615..1d9309b3 100644 --- a/src/libwalletqt/AddressBook.h +++ b/src/libwalletqt/AddressBook.h @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -43,10 +44,9 @@ class AddressBook : public QObject { Q_OBJECT public: - Q_INVOKABLE QList getAll(bool update = false) const; - Q_INVOKABLE Monero::AddressBookRow * getRow(int index) const; - Q_INVOKABLE bool addRow(const QString &address, const QString &payment_id, const QString &description) const; - Q_INVOKABLE bool deleteRow(int rowId) const; + Q_INVOKABLE bool getRow(int index, std::function callback) const; + Q_INVOKABLE bool addRow(const QString &address, const QString &payment_id, const QString &description); + Q_INVOKABLE bool deleteRow(int rowId); quint64 count() const; Q_INVOKABLE QString errorString() const; Q_INVOKABLE int errorCode() const; @@ -61,6 +61,8 @@ public: Q_ENUM(ErrorCode); +private: + void getAll(); signals: void refreshStarted() const; @@ -73,6 +75,7 @@ private: explicit AddressBook(Monero::AddressBook * abImpl, QObject *parent); friend class Wallet; Monero::AddressBook * m_addressBookImpl; + mutable QReadWriteLock m_lock; mutable QList m_rows; }; diff --git a/src/model/AddressBookModel.cpp b/src/model/AddressBookModel.cpp index 5c00ad6f..c21fa2f6 100644 --- a/src/model/AddressBookModel.cpp +++ b/src/model/AddressBookModel.cpp @@ -57,30 +57,27 @@ int AddressBookModel::rowCount(const QModelIndex &) const QVariant AddressBookModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - return QVariant(); + QVariant result; - if (index.row() < 0 || (unsigned)index.row() >= m_addressBook->count()) { - return QVariant(); - } - - Monero::AddressBookRow * ar = m_addressBook->getRow(index.row()); - - QVariant result = ""; - switch (role) { - case AddressBookAddressRole: - result = QString::fromStdString(ar->getAddress()); - break; - case AddressBookDescriptionRole: - result = QString::fromStdString(ar->getDescription()); - break; - case AddressBookPaymentIdRole: - result = QString::fromStdString(ar->getPaymentId()); - break; - case AddressBookRowIdRole: - // Qt doesnt support size_t overload type casting - result.setValue(ar->getRowId()); - break; + bool found = m_addressBook->getRow(index.row(), [&result, &role](const Monero::AddressBookRow &row) { + switch (role) { + case AddressBookAddressRole: + result = QString::fromStdString(row.getAddress()); + break; + case AddressBookDescriptionRole: + result = QString::fromStdString(row.getDescription()); + break; + case AddressBookPaymentIdRole: + result = QString::fromStdString(row.getPaymentId()); + break; + case AddressBookRowIdRole: + // Qt doesnt support size_t overload type casting + result.setValue(row.getRowId()); + break; + } + }); + if (!found) { + qCritical("%s: internal error: invalid index %d", __FUNCTION__, index.row()); } return result;