diff --git a/application.qrc b/application.qrc
index c7201af..52afaf1 100644
--- a/application.qrc
+++ b/application.qrc
@@ -17,5 +17,6 @@
res/zec_qt_wallet_fr.qm
res/zec_qt_wallet_pt.qm
res/zec_qt_wallet_it.qm
+ res/zec_qt_wallet_zh.qm
diff --git a/res/zec_qt_wallet_zh.qm b/res/zec_qt_wallet_zh.qm
new file mode 100644
index 0000000..de6ed57
Binary files /dev/null and b/res/zec_qt_wallet_zh.qm differ
diff --git a/silentdragon.pro b/silentdragon.pro
index 025ba3a..090294d 100644
--- a/silentdragon.pro
+++ b/silentdragon.pro
@@ -53,11 +53,13 @@ SOURCES += \
src/addressbook.cpp \
src/logger.cpp \
src/addresscombo.cpp \
+ src/validateaddress.cpp \
src/websockets.cpp \
src/mobileappconnector.cpp \
src/recurring.cpp \
src/requestdialog.cpp \
- src/memoedit.cpp
+ src/memoedit.cpp \
+ src/viewalladdresses.cpp
HEADERS += \
src/mainwindow.h \
@@ -77,12 +79,14 @@ HEADERS += \
src/fillediconlabel.h \
src/addressbook.h \
src/logger.h \
- src/addresscombo.h \
+ src/addresscombo.h \
+ src/validateaddress.h \
src/websockets.h \
src/mobileappconnector.h \
src/recurring.h \
src/requestdialog.h \
- src/memoedit.h
+ src/memoedit.h \
+ src/viewalladdresses.h
FORMS += \
src/mainwindow.ui \
@@ -92,10 +96,14 @@ FORMS += \
src/turnstile.ui \
src/turnstileprogress.ui \
src/privkey.ui \
- src/memodialog.ui \
+ src/memodialog.ui \
+ src/viewalladdresses.ui \
+ src/validateaddress.ui \
+ src/viewalladdresses.ui \
src/connection.ui \
src/zboard.ui \
src/addressbook.ui \
+ src/viewalladdresses.ui \
src/mobileappconnector.ui \
src/createzcashconfdialog.ui \
src/recurringdialog.ui \
@@ -107,7 +115,8 @@ TRANSLATIONS = res/zec_qt_wallet_es.ts \
res/zec_qt_wallet_fr.ts \
res/zec_qt_wallet_de.ts \
res/zec_qt_wallet_pt.ts \
- res/zec_qt_wallet_it.ts
+ res/zec_qt_wallet_it.ts \
+ res/zec_qt_wallet_zh.ts
include(singleapplication/singleapplication.pri)
DEFINES += QAPPLICATION_CLASS=QApplication
diff --git a/src/addressbook.cpp b/src/addressbook.cpp
index 6cf0489..4ef2d2b 100644
--- a/src/addressbook.cpp
+++ b/src/addressbook.cpp
@@ -122,14 +122,32 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
// Add new address button
QObject::connect(ab.addNew, &QPushButton::clicked, [&] () {
auto addr = ab.addr->text().trimmed();
- if (!addr.isEmpty() && !ab.label->text().isEmpty()) {
- // Test if address is valid.
- if (!Settings::isValidAddress(addr)) {
- QMessageBox::critical(parent, QObject::tr("Address Format Error"), addr + QObject::tr(" doesn't seem to be a valid Hush address."), QMessageBox::Ok);
- } else {
- model.addNewLabel(ab.label->text(), ab.addr->text());
- }
+ QString newLabel = ab.label->text();
+
+ if (addr.isEmpty() || newLabel.isEmpty()) {
+ QMessageBox::critical(parent, QObject::tr("Address or Label Error"),
+ QObject::tr("Address or Label cannot be empty"), QMessageBox::Ok);
+ return;
}
+ // Test if address is valid.
+ if (!Settings::isValidAddress(addr)) {
+ QMessageBox::critical(parent, QObject::tr("Address Format Error"),
+ QObject::tr("%1 doesn't seem to be a valid Zcash address.")
+ .arg(addr),
+ QMessageBox::Ok);
+ return;
+ }
+
+ // Don't allow duplicate address labels.
+ if (!getInstance()->getAddressForLabel(newLabel).isEmpty()) {
+ QMessageBox::critical(parent, QObject::tr("Label Error"),
+ QObject::tr("The label '%1' already exists. Please remove the existing label.")
+ .arg(newLabel),
+ QMessageBox::Ok);
+ return;
+ }
+
+ model.addNewLabel(newLabel, ab.addr->text());
});
// Import Button
@@ -217,7 +235,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
if (d.exec() == QDialog::Accepted && target != nullptr) {
auto selection = ab.addresses->selectionModel();
- if (selection->hasSelection()) {
+ if (selection && selection->hasSelection() && selection->selectedRows().size() > 0) {
auto item = model.itemAt(selection->selectedRows().at(0).row());
fnSetTargetLabelAddr(target, item.first, item.second);
}
@@ -244,17 +262,24 @@ AddressBook::AddressBook() {
void AddressBook::readFromStorage() {
QFile file(AddressBook::writeableFile());
- if (!file.exists()) {
- return;
- }
+ if (file.exists()) {
+ allLabels.clear();
+ file.open(QIODevice::ReadOnly);
+ QDataStream in(&file); // read the data serialized from the file
+ QString version;
+ in >> version >> allLabels;
- allLabels.clear();
- file.open(QIODevice::ReadOnly);
- QDataStream in(&file); // read the data serialized from the file
- QString version;
- in >> version >> allLabels;
+ file.close();
+ }
- file.close();
+ // Special.
+ // Add the default ZecWallet donation address if it isn't already present
+ // QList allAddresses;
+ // std::transform(allLabels.begin(), allLabels.end(),
+ // std::back_inserter(allAddresses), [=] (auto i) { return i.second; });
+ // if (!allAddresses.contains(Settings::getDonationAddr(true))) {
+ // allLabels.append(QPair("ZecWallet donation", Settings::getDonationAddr(true)));
+ // }
}
void AddressBook::writeToStorage() {
@@ -337,6 +362,16 @@ QString AddressBook::getLabelForAddress(QString addr) {
return "";
}
+// Get the address for a label
+QString AddressBook::getAddressForLabel(QString label) {
+ for (auto i: allLabels) {
+ if (i.first == label)
+ return i.second;
+ }
+
+ return "";
+}
+
QString AddressBook::addLabelToAddress(QString addr) {
QString label = AddressBook::getInstance()->getLabelForAddress(addr);
if (!label.isEmpty())
diff --git a/src/addressbook.h b/src/addressbook.h
index 41f9ff9..af64c07 100644
--- a/src/addressbook.h
+++ b/src/addressbook.h
@@ -10,9 +10,9 @@ class AddressBookModel : public QAbstractTableModel {
public:
AddressBookModel(QTableView* parent);
~AddressBookModel();
-
- void addNewLabel(QString label, QString addr);
- void removeItemAt(int row);
+
+ void addNewLabel(QString label, QString addr);
+ void removeItemAt(int row);
QPair itemAt(int row);
int rowCount(const QModelIndex &parent) const;
@@ -52,6 +52,8 @@ public:
// Get an address's first label
QString getLabelForAddress(QString address);
+ // Get a Label's address
+ QString getAddressForLabel(QString label);
private:
AddressBook();
diff --git a/src/addressbook.ui b/src/addressbook.ui
index 946fb13..a20ee8f 100644
--- a/src/addressbook.ui
+++ b/src/addressbook.ui
@@ -23,7 +23,7 @@
-
- Address
+ Address (z-Addr or t-Addr)
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index c285882..279068b 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1,5 +1,7 @@
#include "mainwindow.h"
#include "addressbook.h"
+#include "viewalladdresses.h"
+#include "validateaddress.h"
#include "ui_mainwindow.h"
#include "ui_mobileappconnector.h"
#include "ui_addressbook.h"
@@ -9,6 +11,8 @@
#include "ui_settings.h"
#include "ui_turnstile.h"
#include "ui_turnstileprogress.h"
+#include "ui_viewalladdresses.h"
+#include "ui_validateaddress.h"
#include "rpc.h"
#include "balancestablemodel.h"
#include "settings.h"
@@ -75,6 +79,9 @@ MainWindow::MainWindow(QWidget *parent) :
// z-Board.net
QObject::connect(ui->actionz_board_net, &QAction::triggered, this, &MainWindow::postToZBoard);
+ // Validate Address
+ QObject::connect(ui->actionValidate_Address, &QAction::triggered, this, &MainWindow::validateAddress);
+
// Connect mobile app
QObject::connect(ui->actionConnect_Mobile_App, &QAction::triggered, this, [=] () {
if (rpc->getConnection() == nullptr)
@@ -109,7 +116,7 @@ MainWindow::MainWindow(QWidget *parent) :
setupSendTab();
setupTransactionsTab();
- setupRecieveTab();
+ setupReceiveTab();
setupBalancesTab();
setupTurnstileDialog();
setupZcashdTab();
@@ -628,6 +635,48 @@ void MainWindow::donate() {
ui->tabWidget->setCurrentIndex(1);
}
+/**
+ * Validate an address
+ */
+void MainWindow::validateAddress() {
+ // Make sure everything is up and running
+ if (!getRPC() || !getRPC()->getConnection())
+ return;
+
+ // First thing is ask the user for an address
+ bool ok;
+ auto address = QInputDialog::getText(this, tr("Enter Address to validate"),
+ tr("Transparent or Shielded Address:") + QString(" ").repeated(140), // Pad the label so the dialog box is wide enough
+ QLineEdit::Normal, "", &ok);
+ if (!ok)
+ return;
+
+ getRPC()->validateAddress(address, [=] (json props) {
+ QDialog d(this);
+ Ui_ValidateAddress va;
+ va.setupUi(&d);
+ Settings::saveRestore(&d);
+ Settings::saveRestoreTableHeader(va.tblProps, &d, "validateaddressprops");
+ va.tblProps->horizontalHeader()->setStretchLastSection(true);
+
+ va.lblAddress->setText(address);
+
+ QList> propsList;
+ for (auto it = props.begin(); it != props.end(); it++) {
+
+ propsList.append(
+ QPair(
+ QString::fromStdString(it.key()), QString::fromStdString(it.value().dump()))
+ );
+ }
+
+ ValidateAddressesModel model(va.tblProps, propsList);
+ va.tblProps->setModel(&model);
+
+ d.exec();
+ });
+
+}
void MainWindow::postToZBoard() {
QDialog d(this);
@@ -827,7 +876,7 @@ void MainWindow::payZcashURI(QString uri, QString myAddr) {
return;
// Extract the address
- qDebug() << "Recieved URI " << uri;
+ qDebug() << "Received URI " << uri;
PaymentURI paymentInfo = Settings::parseURI(uri);
if (!paymentInfo.error.isEmpty()) {
QMessageBox::critical(this, tr("Error paying pirate URI"),
@@ -1238,7 +1287,6 @@ void MainWindow::setupTransactionsTab() {
}
void MainWindow::addNewZaddr(bool sapling) {
-
rpc->newZaddr(sapling, [=] (json reply) {
QString addr = QString::fromStdString(reply.get());
// Make sure the RPC class reloads the z-addrs for future use
@@ -1246,8 +1294,8 @@ void MainWindow::addNewZaddr(bool sapling) {
// Just double make sure the z-address is still checked
if ( sapling && ui->rdioZSAddr->isChecked() ) {
- ui->listRecieveAddresses->insertItem(0, addr);
- ui->listRecieveAddresses->setCurrentIndex(0);
+ ui->listReceiveAddresses->insertItem(0, addr);
+ ui->listReceiveAddresses->setCurrentIndex(0);
ui->statusBar->showMessage(QString::fromStdString("Created new zAddr") %
(sapling ? "(Sapling)" : "(Sprout)"),
@@ -1263,14 +1311,14 @@ std::function MainWindow::addZAddrsToComboList(bool sapling) {
return [=] (bool checked) {
if (checked && this->rpc->getAllZAddresses() != nullptr) {
auto addrs = this->rpc->getAllZAddresses();
- ui->listRecieveAddresses->clear();
+ ui->listReceiveAddresses->clear();
std::for_each(addrs->begin(), addrs->end(), [=] (auto addr) {
if ( (sapling && Settings::getInstance()->isSaplingAddress(addr)) ||
(!sapling && !Settings::getInstance()->isSaplingAddress(addr))) {
if (rpc->getAllBalances()) {
auto bal = rpc->getAllBalances()->value(addr);
- ui->listRecieveAddresses->addItem(addr, bal);
+ ui->listReceiveAddresses->addItem(addr, bal);
}
}
});
@@ -1283,15 +1331,17 @@ std::function MainWindow::addZAddrsToComboList(bool sapling) {
};
}
-void MainWindow::setupRecieveTab() {
+void MainWindow::setupReceiveTab() {
auto addNewTAddr = [=] () {
rpc->newTaddr([=] (json reply) {
QString addr = QString::fromStdString(reply.get());
+ // Make sure the RPC class reloads the t-addrs for future use
+ rpc->refreshAddresses();
// Just double make sure the t-address is still checked
if (ui->rdioTAddr->isChecked()) {
- ui->listRecieveAddresses->insertItem(0, addr);
- ui->listRecieveAddresses->setCurrentIndex(0);
+ ui->listReceiveAddresses->insertItem(0, addr);
+ ui->listReceiveAddresses->setCurrentIndex(0);
ui->statusBar->showMessage(tr("Created new t-Addr"), 10 * 1000);
}
@@ -1304,14 +1354,58 @@ void MainWindow::setupRecieveTab() {
// want to reuse t-addrs
if (checked && this->rpc->getUTXOs() != nullptr) {
updateTAddrCombo(checked);
- addNewTAddr();
}
+
+ // Toggle the "View all addresses" button as well
+ ui->btnViewAllAddresses->setVisible(checked);
+ });
+
+ // View all addresses goes to "View all private keys"
+ QObject::connect(ui->btnViewAllAddresses, &QPushButton::clicked, [=] () {
+ // If there's no RPC, return
+ if (!getRPC())
+ return;
+
+ QDialog d(this);
+ Ui_ViewAddressesDialog viewaddrs;
+ viewaddrs.setupUi(&d);
+ Settings::saveRestore(&d);
+ Settings::saveRestoreTableHeader(viewaddrs.tblAddresses, &d, "viewalladdressestable");
+ viewaddrs.tblAddresses->horizontalHeader()->setStretchLastSection(true);
+
+ ViewAllAddressesModel model(viewaddrs.tblAddresses, *getRPC()->getAllTAddresses(), getRPC());
+ viewaddrs.tblAddresses->setModel(&model);
+
+ QObject::connect(viewaddrs.btnExportAll, &QPushButton::clicked, this, &MainWindow::exportAllKeys);
+
+ viewaddrs.tblAddresses->setContextMenuPolicy(Qt::CustomContextMenu);
+ QObject::connect(viewaddrs.tblAddresses, &QTableView::customContextMenuRequested, [=] (QPoint pos) {
+ QModelIndex index = viewaddrs.tblAddresses->indexAt(pos);
+ if (index.row() < 0) return;
+
+ index = index.sibling(index.row(), 0);
+ QString addr = viewaddrs.tblAddresses->model()->data(index).toString();
+
+ QMenu menu(this);
+ menu.addAction(tr("Export Private Key"), [=] () {
+ if (addr.isEmpty())
+ return;
+
+ this->exportKeys(addr);
+ });
+ menu.addAction(tr("Copy Address"), [=]() {
+ QGuiApplication::clipboard()->setText(addr);
+ });
+ menu.exec(viewaddrs.tblAddresses->viewport()->mapToGlobal(pos));
+ });
+
+ d.exec();
});
QObject::connect(ui->rdioZSAddr, &QRadioButton::toggled, addZAddrsToComboList(true));
// Explicitly get new address button.
- QObject::connect(ui->btnRecieveNewAddr, &QPushButton::clicked, [=] () {
+ QObject::connect(ui->btnReceiveNewAddr, &QPushButton::clicked, [=] () {
if (!rpc->getConnection())
return;
@@ -1327,9 +1421,10 @@ void MainWindow::setupRecieveTab() {
if (tab == 2) {
// Switched to receive tab, select the z-addr radio button
ui->rdioZSAddr->setChecked(true);
+ ui->btnViewAllAddresses->setVisible(false);
// And then select the first one
- ui->listRecieveAddresses->setCurrentIndex(0);
+ ui->listReceiveAddresses->setCurrentIndex(0);
}
});
@@ -1338,15 +1433,15 @@ void MainWindow::setupRecieveTab() {
ui->rcvLabel->setValidator(v);
// Select item in address list
- QObject::connect(ui->listRecieveAddresses,
+ QObject::connect(ui->listReceiveAddresses,
QOverload::of(&QComboBox::currentIndexChanged), [=] (int index) {
- QString addr = ui->listRecieveAddresses->itemText(index);
+ QString addr = ui->listReceiveAddresses->itemText(index);
if (addr.isEmpty()) {
// Draw empty stuff
ui->rcvLabel->clear();
ui->rcvBal->clear();
- ui->txtRecieve->clear();
+ ui->txtReceive->clear();
ui->qrcodeDisplay->clear();
return;
}
@@ -1361,7 +1456,7 @@ void MainWindow::setupRecieveTab() {
ui->rcvLabel->setText(label);
ui->rcvBal->setText(Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(addr)));
- ui->txtRecieve->setPlainText(addr);
+ ui->txtReceive->setPlainText(addr);
ui->qrcodeDisplay->setQrcodeString(addr);
if (rpc->getUsedAddresses()->value(addr, false)) {
ui->rcvBal->setToolTip(tr("Address has been previously used"));
@@ -1373,7 +1468,7 @@ void MainWindow::setupRecieveTab() {
// Receive tab add/update label
QObject::connect(ui->rcvUpdateLabel, &QPushButton::clicked, [=]() {
- QString addr = ui->listRecieveAddresses->currentText();
+ QString addr = ui->listReceiveAddresses->currentText();
if (addr.isEmpty())
return;
@@ -1407,9 +1502,9 @@ void MainWindow::setupRecieveTab() {
}
});
- // Recieve Export Key
+ // Receive Export Key
QObject::connect(ui->exportKey, &QPushButton::clicked, [=]() {
- QString addr = ui->listRecieveAddresses->currentText();
+ QString addr = ui->listReceiveAddresses->currentText();
if (addr.isEmpty())
return;
@@ -1417,16 +1512,17 @@ void MainWindow::setupRecieveTab() {
});
}
+
void MainWindow::updateTAddrCombo(bool checked) {
if (checked) {
auto utxos = this->rpc->getUTXOs();
- ui->listRecieveAddresses->clear();
+ ui->listReceiveAddresses->clear();
std::for_each(utxos->begin(), utxos->end(), [=](auto& utxo) {
auto addr = utxo.address;
- if (addr.startsWith("R") && ui->listRecieveAddresses->findText(addr) < 0) {
+ if (addr.startsWith("R") && ui->listReceiveAddresses->findText(addr) < 0) {
auto bal = rpc->getAllBalances()->value(addr);
- ui->listRecieveAddresses->addItem(addr, bal);
+ ui->listReceiveAddresses->addItem(addr, bal);
}
});
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 9a1971d..7a14fa3 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -56,6 +56,8 @@ public:
void balancesReady();
void payZcashURI(QString uri = "", QString myAddr = "");
+ void validateAddress();
+
void updateLabels();
void updateTAddrCombo(bool checked);
void updateFromCombo();
@@ -76,7 +78,7 @@ private:
void setupSendTab();
void setupTransactionsTab();
- void setupRecieveTab();
+ void setupReceiveTab();
void setupBalancesTab();
void setupZcashdTab();
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index b11eb6d..34eb4db 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -756,7 +756,7 @@
-
-
-
+
0
@@ -769,12 +769,19 @@
-
-
+
New Address
+ -
+
+
+ View All Addresses
+
+
+
@@ -825,7 +832,7 @@
-
-
+
0
@@ -1335,6 +1342,7 @@
&Apps
+
@@ -1451,6 +1459,11 @@
Request HUSH...
+
+
+ Validate Address
+
+
@@ -1483,9 +1496,9 @@
cancelSendButton
rdioZSAddr
rdioTAddr
- listRecieveAddresses
- btnRecieveNewAddr
- txtRecieve
+ listReceiveAddresses
+ btnReceiveNewAddr
+ txtReceive
rcvLabel
rcvUpdateLabel
transactionsTable
diff --git a/src/precompiled.h b/src/precompiled.h
index 5745182..79c4c8b 100644
--- a/src/precompiled.h
+++ b/src/precompiled.h
@@ -24,6 +24,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
diff --git a/src/privkey.ui b/src/privkey.ui
index 9fe3760..57bdb16 100644
--- a/src/privkey.ui
+++ b/src/privkey.ui
@@ -11,7 +11,7 @@
- Private Key
+ Private Keys
-
diff --git a/src/rpc.cpp b/src/rpc.cpp
index cdd727d..64e09e8 100644
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -230,6 +230,18 @@ void RPC::importTPrivKey(QString privkey, bool rescan, const std::functiondoRPCWithDefaultErrorHandling(payload, cb);
}
+void RPC::validateAddress(QString address, const std::function& cb) {
+ QString method = address.startsWith("z") ? "z_validateaddress" : "validateaddress";
+
+ json payload = {
+ {"jsonrpc", "1.0"},
+ {"id", "someid"},
+ {"method", method.toStdString() },
+ {"params", { address.toStdString() } },
+ };
+
+ conn->doRPCWithDefaultErrorHandling(payload, cb);
+}
void RPC::getBalance(const std::function& cb) {
json payload = {
diff --git a/src/rpc.h b/src/rpc.h
index 3b95a71..48193ee 100644
--- a/src/rpc.h
+++ b/src/rpc.h
@@ -75,6 +75,7 @@ public:
void getTPrivKey(QString addr, const std::function& cb);
void importZPrivKey(QString addr, bool rescan, const std::function& cb);
void importTPrivKey(QString addr, bool rescan, const std::function& cb);
+ void validateAddress(QString address, const std::function& cb);
void shutdownZcashd();
void noConnection();
diff --git a/src/settings.cpp b/src/settings.cpp
index 27499a7..b8e4891 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -40,6 +40,15 @@ void Settings::saveSettings(const QString& host, const QString& port, const QStr
init();
}
+void Settings::saveRestoreTableHeader(QTableView* table, QDialog* d, QString tablename) {
+ table->horizontalHeader()->restoreState(QSettings().value(tablename).toByteArray());
+ table->horizontalHeader()->setStretchLastSection(true);
+
+ QObject::connect(d, &QDialog::finished, [=](auto) {
+ QSettings().setValue(tablename, table->horizontalHeader()->saveState());
+ });
+}
+
void Settings::setUsingZcashConf(QString confLocation) {
if (!confLocation.isEmpty())
_confLocation = confLocation;
diff --git a/src/settings.h b/src/settings.h
index e72434e..fb289cc 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -76,6 +76,7 @@ public:
static const QString txidStatusMessage;
static void saveRestore(QDialog* d);
+ static void saveRestoreTableHeader(QTableView* table, QDialog* d, QString tablename) ;
static PaymentURI parseURI(QString paymentURI);
static QString paymentURIPretty(PaymentURI);
diff --git a/src/validateaddress.cpp b/src/validateaddress.cpp
new file mode 100644
index 0000000..d82e82e
--- /dev/null
+++ b/src/validateaddress.cpp
@@ -0,0 +1,37 @@
+#include "validateaddress.h"
+
+
+ValidateAddressesModel::ValidateAddressesModel(QTableView *parent, QList> props)
+ : QAbstractTableModel(parent) {
+ headers << tr("Property") << tr("Value");
+ this->props = props;
+}
+
+
+int ValidateAddressesModel::rowCount(const QModelIndex&) const {
+ return props.size();
+}
+
+int ValidateAddressesModel::columnCount(const QModelIndex&) const {
+ return headers.size();
+}
+
+QVariant ValidateAddressesModel::data(const QModelIndex &index, int role) const {
+ QPair p = props.at(index.row());
+ if (role == Qt::DisplayRole) {
+ switch(index.column()) {
+ case 0: return p.first;
+ case 1: return p.second;
+ }
+ }
+ return QVariant();
+}
+
+
+QVariant ValidateAddressesModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ return headers.at(section);
+ }
+
+ return QVariant();
+}
diff --git a/src/validateaddress.h b/src/validateaddress.h
new file mode 100644
index 0000000..19db4cb
--- /dev/null
+++ b/src/validateaddress.h
@@ -0,0 +1,23 @@
+#ifndef VALIDATEADDRESS_H
+#define VALIDATEADDRESS_H
+
+#include "precompiled.h"
+
+class ValidateAddressesModel : public QAbstractTableModel {
+
+public:
+ ValidateAddressesModel(QTableView* parent, QList> props);
+ ~ValidateAddressesModel() = default;
+
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+private:
+ QList> props;
+ QStringList headers;
+};
+
+
+#endif // VALIDATEADDRESS_H
diff --git a/src/validateaddress.ui b/src/validateaddress.ui
new file mode 100644
index 0000000..20caebb
--- /dev/null
+++ b/src/validateaddress.ui
@@ -0,0 +1,85 @@
+
+
+ ValidateAddress
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ Validate Address
+
+
+
-
+
+
+ TextLabel
+
+
+
+ -
+
+
+ Address:
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ ValidateAddress
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ ValidateAddress
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/viewalladdresses.cpp b/src/viewalladdresses.cpp
new file mode 100644
index 0000000..7b7af7d
--- /dev/null
+++ b/src/viewalladdresses.cpp
@@ -0,0 +1,38 @@
+#include "viewalladdresses.h"
+#include "settings.h"
+
+ViewAllAddressesModel::ViewAllAddressesModel(QTableView *parent, QList taddrs, RPC* rpc)
+ : QAbstractTableModel(parent) {
+ headers << tr("Address") << tr("Balance (%1)").arg(Settings::getTokenName());
+ addresses = taddrs;
+ this->rpc = rpc;
+}
+
+
+int ViewAllAddressesModel::rowCount(const QModelIndex&) const {
+ return addresses.size();
+}
+
+int ViewAllAddressesModel::columnCount(const QModelIndex&) const {
+ return headers.size();
+}
+
+QVariant ViewAllAddressesModel::data(const QModelIndex &index, int role) const {
+ QString address = addresses.at(index.row());
+ if (role == Qt::DisplayRole) {
+ switch(index.column()) {
+ case 0: return address;
+ case 1: return rpc->getAllBalances()->value(address, 0.0);
+ }
+ }
+ return QVariant();
+}
+
+
+QVariant ViewAllAddressesModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ return headers.at(section);
+ }
+
+ return QVariant();
+}
diff --git a/src/viewalladdresses.h b/src/viewalladdresses.h
new file mode 100644
index 0000000..4e9e3d4
--- /dev/null
+++ b/src/viewalladdresses.h
@@ -0,0 +1,24 @@
+#ifndef VIEWALLADDRESSES_H
+#define VIEWALLADDRESSES_H
+
+#include "precompiled.h"
+#include "rpc.h"
+
+class ViewAllAddressesModel : public QAbstractTableModel {
+
+public:
+ ViewAllAddressesModel(QTableView* parent, QList taddrs, RPC* rpc);
+ ~ViewAllAddressesModel() = default;
+
+ int rowCount(const QModelIndex &parent) const;
+ int columnCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+private:
+ QList addresses;
+ QStringList headers;
+ RPC* rpc;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/viewalladdresses.ui b/src/viewalladdresses.ui
new file mode 100644
index 0000000..fae5ecf
--- /dev/null
+++ b/src/viewalladdresses.ui
@@ -0,0 +1,81 @@
+
+
+ ViewAddressesDialog
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ All Addresses
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Ok
+
+
+
+ -
+
+
+ Export All Keys
+
+
+
+ -
+
+
+ QAbstractItemView::SingleSelection
+
+
+ true
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ ViewAddressesDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ ViewAddressesDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+