1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,3 +40,4 @@ silentdragonlite.pro.user.4.10-pre1
|
|||||||
silentdragonlite
|
silentdragonlite
|
||||||
silentdragonlite_plugin_import.cpp
|
silentdragonlite_plugin_import.cpp
|
||||||
silentdragonlite_resource.rc
|
silentdragonlite_resource.rc
|
||||||
|
SilentDragonLite
|
||||||
@@ -6,85 +6,99 @@
|
|||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
|
||||||
|
|
||||||
AddressBookModel::AddressBookModel(QTableView *parent)
|
AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent)
|
||||||
: QAbstractTableModel(parent) {
|
{
|
||||||
headers << tr("Label") << tr("Address");
|
headers << tr("Label") << tr("Address");
|
||||||
|
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressBookModel::~AddressBookModel() {
|
AddressBookModel::~AddressBookModel()
|
||||||
|
{
|
||||||
saveData();
|
saveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookModel::saveData() {
|
void AddressBookModel::saveData()
|
||||||
|
{
|
||||||
// Save column positions
|
// Save column positions
|
||||||
QSettings().setValue("addresstablegeometry", parent->horizontalHeader()->saveState());
|
QSettings().setValue(
|
||||||
|
"addresstablegeometry",
|
||||||
|
parent->horizontalHeader()->saveState()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AddressBookModel::loadData() {
|
void AddressBookModel::loadData()
|
||||||
|
{
|
||||||
labels = AddressBook::getInstance()->getAllAddressLabels();
|
labels = AddressBook::getInstance()->getAllAddressLabels();
|
||||||
|
parent->horizontalHeader()->restoreState(
|
||||||
parent->horizontalHeader()->restoreState(QSettings().value("addresstablegeometry").toByteArray());
|
QSettings().value(
|
||||||
|
"addresstablegeometry"
|
||||||
|
).toByteArray()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookModel::addNewLabel(QString label, QString addr) {
|
void AddressBookModel::addNewLabel(QString label, QString addr)
|
||||||
|
{
|
||||||
//labels.push_back(QPair<QString, QString>(label, addr));
|
//labels.push_back(QPair<QString, QString>(label, addr));
|
||||||
AddressBook::getInstance()->addAddressLabel(label, addr);
|
AddressBook::getInstance()->addAddressLabel(label, addr);
|
||||||
|
|
||||||
labels.clear();
|
labels.clear();
|
||||||
labels = AddressBook::getInstance()->getAllAddressLabels();
|
labels = AddressBook::getInstance()->getAllAddressLabels();
|
||||||
|
|
||||||
dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1));
|
dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1));
|
||||||
layoutChanged();
|
layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookModel::removeItemAt(int row) {
|
void AddressBookModel::removeItemAt(int row)
|
||||||
|
{
|
||||||
if (row >= labels.size())
|
if (row >= labels.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AddressBook::getInstance()->removeAddressLabel(labels[row].first, labels[row].second);
|
AddressBook::getInstance()->removeAddressLabel(labels[row].first, labels[row].second);
|
||||||
|
|
||||||
labels.clear();
|
labels.clear();
|
||||||
labels = AddressBook::getInstance()->getAllAddressLabels();
|
labels = AddressBook::getInstance()->getAllAddressLabels();
|
||||||
|
|
||||||
dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1));
|
dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1));
|
||||||
layoutChanged();
|
layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<QString, QString> AddressBookModel::itemAt(int row) {
|
QPair<QString, QString> AddressBookModel::itemAt(int row)
|
||||||
if (row >= labels.size()) return QPair<QString, QString>();
|
{
|
||||||
|
if (row >= labels.size())
|
||||||
|
return QPair<QString, QString>();
|
||||||
|
|
||||||
return labels.at(row);
|
return labels.at(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int AddressBookModel::rowCount(const QModelIndex&) const {
|
int AddressBookModel::rowCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
return labels.size();
|
return labels.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AddressBookModel::columnCount(const QModelIndex&) const {
|
int AddressBookModel::columnCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
return headers.size();
|
return headers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant AddressBookModel::data(const QModelIndex &index, int role) const {
|
QVariant AddressBookModel::data(const QModelIndex &index, int role) const
|
||||||
if (role == Qt::DisplayRole) {
|
{
|
||||||
switch(index.column()) {
|
if (role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
switch(index.column())
|
||||||
|
{
|
||||||
case 0: return labels.at(index.row()).first;
|
case 0: return labels.at(index.row()).first;
|
||||||
case 1: return labels.at(index.row()).second;
|
case 1: return labels.at(index.row()).second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant AddressBookModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
QVariant AddressBookModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
{
|
||||||
|
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
||||||
return headers.at(section);
|
return headers.at(section);
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@@ -93,28 +107,27 @@ QVariant AddressBookModel::headerData(int section, Qt::Orientation orientation,
|
|||||||
//===============
|
//===============
|
||||||
// AddressBook
|
// AddressBook
|
||||||
//===============
|
//===============
|
||||||
void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
void AddressBook::open(MainWindow* parent, QLineEdit* target)
|
||||||
|
{
|
||||||
QDialog d(parent);
|
QDialog d(parent);
|
||||||
Ui_addressBook ab;
|
Ui_addressBook ab;
|
||||||
ab.setupUi(&d);
|
ab.setupUi(&d);
|
||||||
Settings::saveRestore(&d);
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
QRegExpValidator v(QRegExp(Settings::labelRegExp), ab.label);
|
QRegExpValidator v(QRegExp(Settings::labelRegExp), ab.label);
|
||||||
ab.label->setValidator(&v);
|
ab.label->setValidator(&v);
|
||||||
|
|
||||||
AddressBookModel model(ab.addresses);
|
AddressBookModel model(ab.addresses);
|
||||||
ab.addresses->setModel(&model);
|
ab.addresses->setModel(&model);
|
||||||
|
|
||||||
// If there is no target, the we'll call the button "Ok", else "Pick"
|
// If there is no target, the we'll call the button "Ok", else "Pick"
|
||||||
if (target != nullptr) {
|
if (target != nullptr)
|
||||||
ab.buttonBox->button(QDialogButtonBox::Ok)->setText(QObject::tr("Pick"));
|
ab.buttonBox->button(QDialogButtonBox::Ok)->setText(QObject::tr("Pick"));
|
||||||
}
|
|
||||||
|
|
||||||
// Connect the dialog's closing to updating the label address completor
|
// Connect the dialog's closing to updating the label address completor
|
||||||
QObject::connect(&d, &QDialog::finished, [=] (auto) { parent->updateLabels(); });
|
QObject::connect(&d, &QDialog::finished, [=] (auto) { parent->updateLabels(); });
|
||||||
|
|
||||||
// If there is a target then make it the addr for the "Add to" button
|
// If there is a target then make it the addr for the "Add to" button
|
||||||
if (target != nullptr && Settings::isValidAddress(target->text())) {
|
if (target != nullptr && Settings::isValidAddress(target->text()))
|
||||||
|
{
|
||||||
ab.addr->setText(target->text());
|
ab.addr->setText(target->text());
|
||||||
ab.label->setFocus();
|
ab.label->setFocus();
|
||||||
}
|
}
|
||||||
@@ -124,26 +137,37 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
auto addr = ab.addr->text().trimmed();
|
auto addr = ab.addr->text().trimmed();
|
||||||
QString newLabel = ab.label->text();
|
QString newLabel = ab.label->text();
|
||||||
|
|
||||||
if (addr.isEmpty() || newLabel.isEmpty()) {
|
if (addr.isEmpty() || newLabel.isEmpty())
|
||||||
QMessageBox::critical(parent, QObject::tr("Address or Label Error"),
|
{
|
||||||
QObject::tr("Address or Label cannot be empty"), QMessageBox::Ok);
|
QMessageBox::critical(
|
||||||
|
parent,
|
||||||
|
QObject::tr("Address or Label Error"),
|
||||||
|
QObject::tr("Address or Label cannot be empty"),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Test if address is valid.
|
// Test if address is valid.
|
||||||
if (!Settings::isValidAddress(addr)) {
|
if (!Settings::isValidAddress(addr))
|
||||||
QMessageBox::critical(parent, QObject::tr("Address Format Error"),
|
{
|
||||||
QObject::tr("%1 doesn't seem to be a valid hush address.")
|
QMessageBox::critical(
|
||||||
.arg(addr),
|
parent,
|
||||||
QMessageBox::Ok);
|
QObject::tr("Address Format Error"),
|
||||||
|
QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow duplicate address labels.
|
// Don't allow duplicate address labels.
|
||||||
if (!getInstance()->getAddressForLabel(newLabel).isEmpty()) {
|
if (!getInstance()->getAddressForLabel(newLabel).isEmpty())
|
||||||
QMessageBox::critical(parent, QObject::tr("Label Error"),
|
{
|
||||||
QObject::tr("The label '%1' already exists. Please remove the existing label.")
|
QMessageBox::critical(
|
||||||
.arg(newLabel),
|
parent,
|
||||||
QMessageBox::Ok);
|
QObject::tr("Label Error"),
|
||||||
|
QObject::tr("The label '%1' already exists. Please remove the existing label.").arg(newLabel),
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,21 +177,30 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
// Import Button
|
// Import Button
|
||||||
QObject::connect(ab.btnImport, &QPushButton::clicked, [&] () {
|
QObject::connect(ab.btnImport, &QPushButton::clicked, [&] () {
|
||||||
// Get the import file name.
|
// Get the import file name.
|
||||||
auto fileName = QFileDialog::getOpenFileUrl(&d, QObject::tr("Import Address Book"), QUrl(),
|
auto fileName = QFileDialog::getOpenFileUrl(
|
||||||
"CSV file (*.csv)");
|
&d, QObject::tr("Import Address Book"),
|
||||||
|
QUrl(),
|
||||||
|
"CSV file (*.csv)"
|
||||||
|
);
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QFile file(fileName.toLocalFile());
|
QFile file(fileName.toLocalFile());
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
QMessageBox::information(&d, QObject::tr("Unable to open file"), file.errorString());
|
{
|
||||||
|
QMessageBox::information(
|
||||||
|
&d,
|
||||||
|
QObject::tr("Unable to open file"),
|
||||||
|
file.errorString()
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream in(&file);
|
QTextStream in(&file);
|
||||||
QString line;
|
QString line;
|
||||||
int numImported = 0;
|
int numImported = 0;
|
||||||
while (in.readLineInto(&line)) {
|
while (in.readLineInto(&line))
|
||||||
|
{
|
||||||
QStringList items = line.split(",");
|
QStringList items = line.split(",");
|
||||||
if (items.size() != 2)
|
if (items.size() != 2)
|
||||||
continue;
|
continue;
|
||||||
@@ -180,8 +213,11 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
numImported++;
|
numImported++;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox::information(&d, QObject::tr("Address Book Import Done"),
|
QMessageBox::information(
|
||||||
QObject::tr("Imported %1 new Address book entries").arg(numImported));
|
&d,
|
||||||
|
QObject::tr("Address Book Import Done"),
|
||||||
|
QObject::tr("Imported %1 new Address book entries").arg(numImported)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr) {
|
auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr) {
|
||||||
@@ -194,7 +230,8 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
if (!target)
|
if (!target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (index.row() < 0) return;
|
if (index.row() < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
QString lbl = model.itemAt(index.row()).first;
|
QString lbl = model.itemAt(index.row()).first;
|
||||||
QString addr = model.itemAt(index.row()).second;
|
QString addr = model.itemAt(index.row()).second;
|
||||||
@@ -206,20 +243,19 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
ab.addresses->setContextMenuPolicy(Qt::CustomContextMenu);
|
ab.addresses->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
QObject::connect(ab.addresses, &QTableView::customContextMenuRequested, [&] (QPoint pos) {
|
QObject::connect(ab.addresses, &QTableView::customContextMenuRequested, [&] (QPoint pos) {
|
||||||
QModelIndex index = ab.addresses->indexAt(pos);
|
QModelIndex index = ab.addresses->indexAt(pos);
|
||||||
|
if (index.row() < 0)
|
||||||
if (index.row() < 0) return;
|
return;
|
||||||
|
|
||||||
QString lbl = model.itemAt(index.row()).first;
|
QString lbl = model.itemAt(index.row()).first;
|
||||||
QString addr = model.itemAt(index.row()).second;
|
QString addr = model.itemAt(index.row()).second;
|
||||||
|
|
||||||
QMenu menu(parent);
|
QMenu menu(parent);
|
||||||
|
|
||||||
if (target != nullptr) {
|
if (target != nullptr)
|
||||||
menu.addAction("Pick", [&] () {
|
menu.addAction("Pick", [&] () {
|
||||||
d.accept();
|
d.accept();
|
||||||
fnSetTargetLabelAddr(target, lbl, addr);
|
fnSetTargetLabelAddr(target, lbl, addr);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
menu.addAction(QObject::tr("Copy address"), [&] () {
|
menu.addAction(QObject::tr("Copy address"), [&] () {
|
||||||
QGuiApplication::clipboard()->setText(addr);
|
QGuiApplication::clipboard()->setText(addr);
|
||||||
@@ -248,27 +284,30 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
//=============
|
//=============
|
||||||
// AddressBook singleton class
|
// AddressBook singleton class
|
||||||
//=============
|
//=============
|
||||||
AddressBook* AddressBook::getInstance() {
|
AddressBook* AddressBook::getInstance()
|
||||||
|
{
|
||||||
if (!instance)
|
if (!instance)
|
||||||
instance = new AddressBook();
|
instance = new AddressBook();
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressBook::AddressBook() {
|
AddressBook::AddressBook()
|
||||||
|
{
|
||||||
readFromStorage();
|
readFromStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBook::readFromStorage() {
|
void AddressBook::readFromStorage()
|
||||||
|
{
|
||||||
QFile file(AddressBook::writeableFile());
|
QFile file(AddressBook::writeableFile());
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists())
|
||||||
|
{
|
||||||
allLabels.clear();
|
allLabels.clear();
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
QDataStream in(&file); // read the data serialized from the file
|
QDataStream in(&file); // read the data serialized from the file
|
||||||
QString version;
|
QString version;
|
||||||
in >> version >> allLabels;
|
in >> version >> allLabels;
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +321,8 @@ void AddressBook::readFromStorage() {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBook::writeToStorage() {
|
void AddressBook::writeToStorage()
|
||||||
|
{
|
||||||
QFile file(AddressBook::writeableFile());
|
QFile file(AddressBook::writeableFile());
|
||||||
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
||||||
QDataStream out(&file); // we will serialize the data into the file
|
QDataStream out(&file); // we will serialize the data into the file
|
||||||
@@ -290,42 +330,44 @@ void AddressBook::writeToStorage() {
|
|||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressBook::writeableFile() {
|
QString AddressBook::writeableFile()
|
||||||
|
{
|
||||||
auto filename = QStringLiteral("addresslabels.dat");
|
auto filename = QStringLiteral("addresslabels.dat");
|
||||||
|
|
||||||
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||||
if (!dir.exists())
|
if (!dir.exists())
|
||||||
QDir().mkpath(dir.absolutePath());
|
QDir().mkpath(dir.absolutePath());
|
||||||
|
|
||||||
if (Settings::getInstance()->isTestnet()) {
|
if (Settings::getInstance()->isTestnet())
|
||||||
return dir.filePath("testnet-" % filename);
|
return dir.filePath("testnet-" % filename);
|
||||||
} else {
|
|
||||||
|
else
|
||||||
return dir.filePath(filename);
|
return dir.filePath(filename);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add a new address/label to the database
|
// Add a new address/label to the database
|
||||||
void AddressBook::addAddressLabel(QString label, QString address) {
|
void AddressBook::addAddressLabel(QString label, QString address)
|
||||||
|
{
|
||||||
Q_ASSERT(Settings::isValidAddress(address));
|
Q_ASSERT(Settings::isValidAddress(address));
|
||||||
|
|
||||||
// First, remove any existing label
|
// First, remove any existing label
|
||||||
// Iterate over the list and remove the label/address
|
// Iterate over the list and remove the label/address
|
||||||
for (int i=0; i < allLabels.size(); i++) {
|
for (int i=0; i < allLabels.size(); i++)
|
||||||
if (allLabels[i].first == label) {
|
if (allLabels[i].first == label)
|
||||||
removeAddressLabel(allLabels[i].first, allLabels[i].second);
|
removeAddressLabel(allLabels[i].first, allLabels[i].second);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allLabels.push_back(QPair<QString, QString>(label, address));
|
allLabels.push_back(QPair<QString, QString>(label, address));
|
||||||
writeToStorage();
|
writeToStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a new address/label from the database
|
// Remove a new address/label from the database
|
||||||
void AddressBook::removeAddressLabel(QString label, QString address) {
|
void AddressBook::removeAddressLabel(QString label, QString address)
|
||||||
|
{
|
||||||
// Iterate over the list and remove the label/address
|
// Iterate over the list and remove the label/address
|
||||||
for (int i=0; i < allLabels.size(); i++) {
|
for (int i=0; i < allLabels.size(); i++)
|
||||||
if (allLabels[i].first == label && allLabels[i].second == address) {
|
{
|
||||||
|
if (allLabels[i].first == label && allLabels[i].second == address)
|
||||||
|
{
|
||||||
allLabels.removeAt(i);
|
allLabels.removeAt(i);
|
||||||
writeToStorage();
|
writeToStorage();
|
||||||
return;
|
return;
|
||||||
@@ -333,10 +375,13 @@ void AddressBook::removeAddressLabel(QString label, QString address) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBook::updateLabel(QString oldlabel, QString address, QString newlabel) {
|
void AddressBook::updateLabel(QString oldlabel, QString address, QString newlabel)
|
||||||
|
{
|
||||||
// Iterate over the list and update the label/address
|
// Iterate over the list and update the label/address
|
||||||
for (int i = 0; i < allLabels.size(); i++) {
|
for (int i = 0; i < allLabels.size(); i++)
|
||||||
if (allLabels[i].first == oldlabel && allLabels[i].second == address) {
|
{
|
||||||
|
if (allLabels[i].first == oldlabel && allLabels[i].second == address)
|
||||||
|
{
|
||||||
allLabels[i].first = newlabel;
|
allLabels[i].first = newlabel;
|
||||||
writeToStorage();
|
writeToStorage();
|
||||||
return;
|
return;
|
||||||
@@ -345,42 +390,46 @@ void AddressBook::updateLabel(QString oldlabel, QString address, QString newlabe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read all addresses
|
// Read all addresses
|
||||||
const QList<QPair<QString, QString>>& AddressBook::getAllAddressLabels() {
|
const QList<QPair<QString, QString>>& AddressBook::getAllAddressLabels()
|
||||||
if (allLabels.isEmpty()) {
|
{
|
||||||
|
if (allLabels.isEmpty())
|
||||||
readFromStorage();
|
readFromStorage();
|
||||||
}
|
|
||||||
return allLabels;
|
return allLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the label for an address
|
// Get the label for an address
|
||||||
QString AddressBook::getLabelForAddress(QString addr) {
|
QString AddressBook::getLabelForAddress(QString addr)
|
||||||
for (auto i : allLabels) {
|
{
|
||||||
|
for (auto i : allLabels)
|
||||||
if (i.second == addr)
|
if (i.second == addr)
|
||||||
return i.first;
|
return i.first;
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the address for a label
|
// Get the address for a label
|
||||||
QString AddressBook::getAddressForLabel(QString label) {
|
QString AddressBook::getAddressForLabel(QString label)
|
||||||
for (auto i: allLabels) {
|
{
|
||||||
|
for (auto i: allLabels)
|
||||||
if (i.first == label)
|
if (i.first == label)
|
||||||
return i.second;
|
return i.second;
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressBook::addLabelToAddress(QString addr) {
|
QString AddressBook::addLabelToAddress(QString addr)
|
||||||
|
{
|
||||||
QString label = AddressBook::getInstance()->getLabelForAddress(addr);
|
QString label = AddressBook::getInstance()->getLabelForAddress(addr);
|
||||||
if (!label.isEmpty())
|
if (!label.isEmpty())
|
||||||
return label + "/" + addr;
|
return label + "/" + addr;
|
||||||
|
|
||||||
else
|
else
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressBook::addressFromAddressLabel(const QString& lblAddr) {
|
QString AddressBook::addressFromAddressLabel(const QString& lblAddr)
|
||||||
|
{
|
||||||
return lblAddr.trimmed().split("/").last();
|
return lblAddr.trimmed().split("/").last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,29 +2,31 @@
|
|||||||
#include "addressbook.h"
|
#include "addressbook.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
AddressCombo::AddressCombo(QWidget* parent) :
|
AddressCombo::AddressCombo(QWidget* parent): QComboBox(parent)
|
||||||
QComboBox(parent) {
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
QString AddressCombo::itemText(int i) {
|
QString AddressCombo::itemText(int i)
|
||||||
|
{
|
||||||
QString txt = QComboBox::itemText(i);
|
QString txt = QComboBox::itemText(i);
|
||||||
return AddressBook::addressFromAddressLabel(txt.split("(")[0].trimmed());
|
return AddressBook::addressFromAddressLabel(txt.split("(")[0].trimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressCombo::currentText() {
|
QString AddressCombo::currentText()
|
||||||
|
{
|
||||||
QString txt = QComboBox::currentText();
|
QString txt = QComboBox::currentText();
|
||||||
return AddressBook::addressFromAddressLabel(txt.split("(")[0].trimmed());
|
return AddressBook::addressFromAddressLabel(txt.split("(")[0].trimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressCombo::setCurrentText(const QString& text) {
|
void AddressCombo::setCurrentText(const QString& text)
|
||||||
for (int i=0; i < count(); i++) {
|
{
|
||||||
if (itemText(i) == text) {
|
for (int i=0; i < count(); i++)
|
||||||
|
if (itemText(i) == text)
|
||||||
QComboBox::setCurrentIndex(i);
|
QComboBox::setCurrentIndex(i);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressCombo::addItem(const QString& text, CAmount bal) {
|
void AddressCombo::addItem(const QString& text, CAmount bal)
|
||||||
|
{
|
||||||
QString txt = AddressBook::addLabelToAddress(text);
|
QString txt = AddressBook::addLabelToAddress(text);
|
||||||
if (bal.toqint64() > 0)
|
if (bal.toqint64() > 0)
|
||||||
txt = txt % "(" % bal.toDecimalhushString() % ")";
|
txt = txt % "(" % bal.toDecimalhushString() % ")";
|
||||||
@@ -32,7 +34,8 @@ void AddressCombo::addItem(const QString& text, CAmount bal) {
|
|||||||
QComboBox::addItem(txt);
|
QComboBox::addItem(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressCombo::insertItem(int index, const QString& text, CAmount bal) {
|
void AddressCombo::insertItem(int index, const QString& text, CAmount bal)
|
||||||
|
{
|
||||||
QString txt = AddressBook::addLabelToAddress(text) %
|
QString txt = AddressBook::addLabelToAddress(text) %
|
||||||
"(" % bal.toDecimalhushString() % ")";
|
"(" % bal.toDecimalhushString() % ")";
|
||||||
QComboBox::insertItem(index, txt);
|
QComboBox::insertItem(index, txt);
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "camount.h"
|
#include "camount.h"
|
||||||
|
|
||||||
BalancesTableModel::BalancesTableModel(QObject *parent)
|
BalancesTableModel::BalancesTableModel(QObject *parent): QAbstractTableModel(parent)
|
||||||
: QAbstractTableModel(parent) {
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QString> taddrs,
|
void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QString> taddrs,
|
||||||
const QMap<QString, CAmount> balances, const QList<UnspentOutput> outputs)
|
const QMap<QString, CAmount> balances, const QList<UnspentOutput> outputs)
|
||||||
@@ -29,21 +28,19 @@ void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QSt
|
|||||||
modeldata = new QList<std::tuple<QString, CAmount>>();
|
modeldata = new QList<std::tuple<QString, CAmount>>();
|
||||||
std::for_each(balances.keyBegin(), balances.keyEnd(), [=, &anyz, &anyt] (auto keyIt) {
|
std::for_each(balances.keyBegin(), balances.keyEnd(), [=, &anyz, &anyt] (auto keyIt) {
|
||||||
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
||||||
if (Settings::isZAddress(keyIt)) {
|
if (Settings::isZAddress(keyIt))
|
||||||
anyz = true;
|
anyz = true;
|
||||||
} else if (Settings::isTAddress(keyIt)) {
|
|
||||||
|
else if (Settings::isTAddress(keyIt))
|
||||||
anyt = true;
|
anyt = true;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add all addresses that have no balances, if there are no existing addresses
|
// Add all addresses that have no balances, if there are no existing addresses
|
||||||
if (!anyz && zaddrs.length() > 0) {
|
if (!anyz && zaddrs.length() > 0)
|
||||||
modeldata->push_back(std::make_tuple(zaddrs[0], CAmount::fromqint64(0)));
|
modeldata->push_back(std::make_tuple(zaddrs[0], CAmount::fromqint64(0)));
|
||||||
}
|
|
||||||
|
|
||||||
if (!anyt && taddrs.length() > 0) {
|
if (!anyt && taddrs.length() > 0)
|
||||||
modeldata->push_back(std::make_tuple(taddrs[0], CAmount::fromqint64(0)));
|
modeldata->push_back(std::make_tuple(taddrs[0], CAmount::fromqint64(0)));
|
||||||
}
|
|
||||||
|
|
||||||
// And then update the data
|
// And then update the data
|
||||||
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
|
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
|
||||||
@@ -53,19 +50,17 @@ void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QSt
|
|||||||
layoutChanged();
|
layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
BalancesTableModel::~BalancesTableModel() {
|
BalancesTableModel::~BalancesTableModel()
|
||||||
|
{
|
||||||
delete modeldata;
|
delete modeldata;
|
||||||
delete unspentOutputs;
|
delete unspentOutputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BalancesTableModel::rowCount(const QModelIndex&) const
|
int BalancesTableModel::rowCount(const QModelIndex&) const
|
||||||
{
|
{
|
||||||
if (modeldata == nullptr) {
|
if (modeldata == nullptr)
|
||||||
if (loading)
|
return (loading) ? 1: 0;
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return modeldata->size();
|
return modeldata->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,25 +71,31 @@ int BalancesTableModel::columnCount(const QModelIndex&) const
|
|||||||
|
|
||||||
QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading)
|
||||||
if (role == Qt::DisplayRole)
|
return (role == Qt::DisplayRole) ? "Loading..." : QVariant();
|
||||||
|
/*if (role == Qt::DisplayRole)
|
||||||
return "Loading...";
|
return "Loading...";
|
||||||
else
|
else
|
||||||
return QVariant();
|
return QVariant();*/
|
||||||
}
|
|
||||||
|
|
||||||
if (role == Qt::TextAlignmentRole && index.column() == 1) return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
if (role == Qt::TextAlignmentRole && index.column() == 1)
|
||||||
|
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||||
|
|
||||||
if (role == Qt::ForegroundRole) {
|
if (role == Qt::ForegroundRole) {
|
||||||
// If any of the UTXOs for this address has zero confirmations, paint it in red
|
// If any of the UTXOs for this address has zero confirmations, paint it in red
|
||||||
const auto& addr = std::get<0>(modeldata->at(index.row()));
|
const auto& addr = std::get<0>(modeldata->at(index.row()));
|
||||||
for (auto unconfirmedOutput : *unspentOutputs) {
|
for (auto unconfirmedOutput : *unspentOutputs)
|
||||||
if (unconfirmedOutput.address == addr &&
|
{
|
||||||
(!unconfirmedOutput.spendable || unconfirmedOutput.pending)) {
|
if (
|
||||||
|
unconfirmedOutput.address == addr &&
|
||||||
|
(!unconfirmedOutput.spendable || unconfirmedOutput.pending)
|
||||||
|
)
|
||||||
|
{
|
||||||
QBrush b;
|
QBrush b;
|
||||||
b.setColor(Qt::red);
|
b.setColor(Qt::red);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else, just return the default brush
|
// Else, just return the default brush
|
||||||
@@ -103,17 +104,21 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole)
|
||||||
switch (index.column()) {
|
{
|
||||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
switch (index.column())
|
||||||
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalhushString();
|
{
|
||||||
|
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||||
|
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalhushString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(role == Qt::ToolTipRole) {
|
if(role == Qt::ToolTipRole)
|
||||||
switch (index.column()) {
|
{
|
||||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
switch (index.column())
|
||||||
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalhushString();
|
{
|
||||||
|
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||||
|
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalhushString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +128,13 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
QVariant BalancesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant BalancesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
if (role == Qt::TextAlignmentRole && section == 1) {
|
if (role == Qt::TextAlignmentRole && section == 1)
|
||||||
|
{
|
||||||
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
return QVariant(Qt::AlignRight | Qt::AlignVCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == Qt::FontRole) {
|
if (role == Qt::FontRole)
|
||||||
|
{
|
||||||
QFont f;
|
QFont f;
|
||||||
f.setBold(true);
|
f.setBold(true);
|
||||||
return f;
|
return f;
|
||||||
@@ -136,13 +143,16 @@ QVariant BalancesTableModel::headerData(int section, Qt::Orientation orientation
|
|||||||
if (role != Qt::DisplayRole)
|
if (role != Qt::DisplayRole)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (orientation == Qt::Horizontal) {
|
if (orientation == Qt::Horizontal)
|
||||||
switch (section) {
|
{
|
||||||
case 0: return tr("Address");
|
switch (section)
|
||||||
case 1: return tr("Amount");
|
{
|
||||||
default: return QVariant();
|
case 0: return tr("Address");
|
||||||
|
case 1: return tr("Amount");
|
||||||
|
default: return QVariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
160
src/camount.cpp
160
src/camount.cpp
@@ -1,204 +1,230 @@
|
|||||||
#include "camount.h"
|
#include "camount.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
const int NUMPLACES = 8;
|
const int NUMPLACES = 8;
|
||||||
const qint64 COIN = 100000000;
|
const qint64 COIN = 100000000;
|
||||||
|
|
||||||
double CAmount::toDecimalDouble() const {
|
double CAmount::toDecimalDouble() const
|
||||||
|
{
|
||||||
return static_cast<double>(this->amount) / COIN;
|
return static_cast<double>(this->amount) / COIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalString() const {
|
QString CAmount::toDecimalString() const
|
||||||
if (amount < 0) {
|
{
|
||||||
|
if (amount < 0)
|
||||||
|
{
|
||||||
CAmount negative(-1 * this->amount);
|
CAmount negative(-1 * this->amount);
|
||||||
return "-" + negative.toDecimalString();
|
return "-" + negative.toDecimalString();
|
||||||
}
|
}
|
||||||
|
|
||||||
int wholePart = amount / COIN;
|
int wholePart = amount / COIN;
|
||||||
int decimalPart = amount % COIN;
|
int decimalPart = amount % COIN;
|
||||||
|
|
||||||
QString r = QString::number(wholePart);
|
QString r = QString::number(wholePart);
|
||||||
if (decimalPart > 0) {
|
if (decimalPart > 0)
|
||||||
|
{
|
||||||
QString decimalPartStr = QString::number(decimalPart);
|
QString decimalPartStr = QString::number(decimalPart);
|
||||||
r = r + "." + decimalPartStr.rightJustified(NUMPLACES, '0');
|
r = r + "." + decimalPartStr.rightJustified(NUMPLACES, '0');
|
||||||
|
|
||||||
// Trim tailing 0s
|
// Trim tailing 0s
|
||||||
while (r.right(1) == "0") {
|
while (r.right(1) == "0")
|
||||||
r = r.left(r.length() - 1);
|
r = r.left(r.length() - 1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalUSDString() const {
|
double CAmount::getDblAmount() const
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
{
|
||||||
|
return static_cast<double>(this->amount) / COIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CAmount::toDecimalUSDString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getZECPrice();
|
double price = Settings::getInstance()->getZECPrice();
|
||||||
|
return "$ " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "$ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalEURString() const {
|
QString CAmount::toDecimalEURString() const
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
{
|
||||||
double price = Settings::getInstance()->getEURPrice();
|
double price = Settings::getInstance()->getEURPrice();
|
||||||
|
return QLocale(QLocale::German).toString(this->getDblAmount() * price, 'f', 2) + " €";
|
||||||
return QLocale(QLocale::German).toString(dblAmount*price, 'f', 2) + " €";
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalBTCString() const {
|
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
QString CAmount::toDecimalBTCString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getBTCPrice();
|
double price = Settings::getInstance()->getBTCPrice();
|
||||||
|
return "BTC " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 9);
|
||||||
return "BTC " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 9);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalCNYString() const {
|
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
QString CAmount::toDecimalCNYString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getCNYPrice();
|
double price = Settings::getInstance()->getCNYPrice();
|
||||||
|
return "¥ /元 " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "¥ /元 " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalRUBString() const {
|
QString CAmount::toDecimalRUBString() const
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
{
|
||||||
double price = Settings::getInstance()->getRUBPrice();
|
double price = Settings::getInstance()->getRUBPrice();
|
||||||
|
return "₽ " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "₽ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalCADString() const {
|
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
QString CAmount::toDecimalCADString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getCADPrice();
|
double price = Settings::getInstance()->getCADPrice();
|
||||||
|
return "$ " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "$ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalSGDString() const {
|
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
QString CAmount::toDecimalSGDString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getSGDPrice();
|
double price = Settings::getInstance()->getSGDPrice();
|
||||||
|
return "$ " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "$ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalCHFString() const {
|
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
QString CAmount::toDecimalCHFString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getCHFPrice();
|
double price = Settings::getInstance()->getCHFPrice();
|
||||||
|
return "CHF " + QLocale(QLocale::German).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "CHF " + QLocale(QLocale::German).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalINRString() const {
|
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
QString CAmount::toDecimalINRString() const
|
||||||
|
{
|
||||||
double price = Settings::getInstance()->getINRPrice();
|
double price = Settings::getInstance()->getINRPrice();
|
||||||
|
return "₹ " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "₹ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalGBPString() const {
|
QString CAmount::toDecimalGBPString() const
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
{
|
||||||
double price = Settings::getInstance()->getGBPPrice();
|
double price = Settings::getInstance()->getGBPPrice();
|
||||||
|
return "£ " + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return "£ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
QString CAmount::toDecimalAUDString() const {
|
QString CAmount::toDecimalAUDString() const
|
||||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
{
|
||||||
double price = Settings::getInstance()->getAUDPrice();
|
double price = Settings::getInstance()->getAUDPrice();
|
||||||
|
return " $" + QLocale(QLocale::English).toString(this->getDblAmount() * price, 'f', 2);
|
||||||
return " $" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushString() const {
|
QString CAmount::toDecimalhushString() const
|
||||||
|
{
|
||||||
return this->toDecimalString() % " " % Settings::getTokenName();
|
return this->toDecimalString() % " " % Settings::getTokenName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushUSDString() const {
|
QString CAmount::toDecimalhushUSDString() const
|
||||||
|
{
|
||||||
auto usdString = this->toDecimalUSDString();
|
auto usdString = this->toDecimalUSDString();
|
||||||
if (!usdString.isEmpty())
|
if (!usdString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % usdString % ")";
|
return this->toDecimalhushString() % " (" % usdString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString CAmount::toDecimalhushEURString() const {
|
QString CAmount::toDecimalhushEURString() const
|
||||||
|
{
|
||||||
auto eurString = this->toDecimalEURString();
|
auto eurString = this->toDecimalEURString();
|
||||||
if (!eurString.isEmpty())
|
if (!eurString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % eurString % ")";
|
return this->toDecimalhushString() % " (" % eurString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushBTCString() const {
|
QString CAmount::toDecimalhushBTCString() const
|
||||||
|
{
|
||||||
auto btcString = this->toDecimalBTCString();
|
auto btcString = this->toDecimalBTCString();
|
||||||
if (!btcString.isEmpty())
|
if (!btcString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % btcString % ")";
|
return this->toDecimalhushString() % " (" % btcString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushCNYString() const {
|
QString CAmount::toDecimalhushCNYString() const
|
||||||
|
{
|
||||||
auto cnyString = this->toDecimalCNYString();
|
auto cnyString = this->toDecimalCNYString();
|
||||||
if (!cnyString.isEmpty())
|
if (!cnyString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % cnyString % ")";
|
return this->toDecimalhushString() % " (" % cnyString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushRUBString() const {
|
QString CAmount::toDecimalhushRUBString() const
|
||||||
|
{
|
||||||
auto rubString = this->toDecimalRUBString();
|
auto rubString = this->toDecimalRUBString();
|
||||||
if (!rubString.isEmpty())
|
if (!rubString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % rubString % ")";
|
return this->toDecimalhushString() % " (" % rubString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushCADString() const {
|
QString CAmount::toDecimalhushCADString() const
|
||||||
|
{
|
||||||
auto cadString = this->toDecimalCADString();
|
auto cadString = this->toDecimalCADString();
|
||||||
if (!cadString.isEmpty())
|
if (!cadString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % cadString % ")";
|
return this->toDecimalhushString() % " (" % cadString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushSGDString() const {
|
QString CAmount::toDecimalhushSGDString() const
|
||||||
|
{
|
||||||
auto sgdString = this->toDecimalSGDString();
|
auto sgdString = this->toDecimalSGDString();
|
||||||
if (!sgdString.isEmpty())
|
if (!sgdString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % sgdString % ")";
|
return this->toDecimalhushString() % " (" % sgdString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushCHFString() const {
|
QString CAmount::toDecimalhushCHFString() const
|
||||||
|
{
|
||||||
auto chfString = this->toDecimalCHFString();
|
auto chfString = this->toDecimalCHFString();
|
||||||
if (!chfString.isEmpty())
|
if (!chfString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % chfString % ")";
|
return this->toDecimalhushString() % " (" % chfString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushINRString() const {
|
QString CAmount::toDecimalhushINRString() const
|
||||||
|
{
|
||||||
auto inrString = this->toDecimalINRString();
|
auto inrString = this->toDecimalINRString();
|
||||||
if (!inrString.isEmpty())
|
if (!inrString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % inrString % ")";
|
return this->toDecimalhushString() % " (" % inrString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushGBPString() const {
|
QString CAmount::toDecimalhushGBPString() const
|
||||||
|
{
|
||||||
auto gbpString = this->toDecimalGBPString();
|
auto gbpString = this->toDecimalGBPString();
|
||||||
if (!gbpString.isEmpty())
|
if (!gbpString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % gbpString % ")";
|
return this->toDecimalhushString() % " (" % gbpString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAmount::toDecimalhushAUDString() const {
|
QString CAmount::toDecimalhushAUDString() const
|
||||||
|
{
|
||||||
auto audString = this->toDecimalAUDString();
|
auto audString = this->toDecimalAUDString();
|
||||||
if (!audString.isEmpty())
|
if (!audString.isEmpty())
|
||||||
return this->toDecimalhushString() % " (" % audString % ")";
|
return this->toDecimalhushString() % " (" % audString % ")";
|
||||||
|
|
||||||
else
|
else
|
||||||
return this->toDecimalhushString();
|
return this->toDecimalhushString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CAmount CAmount::fromDecimalString(QString decimalString) {
|
CAmount CAmount::fromDecimalString(QString decimalString)
|
||||||
|
{
|
||||||
auto amtParts = decimalString.split(".");
|
auto amtParts = decimalString.split(".");
|
||||||
qint64 r = amtParts[0].toULongLong() * COIN;
|
qint64 r = amtParts[0].toULongLong() * COIN;
|
||||||
if (amtParts.length() == 2) {
|
if (amtParts.length() == 2)
|
||||||
|
{
|
||||||
auto trailingZeros = QString("0").repeated(NUMPLACES - amtParts[1].length());
|
auto trailingZeros = QString("0").repeated(NUMPLACES - amtParts[1].length());
|
||||||
r += QString(amtParts[1] + trailingZeros).toULongLong();
|
r += QString(amtParts[1] + trailingZeros).toULongLong();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
|
|
||||||
double toDecimalDouble() const;
|
double toDecimalDouble() const;
|
||||||
QString toDecimalString() const;
|
QString toDecimalString() const;
|
||||||
|
double getDblAmount() const;
|
||||||
QString toDecimalUSDString() const;
|
QString toDecimalUSDString() const;
|
||||||
QString toDecimalEURString() const;
|
QString toDecimalEURString() const;
|
||||||
QString toDecimalBTCString() const;
|
QString toDecimalBTCString() const;
|
||||||
|
|||||||
@@ -5,42 +5,47 @@
|
|||||||
#include "firsttimewizard.h"
|
#include "firsttimewizard.h"
|
||||||
#include "ui_createhushconfdialog.h"
|
#include "ui_createhushconfdialog.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../lib/silentdragonlitelib.h"
|
#include "../lib/silentdragonlitelib.h"
|
||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc) {
|
ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc)
|
||||||
|
{
|
||||||
this->main = main;
|
this->main = main;
|
||||||
this->rpc = rpc;
|
this->rpc = rpc;
|
||||||
|
|
||||||
d = new QDialog(main);
|
d = new QDialog(main);
|
||||||
connD = new Ui_ConnectionDialog();
|
connD = new Ui_ConnectionDialog();
|
||||||
connD->setupUi(d);
|
connD->setupUi(d);
|
||||||
QPixmap logo(":/img/res/logobig.gif");
|
QPixmap logo(":/img/res/logobig.gif");
|
||||||
connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
connD->topIcon->setBasePixmap(
|
||||||
|
logo.scaled(
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
Qt::KeepAspectRatio,
|
||||||
|
Qt::SmoothTransformation
|
||||||
|
)
|
||||||
|
);
|
||||||
isSyncing = new QAtomicInteger<bool>();
|
isSyncing = new QAtomicInteger<bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionLoader::~ConnectionLoader() {
|
ConnectionLoader::~ConnectionLoader()
|
||||||
|
{
|
||||||
delete isSyncing;
|
delete isSyncing;
|
||||||
delete connD;
|
delete connD;
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionLoader::loadConnection() {
|
void ConnectionLoader::loadConnection()
|
||||||
|
{
|
||||||
QTimer::singleShot(1, [=]() { this->doAutoConnect(); });
|
QTimer::singleShot(1, [=]() { this->doAutoConnect(); });
|
||||||
if (!Settings::getInstance()->isHeadless())
|
if (!Settings::getInstance()->isHeadless())
|
||||||
d->exec();
|
d->exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionLoader::doAutoConnect() {
|
void ConnectionLoader::doAutoConnect()
|
||||||
|
{
|
||||||
qDebug() << "Doing autoconnect";
|
qDebug() << "Doing autoconnect";
|
||||||
|
|
||||||
auto config = std::shared_ptr<ConnectionConfig>(new ConnectionConfig());
|
auto config = std::shared_ptr<ConnectionConfig>(new ConnectionConfig());
|
||||||
config->dangerous = true;
|
config->dangerous = true;
|
||||||
config->server = Settings::getInstance()->getSettings().server;
|
config->server = Settings::getInstance()->getSettings().server;
|
||||||
@@ -49,16 +54,24 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
main->logger->write(QObject::tr("Attempting to initialize library with ") + config->server);
|
main->logger->write(QObject::tr("Attempting to initialize library with ") + config->server);
|
||||||
|
|
||||||
// Check to see if there's an existing wallet
|
// Check to see if there's an existing wallet
|
||||||
if (litelib_wallet_exists(Settings::getDefaultChainName().toStdString().c_str())) {
|
if (litelib_wallet_exists(Settings::getDefaultChainName().toStdString().c_str()))
|
||||||
|
{
|
||||||
main->logger->write(QObject::tr("Using existing wallet."));
|
main->logger->write(QObject::tr("Using existing wallet."));
|
||||||
char* resp = litelib_initialize_existing(config->dangerous, config->server.toStdString().c_str());
|
char* resp = litelib_initialize_existing(
|
||||||
|
config->dangerous,
|
||||||
|
config->server.toStdString().c_str()
|
||||||
|
);
|
||||||
QString response = litelib_process_response(resp);
|
QString response = litelib_process_response(resp);
|
||||||
|
|
||||||
if (response.toUpper().trimmed() != "OK") {
|
if (response.toUpper().trimmed() != "OK")
|
||||||
|
{
|
||||||
showError(response);
|
showError(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
main->logger->write(QObject::tr("Create/restore wallet."));
|
main->logger->write(QObject::tr("Create/restore wallet."));
|
||||||
createOrRestore(config->dangerous, config->server);
|
createOrRestore(config->dangerous, config->server);
|
||||||
d->show();
|
d->show();
|
||||||
@@ -72,7 +85,6 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
// If success, set the connection
|
// If success, set the connection
|
||||||
main->logger->write("Connection is online.");
|
main->logger->write("Connection is online.");
|
||||||
connection->setInfo(reply);
|
connection->setInfo(reply);
|
||||||
|
|
||||||
isSyncing = new QAtomicInteger<bool>();
|
isSyncing = new QAtomicInteger<bool>();
|
||||||
isSyncing->store(true);
|
isSyncing->store(true);
|
||||||
|
|
||||||
@@ -80,10 +92,8 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
syncTimer = new QTimer(main);
|
syncTimer = new QTimer(main);
|
||||||
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
|
connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) {
|
||||||
isSyncing->store(false);
|
isSyncing->store(false);
|
||||||
|
|
||||||
// Cancel the timer
|
// Cancel the timer
|
||||||
syncTimer->deleteLater();
|
syncTimer->deleteLater();
|
||||||
|
|
||||||
// When sync is done, set the connection
|
// When sync is done, set the connection
|
||||||
this->doRPCSetConnection(connection);
|
this->doRPCSetConnection(connection);
|
||||||
});
|
});
|
||||||
@@ -94,10 +104,13 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
if (isSyncing != nullptr && isSyncing->load()) {
|
if (isSyncing != nullptr && isSyncing->load()) {
|
||||||
// Get the sync status
|
// Get the sync status
|
||||||
connection->doRPC("syncstatus", "", [=](json reply) {
|
connection->doRPC("syncstatus", "", [=](json reply) {
|
||||||
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end()) {
|
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end())
|
||||||
|
{
|
||||||
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
|
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
|
||||||
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
|
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
|
||||||
me->showInformation("Synced " + QString::number(synced) + " / " + QString::number(total));
|
me->showInformation(
|
||||||
|
"Synced " + QString::number(synced) + " / " + QString::number(total)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[=](QString err) {
|
[=](QString err) {
|
||||||
@@ -114,104 +127,110 @@ void ConnectionLoader::doAutoConnect() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionLoader::createOrRestore(bool dangerous, QString server) {
|
void ConnectionLoader::createOrRestore(bool dangerous, QString server)
|
||||||
|
{
|
||||||
// Close the startup dialog, since we'll be showing the wizard
|
// Close the startup dialog, since we'll be showing the wizard
|
||||||
d->hide();
|
d->hide();
|
||||||
|
|
||||||
// Create a wizard
|
// Create a wizard
|
||||||
FirstTimeWizard wizard(dangerous, server);
|
FirstTimeWizard wizard(dangerous, server);
|
||||||
|
|
||||||
wizard.exec();
|
wizard.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionLoader::doRPCSetConnection(Connection* conn) {
|
void ConnectionLoader::doRPCSetConnection(Connection* conn)
|
||||||
|
{
|
||||||
qDebug() << "Connectionloader finished, setting connection";
|
qDebug() << "Connectionloader finished, setting connection";
|
||||||
rpc->setConnection(conn);
|
rpc->setConnection(conn);
|
||||||
|
|
||||||
d->accept();
|
d->accept();
|
||||||
|
|
||||||
QTimer::singleShot(1, [=]() { delete this; });
|
QTimer::singleShot(1, [=]() { delete this; });
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config) {
|
Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> config)
|
||||||
|
{
|
||||||
return new Connection(main, config);
|
return new Connection(main, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the UI with the status
|
// Update the UI with the status
|
||||||
void ConnectionLoader::showInformation(QString info, QString detail) {
|
void ConnectionLoader::showInformation(QString info, QString detail)
|
||||||
|
{
|
||||||
connD->status->setText(info);
|
connD->status->setText(info);
|
||||||
connD->statusDetail->setText(detail);
|
connD->statusDetail->setText(detail);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show error will close the loading dialog and show an error.
|
* Show error will close the loading dialog and show an error.
|
||||||
*/
|
*/
|
||||||
void ConnectionLoader::showError(QString explanation) {
|
void ConnectionLoader::showError(QString explanation)
|
||||||
|
{
|
||||||
rpc->noConnection();
|
rpc->noConnection();
|
||||||
|
QMessageBox::critical(
|
||||||
QMessageBox::critical(main, QObject::tr("Connection Error"), explanation, QMessageBox::Ok);
|
main,
|
||||||
|
QObject::tr("Connection Error"),
|
||||||
|
explanation,
|
||||||
|
QMessageBox::Ok
|
||||||
|
);
|
||||||
d->close();
|
d->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString litelib_process_response(char* resp) {
|
QString litelib_process_response(char* resp)
|
||||||
|
{
|
||||||
char* resp_copy = new char[strlen(resp) + 1];
|
char* resp_copy = new char[strlen(resp) + 1];
|
||||||
strcpy(resp_copy, resp);
|
//a safer version of strcpy
|
||||||
|
strncpy(resp_copy, resp, strlen(resp)+1);
|
||||||
litelib_rust_free_string(resp);
|
litelib_rust_free_string(resp);
|
||||||
|
|
||||||
QString reply = QString::fromStdString(resp_copy);
|
QString reply = QString::fromStdString(resp_copy);
|
||||||
memset(resp_copy, '-', strlen(resp_copy));
|
memset(resp_copy, '-', strlen(resp_copy));
|
||||||
delete[] resp_copy;
|
delete[] resp_copy;
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************
|
/***********************************************************************************
|
||||||
* Connection, Executor and Callback Class
|
* Connection, Executor and Callback Class
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
void Executor::run() {
|
void Executor::run()
|
||||||
|
{
|
||||||
char* resp = litelib_execute(this->cmd.toStdString().c_str(), this->args.toStdString().c_str());
|
char* resp = litelib_execute(this->cmd.toStdString().c_str(), this->args.toStdString().c_str());
|
||||||
|
|
||||||
QString reply = litelib_process_response(resp);
|
QString reply = litelib_process_response(resp);
|
||||||
|
|
||||||
//qDebug() << "RPC Reply=" << reply;
|
//qDebug() << "RPC Reply=" << reply;
|
||||||
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
|
auto parsed = json::parse(
|
||||||
if (parsed.is_discarded() || parsed.is_null()) {
|
reply.toStdString().c_str(),
|
||||||
|
nullptr,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
if (parsed.is_discarded() || parsed.is_null())
|
||||||
emit handleError(reply);
|
emit handleError(reply);
|
||||||
} else {
|
|
||||||
|
else
|
||||||
emit responseReady(parsed);
|
emit responseReady(parsed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Callback::processRPCCallback(json resp) {
|
void Callback::processRPCCallback(json resp)
|
||||||
|
{
|
||||||
this->cb(resp);
|
this->cb(resp);
|
||||||
|
|
||||||
// Destroy self
|
// Destroy self
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Callback::processError(QString resp) {
|
void Callback::processError(QString resp)
|
||||||
|
{
|
||||||
this->errCb(resp);
|
this->errCb(resp);
|
||||||
|
|
||||||
// Destroy self
|
// Destroy self
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection::Connection(MainWindow* m, std::shared_ptr<ConnectionConfig> conf) {
|
Connection::Connection(MainWindow* m, std::shared_ptr<ConnectionConfig> conf)
|
||||||
|
{
|
||||||
this->config = conf;
|
this->config = conf;
|
||||||
this->main = m;
|
this->main = m;
|
||||||
|
|
||||||
// Register the JSON type as a type that can be passed between signals and slots.
|
// Register the JSON type as a type that can be passed between signals and slots.
|
||||||
qRegisterMetaType<json>("json");
|
qRegisterMetaType<json>("json");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::doRPC(const QString cmd, const QString args, const std::function<void(json)>& cb,
|
void Connection::doRPC(const QString cmd, const QString args, const std::function<void(json)>& cb, const std::function<void(QString)>& errCb)
|
||||||
const std::function<void(QString)>& errCb) {
|
{
|
||||||
if (shutdownInProgress) {
|
if (shutdownInProgress)
|
||||||
// Ignoring RPC because shutdown in progress
|
// Ignoring RPC because shutdown in progress
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "Doing RPC: " << cmd;
|
//qDebug() << "Doing RPC: " << cmd;
|
||||||
|
|
||||||
@@ -223,24 +242,27 @@ void Connection::doRPC(const QString cmd, const QString args, const std::functio
|
|||||||
|
|
||||||
QObject::connect(runner, &Executor::responseReady, c, &Callback::processRPCCallback);
|
QObject::connect(runner, &Executor::responseReady, c, &Callback::processRPCCallback);
|
||||||
QObject::connect(runner, &Executor::handleError, c, &Callback::processError);
|
QObject::connect(runner, &Executor::handleError, c, &Callback::processError);
|
||||||
|
|
||||||
QThreadPool::globalInstance()->start(runner);
|
QThreadPool::globalInstance()->start(runner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(json)>& cb) {
|
void Connection::doRPCWithDefaultErrorHandling(const QString cmd, const QString args, const std::function<void(json)>& cb)
|
||||||
|
{
|
||||||
doRPC(cmd, args, cb, [=] (QString err) {
|
doRPC(cmd, args, cb, [=] (QString err) {
|
||||||
this->showTxError(err);
|
this->showTxError(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(json)>& cb) {
|
void Connection::doRPCIgnoreError(const QString cmd, const QString args, const std::function<void(json)>& cb)
|
||||||
|
{
|
||||||
doRPC(cmd, args, cb, [=] (auto) {
|
doRPC(cmd, args, cb, [=] (auto) {
|
||||||
// Ignored error handling
|
// Ignored error handling
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::showTxError(const QString& error) {
|
void Connection::showTxError(const QString& error)
|
||||||
if (error.isNull()) return;
|
{
|
||||||
|
if (error.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
// Prevent multiple dialog boxes from showing, because they're all called async
|
// Prevent multiple dialog boxes from showing, because they're all called async
|
||||||
static bool shown = false;
|
static bool shown = false;
|
||||||
@@ -248,14 +270,19 @@ void Connection::showTxError(const QString& error) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
shown = true;
|
shown = true;
|
||||||
QMessageBox::critical(main, QObject::tr("Transaction Error"), QObject::tr("There was an error sending the transaction. The error was:") + "\n\n"
|
QMessageBox::critical(
|
||||||
+ error, QMessageBox::StandardButton::Ok);
|
main,
|
||||||
|
QObject::tr("Transaction Error"),
|
||||||
|
QObject::tr("There was an error sending the transaction. The error was:") + "\n\n" + error,
|
||||||
|
QMessageBox::StandardButton::Ok
|
||||||
|
);
|
||||||
shown = false;
|
shown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent all future calls from going through
|
* Prevent all future calls from going through
|
||||||
*/
|
*/
|
||||||
void Connection::shutdown() {
|
void Connection::shutdown()
|
||||||
|
{
|
||||||
shutdownInProgress = true;
|
shutdownInProgress = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
Controller::Controller(MainWindow* main) {
|
Controller::Controller(MainWindow* main)
|
||||||
|
{
|
||||||
auto cl = new ConnectionLoader(main, this);
|
auto cl = new ConnectionLoader(main, this);
|
||||||
|
|
||||||
// Execute the load connection async, so we can set up the rest of RPC properly.
|
// Execute the load connection async, so we can set up the rest of RPC properly.
|
||||||
@@ -49,24 +50,24 @@ Controller::Controller(MainWindow* main) {
|
|||||||
zrpc = new LiteInterface();
|
zrpc = new LiteInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller::~Controller() {
|
Controller::~Controller()
|
||||||
|
{
|
||||||
delete timer;
|
delete timer;
|
||||||
delete txTimer;
|
delete txTimer;
|
||||||
|
|
||||||
delete transactionsTableModel;
|
delete transactionsTableModel;
|
||||||
delete balancesTableModel;
|
delete balancesTableModel;
|
||||||
|
|
||||||
delete model;
|
delete model;
|
||||||
delete zrpc;
|
delete zrpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called when a connection to hushd is available.
|
// Called when a connection to hushd is available.
|
||||||
void Controller::setConnection(Connection* c) {
|
void Controller::setConnection(Connection* c)
|
||||||
if (c == nullptr) return;
|
{
|
||||||
|
if (c == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
this->zrpc->setConnection(c);
|
this->zrpc->setConnection(c);
|
||||||
|
|
||||||
ui->statusBar->showMessage("");
|
ui->statusBar->showMessage("");
|
||||||
|
|
||||||
// If we're allowed to get the Hush Price, get the prices
|
// If we're allowed to get the Hush Price, get the prices
|
||||||
@@ -81,473 +82,152 @@ void Controller::setConnection(Connection* c) {
|
|||||||
// where we need to immediately refresh
|
// where we need to immediately refresh
|
||||||
refresh(true);
|
refresh(true);
|
||||||
|
|
||||||
// Create Sietch zdust addr at startup.
|
// Create Sietch zdust addr at startup.
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
for(uint8_t i = 0; i < 10; i++)
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch.txt");
|
{
|
||||||
QFile file(path);
|
zrpc->createNewSietchZaddr( [=] (json reply) {
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
QString path = "";
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
if(i > 0)
|
||||||
file.close();
|
path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch") + QString(i) + QString(".txt");
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
else
|
||||||
file.close();
|
path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch.txt");
|
||||||
|
|
||||||
|
QFile file(path);
|
||||||
|
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
||||||
|
if(!file.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QTextStream out(&file); out << zdust.toUtf8();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch1.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch2.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch3.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch4.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch5.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch6.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch7.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch8.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch9.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the RPC JSON Parameters for this tx
|
// Build the RPC JSON Parameters for this tx
|
||||||
void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
|
void Controller::fillTxJsonParams(json& allRecepients, Tx tx)
|
||||||
|
{
|
||||||
Q_ASSERT(allRecepients.is_array());
|
Q_ASSERT(allRecepients.is_array());
|
||||||
|
|
||||||
// Construct the JSON params
|
// Construct the JSON params
|
||||||
json rec = json::object();
|
json rec = json::object();
|
||||||
json dust = json::object();
|
|
||||||
json dust1 = json::object();
|
|
||||||
json dust2 = json::object();
|
|
||||||
json dust3 = json::object();
|
|
||||||
json dust4 = json::object();
|
|
||||||
json dust5 = json::object();
|
|
||||||
json dust6 = json::object();
|
|
||||||
json dust7 = json::object();
|
|
||||||
json dust8 = json::object();
|
|
||||||
json dust9 = json::object();
|
|
||||||
|
|
||||||
// Create Sietch zdust addr again to not use it twice.
|
//creating the JSON dust parameters in a std::vector to iterate over there during tx
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
std::vector<json> dust(10);
|
||||||
|
dust.resize(10, json::object());
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch.txt");
|
// Create Sietch zdust addr again to not use it twice.
|
||||||
QFile file(path);
|
for(uint8_t i = 0; i < 10; i++)
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
{
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
zrpc->createNewSietchZaddr( [=] (json reply) {
|
||||||
file.close();
|
QString path = "";
|
||||||
} else {
|
if(i > 0)
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch") + QString(i) + QString(".txt");
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
else
|
||||||
|
path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch.txt");
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch1.txt");
|
QFile file(path);
|
||||||
QFile file(path);
|
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
if(!file.open(QIODevice::WriteOnly))
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
{
|
||||||
file.close();
|
file.close();
|
||||||
} else {
|
} else {
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
QTextStream out(&file); out << zdust.toUtf8();
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch2.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch3.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch4.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch5.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch6.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch7.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch8.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
zrpc->createNewSietchZaddr( [=] (json reply) {
|
|
||||||
|
|
||||||
QString path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch9.txt");
|
|
||||||
QFile file(path);
|
|
||||||
QString zdust = QString::fromStdString(reply.get<json::array_t>()[0]);
|
|
||||||
if(!file.open(QIODevice::WriteOnly)){
|
|
||||||
file.close();
|
|
||||||
} else {
|
|
||||||
QTextStream out(&file); out << zdust.toUtf8();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Set sietch zdust addr to json.
|
|
||||||
|
|
||||||
QString path= (QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)) + QString("/Sietch.txt");
|
|
||||||
QFile inputFile(path);
|
|
||||||
if (inputFile.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString path1= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch1.txt");
|
|
||||||
QFile inputFile1(path1);
|
|
||||||
if (inputFile1.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile1);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
QString zdust = line;
|
|
||||||
|
|
||||||
dust1["address"] = zdust.toStdString();
|
// Set sietch zdust addr to json.
|
||||||
}
|
for(uint8_t i = 0; i < 10; i++)
|
||||||
inputFile1.close();
|
{
|
||||||
}
|
QString path = "";
|
||||||
|
if(i > 0)
|
||||||
|
path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch") + QString(i) + QString(".txt");
|
||||||
|
|
||||||
QString path2= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch2.txt");
|
else
|
||||||
QFile inputFile2(path2);
|
path= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch.txt");
|
||||||
if (inputFile2.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile2);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust2["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile2.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path3= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch3.txt");
|
QFile inputFile(path);
|
||||||
QFile inputFile3(path3);
|
if (inputFile.open(QIODevice::ReadOnly))
|
||||||
if (inputFile3.open(QIODevice::ReadOnly))
|
{
|
||||||
{
|
QTextStream in(&inputFile);
|
||||||
QTextStream in(&inputFile3);
|
while (!in.atEnd())
|
||||||
while (!in.atEnd())
|
{
|
||||||
{
|
QString line = in.readLine();
|
||||||
QString line = in.readLine();
|
dust.at(i)["address"] = line.toStdString();
|
||||||
dust3["address"] = line.toStdString();
|
}
|
||||||
}
|
|
||||||
inputFile3.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path4= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch4.txt");
|
inputFile.close();
|
||||||
QFile inputFile4(path4);
|
|
||||||
if (inputFile4.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile4);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust4["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile4.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path5= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch5.txt");
|
|
||||||
QFile inputFile5(path5);
|
|
||||||
if (inputFile5.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile5);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust5["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile5.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path6= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch6.txt");
|
|
||||||
QFile inputFile6(path6);
|
|
||||||
if (inputFile6.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile6);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust6["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile6.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path7= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch7.txt");
|
|
||||||
QFile inputFile7(path7);
|
|
||||||
if (inputFile7.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile7);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust7["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile7.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path8= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch8.txt");
|
|
||||||
QFile inputFile8(path8);
|
|
||||||
if (inputFile8.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile8);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust8["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path9= QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QString("/Sietch9.txt");
|
|
||||||
QFile inputFile9(path9);
|
|
||||||
if (inputFile9.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
QTextStream in(&inputFile9);
|
|
||||||
while (!in.atEnd())
|
|
||||||
{
|
|
||||||
QString line = in.readLine();
|
|
||||||
dust9["address"] = line.toStdString();
|
|
||||||
}
|
|
||||||
inputFile9.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dust amt/memo, construct the JSON
|
|
||||||
dust["amount"] = 0;
|
|
||||||
dust["memo"] = "";
|
|
||||||
dust1["amount"] = 0;
|
|
||||||
dust1["memo"] = "";
|
|
||||||
dust2["amount"] = 0;
|
|
||||||
dust2["memo"] = "";
|
|
||||||
dust3["amount"] = 0;
|
|
||||||
dust3["memo"] = "";
|
|
||||||
dust4["amount"] = 0;
|
|
||||||
dust4["memo"] = "";
|
|
||||||
dust5["amount"] = 0;
|
|
||||||
dust5["memo"] = "";
|
|
||||||
dust6["amount"] = 0;
|
|
||||||
dust6["memo"] = "";
|
|
||||||
dust7["amount"] = 0;
|
|
||||||
dust7["memo"] = "";
|
|
||||||
dust8["amount"] = 0;
|
|
||||||
dust8["memo"] = "";
|
|
||||||
dust9["amount"] = 0;
|
|
||||||
dust9["memo"] = "";
|
|
||||||
|
|
||||||
// For each addr/amt/memo, construct the JSON and also build the confirm dialog box
|
|
||||||
|
|
||||||
for (int i=0; i < tx.toAddrs.size(); i++) {
|
|
||||||
auto toAddr = tx.toAddrs[i];
|
|
||||||
|
|
||||||
rec["address"] = toAddr.addr.toStdString();
|
|
||||||
rec["amount"] = toAddr.amount.toqint64();
|
|
||||||
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
|
||||||
rec["memo"] = toAddr.memo.toStdString();
|
|
||||||
|
|
||||||
allRecepients.push_back(rec) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
int decider = qrand() % ((100 + 1)-1)+ 1;// random int between 1 and 100
|
|
||||||
|
|
||||||
//50% chance of adding another zdust, shuffle.
|
|
||||||
|
|
||||||
|
|
||||||
if(decider % 4 == 3) {
|
|
||||||
allRecepients.insert(std::begin(allRecepients),{dust,dust1,dust2,dust3,dust4,dust5,dust6,dust7,dust8}) ;
|
|
||||||
// std::shuffle(allRecepients.begin(),allRecepients.end(),std::random_device());
|
|
||||||
|
|
||||||
}else {
|
|
||||||
allRecepients.insert(std::begin(allRecepients),{dust,dust1,dust2,dust3,dust4,dust5,dust6,dust7,dust8,dust9}) ;
|
|
||||||
// std::shuffle(allRecepients.begin(),allRecepients.end(),std::random_device());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Dust amt/memo, construct the JSON
|
||||||
|
for(uint8_t i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
printf("Setting amount and memo to 0 for dust%i \n", i);
|
||||||
|
dust.at(i)["amount"] = 0;
|
||||||
|
dust.at(i)["memo"] = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For each addr/amt/memo, construct the JSON and also build the confirm dialog box
|
||||||
|
for (int i=0; i < tx.toAddrs.size(); i++)
|
||||||
|
{
|
||||||
|
auto toAddr = tx.toAddrs[i];
|
||||||
|
rec["address"] = toAddr.addr.toStdString();
|
||||||
|
rec["amount"] = toAddr.amount.toqint64();
|
||||||
|
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
||||||
|
rec["memo"] = toAddr.memo.toStdString();
|
||||||
|
|
||||||
|
allRecepients.push_back(rec) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decider = qrand() % ((100 + 1)-1)+ 1;// random int between 1 and 100
|
||||||
|
//50% chance of adding another zdust, shuffle.
|
||||||
|
|
||||||
|
if(decider % 4 == 3)
|
||||||
|
allRecepients.insert(std::begin(allRecepients), {
|
||||||
|
dust.at(0),
|
||||||
|
dust.at(1),
|
||||||
|
dust.at(2),
|
||||||
|
dust.at(3),
|
||||||
|
dust.at(4),
|
||||||
|
dust.at(5),
|
||||||
|
dust.at(6),
|
||||||
|
dust.at(7),
|
||||||
|
dust.at(8)
|
||||||
|
}) ;
|
||||||
|
// std::shuffle(allRecepients.begin(),allRecepients.end(),std::random_device());
|
||||||
|
else
|
||||||
|
allRecepients.insert(std::begin(allRecepients), {
|
||||||
|
dust.at(0),
|
||||||
|
dust.at(1),
|
||||||
|
dust.at(2),
|
||||||
|
dust.at(3),
|
||||||
|
dust.at(4),
|
||||||
|
dust.at(5),
|
||||||
|
dust.at(6),
|
||||||
|
dust.at(7),
|
||||||
|
dust.at(8),
|
||||||
|
dust.at(9)
|
||||||
|
});
|
||||||
|
// std::shuffle(allRecepients.begin(),allRecepients.end(),std::random_device());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::noConnection() {
|
void Controller::noConnection()
|
||||||
|
{
|
||||||
QIcon i = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
|
QIcon i = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
|
||||||
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
||||||
main->statusIcon->setToolTip("");
|
main->statusIcon->setToolTip("");
|
||||||
@@ -576,21 +256,23 @@ void Controller::noConnection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This will refresh all the balance data from hushd
|
/// This will refresh all the balance data from hushd
|
||||||
void Controller::refresh(bool force) {
|
void Controller::refresh(bool force)
|
||||||
|
{
|
||||||
if (!zrpc->haveConnection())
|
if (!zrpc->haveConnection())
|
||||||
return noConnection();
|
return noConnection();
|
||||||
|
|
||||||
getInfoThenRefresh(force);
|
getInfoThenRefresh(force);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::processInfo(const json& info) {
|
void Controller::processInfo(const json& info)
|
||||||
|
{
|
||||||
// Testnet?
|
// Testnet?
|
||||||
QString chainName;
|
QString chainName;
|
||||||
if (!info["chain_name"].is_null()) {
|
if (!info["chain_name"].is_null())
|
||||||
|
{
|
||||||
chainName = QString::fromStdString(info["chain_name"].get<json::string_t>());
|
chainName = QString::fromStdString(info["chain_name"].get<json::string_t>());
|
||||||
Settings::getInstance()->setTestnet(chainName == "test");
|
Settings::getInstance()->setTestnet(chainName == "test");
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
QString version = QString::fromStdString(info["version"].get<json::string_t>());
|
QString version = QString::fromStdString(info["version"].get<json::string_t>());
|
||||||
Settings::getInstance()->sethushdVersion(version);
|
Settings::getInstance()->sethushdVersion(version);
|
||||||
@@ -600,7 +282,8 @@ void Controller::processInfo(const json& info) {
|
|||||||
main->disableRecurring();
|
main->disableRecurring();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::getInfoThenRefresh(bool force) {
|
void Controller::getInfoThenRefresh(bool force)
|
||||||
|
{
|
||||||
if (!zrpc->haveConnection())
|
if (!zrpc->haveConnection())
|
||||||
return noConnection();
|
return noConnection();
|
||||||
|
|
||||||
@@ -608,38 +291,59 @@ void Controller::getInfoThenRefresh(bool force) {
|
|||||||
|
|
||||||
zrpc->fetchInfo([=] (const json& reply) {
|
zrpc->fetchInfo([=] (const json& reply) {
|
||||||
prevCallSucceeded = true;
|
prevCallSucceeded = true;
|
||||||
|
|
||||||
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
|
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
|
||||||
int longestchain = reply["longestchain"].get<json::number_integer_t>();
|
int longestchain = reply["longestchain"].get<json::number_integer_t>();
|
||||||
int notarized = reply["notarized"].get<json::number_integer_t>();
|
int notarized = reply["notarized"].get<json::number_integer_t>();
|
||||||
int difficulty = reply["difficulty"].get<json::number_integer_t>();
|
int difficulty = reply["difficulty"].get<json::number_integer_t>();
|
||||||
int blocks_until_halving= 340000 - curBlock;
|
int blocks_until_halving= 340000 - curBlock;
|
||||||
int halving_days =
|
int halving_days = (blocks_until_halving * 150) / (60*60*24) ;
|
||||||
(blocks_until_halving * 150) / (60*60*24) ;
|
|
||||||
bool doUpdate = force || (model->getLatestBlock() != curBlock);
|
bool doUpdate = force || (model->getLatestBlock() != curBlock);
|
||||||
model->setLatestBlock(curBlock);
|
model->setLatestBlock(curBlock);
|
||||||
|
if (
|
||||||
if (Settings::getInstance()->get_currency_name() == "EUR" || Settings::getInstance()->get_currency_name() == "CHF" || Settings::getInstance()->get_currency_name() == "RUB") {
|
Settings::getInstance()->get_currency_name() == "EUR" ||
|
||||||
ui->blockHeight->setText("Block: " + QLocale(QLocale::German).toString(curBlock));
|
Settings::getInstance()->get_currency_name() == "CHF" ||
|
||||||
ui->last_notarized->setText("Block: " + QLocale(QLocale::German).toString(notarized));
|
Settings::getInstance()->get_currency_name() == "RUB"
|
||||||
ui->longestchain->setText("Block: " + QLocale(QLocale::German).toString(longestchain));
|
)
|
||||||
ui->difficulty->setText(QLocale(QLocale::German).toString(difficulty));
|
{
|
||||||
ui->halvingTime->setText((QLocale(QLocale::German).toString(blocks_until_halving)) + " Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days" ));
|
ui->blockHeight->setText(
|
||||||
|
"Block: " + QLocale(QLocale::German).toString(curBlock)
|
||||||
|
);
|
||||||
|
ui->last_notarized->setText(
|
||||||
|
"Block: " + QLocale(QLocale::German).toString(notarized)
|
||||||
|
);
|
||||||
|
ui->longestchain->setText(
|
||||||
|
"Block: " + QLocale(QLocale::German).toString(longestchain)
|
||||||
|
);
|
||||||
|
ui->difficulty->setText(
|
||||||
|
QLocale(QLocale::German).toString(difficulty)
|
||||||
|
);
|
||||||
|
ui->halvingTime->setText(
|
||||||
|
(QLocale(QLocale::German).toString(blocks_until_halving)) +
|
||||||
|
" Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days" )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
ui->blockHeight->setText("Block: " + QLocale(QLocale::English).toString(curBlock));
|
{
|
||||||
ui->last_notarized->setText("Block: " + QLocale(QLocale::English).toString(notarized));
|
ui->blockHeight->setText(
|
||||||
ui->longestchain->setText("Block: " + QLocale(QLocale::English).toString(longestchain));
|
"Block: " + QLocale(QLocale::English).toString(curBlock)
|
||||||
ui->difficulty->setText(QLocale(QLocale::English).toString(difficulty));
|
);
|
||||||
ui->halvingTime->setText((QLocale(QLocale::English).toString(blocks_until_halving)) + " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days" ));
|
ui->last_notarized->setText(
|
||||||
|
"Block: " + QLocale(QLocale::English).toString(notarized)
|
||||||
|
);
|
||||||
|
ui->longestchain->setText(
|
||||||
|
"Block: " + QLocale(QLocale::English).toString(longestchain)
|
||||||
|
);
|
||||||
|
ui->difficulty->setText(
|
||||||
|
QLocale(QLocale::English).toString(difficulty)
|
||||||
|
);
|
||||||
|
ui->halvingTime->setText(
|
||||||
|
(QLocale(QLocale::English).toString(blocks_until_halving)) +
|
||||||
|
" Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days" )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ui->Version->setText(QString::fromStdString(reply["version"].get<json::string_t>()));
|
ui->Version->setText(QString::fromStdString(reply["version"].get<json::string_t>()));
|
||||||
ui->Vendor->setText(QString::fromStdString(reply["vendor"].get<json::string_t>()));
|
ui->Vendor->setText(QString::fromStdString(reply["vendor"].get<json::string_t>()));
|
||||||
|
|
||||||
|
|
||||||
main->logger->write(QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") );
|
main->logger->write(QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") );
|
||||||
|
|
||||||
// Connected, so display checkmark.
|
// Connected, so display checkmark.
|
||||||
|
|||||||
Reference in New Issue
Block a user