Browse Source

Fix ZEC double precision display, add validations

import_zecw
Aditya Kulkarni 6 years ago
parent
commit
44554f7ff4
  1. 2
      src/balancestablemodel.cpp
  2. 12
      src/main.cpp
  3. 17
      src/mainwindow.cpp
  4. 4
      src/mainwindow.h
  5. 20
      src/mainwindow.ui
  6. 1
      src/precompiled.h
  7. 21
      src/rpc.cpp
  8. 77
      src/sendtab.cpp
  9. 2
      src/txtablemodel.cpp
  10. 13
      src/ui_mainwindow.h

2
src/balancestablemodel.cpp

@ -18,7 +18,7 @@ void BalancesTableModel::setNewData(const QMap<QString, double>* balances,
delete modeldata;
modeldata = new QList<std::tuple<QString, QString>>();
std::for_each(balances->constKeyValueBegin(), balances->constKeyValueEnd(), [=] (auto it) {
modeldata->push_back(std::make_tuple(it.first, QString::number(it.second, 'f')));
modeldata->push_back(std::make_tuple(it.first, QString::number(it.second, 'g', 8)));
});
// And then update the data

12
src/main.cpp

@ -3,6 +3,13 @@
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
#ifdef Q_OS_LINUX
QFontDatabase::addApplicationFont(":/fonts/res/Ubuntu-R.ttf");
qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false));
#endif
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@ -10,11 +17,6 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationDomain("adityapk.com");
QCoreApplication::setApplicationName("zcash-qt-wallet");
QApplication a(argc, argv);
#ifdef Q_OS_LINUX
QFontDatabase::addApplicationFont(":/fonts/res/Ubuntu-R.ttf");
qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false));
#endif
MainWindow w;
w.show();

17
src/mainwindow.cpp

@ -70,7 +70,10 @@ MainWindow::MainWindow(QWidget *parent) :
});
// Set up exit action
QObject::connect(ui->actionExit, &QAction::triggered, [=] { this->close(); });
QObject::connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close);
// Set up donate action
QObject::connect(ui->actionDonate, &QAction::triggered, this, &MainWindow::donate);
// Set up about action
QObject::connect(ui->actionAbout, &QAction::triggered, [=] () {
@ -97,6 +100,18 @@ MainWindow::MainWindow(QWidget *parent) :
rpc->refresh();
}
void MainWindow::donate() {
// Set up a donation to me :)
ui->Address1->setText("zcEgrceTwvoiFdEvPWcsJHAMrpLsprMF6aRJiQa3fan5ZphyXLPuHghnEPrEPRoEVzUy65GnMVyCTRdkT6BYBepnXh6NBYs");
ui->Address1->setCursorPosition(0);
ui->Amount1->setText("0.01");
ui->statusBar->showMessage("Donate 0.01 ZEC to support zcash-qt-wallet");
// And switch to the send tab.
ui->tabWidget->setCurrentIndex(1);
}
void MainWindow::setupBalancesTab() {
ui->unconfirmedWarning->setVisible(false);

4
src/mainwindow.h

@ -42,6 +42,10 @@ private:
void addAddressSection();
void maxAmountChecked(int checked);
QString doSendTxValidations(QString fromAddr, QList<QPair<QString, double>> toAddrs);
void donate();
RPC* rpc;
Settings* settings;

20
src/mainwindow.ui

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>838</width>
<height>595</height>
<width>889</width>
<height>603</height>
</rect>
</property>
<property name="windowTitle">
@ -18,7 +18,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -247,8 +247,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>774</width>
<height>276</height>
<width>772</width>
<height>218</height>
</rect>
</property>
<layout class="QVBoxLayout" name="sendToLayout">
@ -610,8 +610,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>838</width>
<height>21</height>
<width>889</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuBalance">
@ -626,6 +626,7 @@
<property name="title">
<string>Help</string>
</property>
<addaction name="actionDonate"/>
<addaction name="actionAbout"/>
</widget>
<addaction name="menuBalance"/>
@ -647,6 +648,11 @@
<string>Settings</string>
</property>
</action>
<action name="actionDonate">
<property name="text">
<string>Donate</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>

1
src/precompiled.h

@ -14,6 +14,7 @@
#include <QScrollBar>
#include <QPainter>
#include <QMovie>
#include <QPair>
#include <QTimer>
#include <QSettings>
#include <QFile>

21
src/rpc.cpp

@ -341,7 +341,7 @@ void RPC::refreshBalances() {
UnspentOutput(
qsAddr,
QString::fromStdString(it["txid"]),
QString::number(it["amount"].get<json::number_float_t>(), 'f', 8),
QString::number(it["amount"].get<json::number_float_t>(), 'g', 8),
confirmations
)
);
@ -361,7 +361,7 @@ void RPC::refreshBalances() {
ui->inputsCombo->clear();
auto i = allBalances->constBegin();
while (i != allBalances->constEnd()) {
QString item = i.key() % "(" % QString::number(i.value(), 'f') % " ZEC)";
QString item = i.key() % "(" % QString::number(i.value(), 'g', 8) % " ZEC)";
ui->inputsCombo->addItem(item);
if (item.startsWith(lastFromAddr)) ui->inputsCombo->setCurrentText(item);
@ -417,13 +417,7 @@ void RPC::refreshTxStatus(const QString& newOpid) {
};
doRPC(payload, [=] (const json& reply) {
// If there is some op that we are watching, then show the loading bar, otherwise hide it
if (watchingOps.isEmpty()) {
main->loadingLabel->setVisible(false);
} else {
main->loadingLabel->setVisible(true);
main->loadingLabel->setToolTip(QString::number(watchingOps.size()) + " tx computing");
}
int numExecuting = 0;
// There's an array for each item in the status
for (auto& it : reply.get<json::array_t>()) {
@ -462,8 +456,17 @@ void RPC::refreshTxStatus(const QString& newOpid) {
} else if (status == "executing") {
// If the operation is executing, then watch every second.
txTimer->start(1 * 1000);
numExecuting++;
}
}
}
// If there is some op that we are watching, then show the loading bar, otherwise hide it
if (numExecuting == 0) {
main->loadingLabel->setVisible(false);
} else {
main->loadingLabel->setVisible(true);
main->loadingLabel->setToolTip(QString::number(numExecuting) + " tx computing");
}
});
}

77
src/sendtab.cpp

@ -66,7 +66,7 @@ void MainWindow::setDefaultPayFrom() {
void MainWindow::inputComboTextChanged(const QString& text) {
auto bal = rpc->getAllBalances()->value(text.split("(")[0].trimmed());
auto balFmt = QString::number(bal, 'f', 8) + " ZEC";
auto balFmt = QString::number(bal, 'g', 8) + " ZEC";
ui->sendAddressBalance->setText(balFmt);
}
@ -163,7 +163,7 @@ void MainWindow::maxAmountChecked(int checked) {
auto maxamount = rpc->getAllBalances()->value(addr) - sumAllAmounts;
maxamount = (maxamount < 0) ? 0 : maxamount;
ui->Amount1->setText(QString::number(maxamount, 'f'));
ui->Amount1->setText(QString::number(maxamount, 'g', 8));
} else if (checked == Qt::Unchecked) {
// Just remove the readonly part, don't change the content
ui->Amount1->setReadOnly(false);
@ -179,6 +179,34 @@ void MainWindow::sendButton() {
return splitted;
};
// Gather the from / to addresses
QString fromAddr = ui->inputsCombo->currentText().split("(")[0].trimmed();
QList<QPair<QString, double>> toAddrs;
// For each addr/amt in the sendTo tab
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
for (int i=0; i < totalItems; i++) {
auto addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
auto amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble();
toAddrs.push_back(QPair<QString, double>(addr, amt));
}
QString error = doSendTxValidations(fromAddr, toAddrs);
if (!error.isEmpty()) {
// Something went wrong, so show an error and exit
QMessageBox msg(
QMessageBox::Critical,
"Transaction Error",
error,
QMessageBox::Ok,
this
);
msg.exec();
// abort the Tx
return;
}
// Get all the addresses and amounts
json allRecepients = json::array();
@ -197,16 +225,15 @@ void MainWindow::sendButton() {
delete amt;
}
// For each addr/amt in the sendTo tab
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
for (int i=0; i < totalItems; i++) {
auto addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1));
auto amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1));
// For each addr/amt
//std::for_each(toAddr.begin(), toAddr.end(), [&] (auto toAddr) {
for (int i=0; i < toAddrs.size(); i++) {
auto toAddr = toAddrs[i];
// Construct the JSON params
json rec = json::object();
rec["address"] = addr->text().toStdString();
rec["amount"] = amt->text().toDouble();
rec["address"] = toAddr.first.toStdString();
rec["amount"] = toAddr.second;
allRecepients.push_back(rec);
// Add new Address widgets instead of the same one.
@ -214,24 +241,24 @@ void MainWindow::sendButton() {
auto Addr = new QLabel(confirm.sendToAddrs);
Addr->setObjectName(QString("Addr") % QString::number(i + 1));
Addr->setWordWrap(true);
Addr->setText(fnSplitAddressForWrap(addr->text()));
Addr->setText(fnSplitAddressForWrap(toAddr.first));
confirm.gridLayout->addWidget(Addr, i, 0, 1, 1);
auto Amt = new QLabel(confirm.sendToAddrs);
Amt->setObjectName(QString("Amt") % QString::number(i + 1));
Amt->setText(amt->text() % " ZEC");
Amt->setText(QString::number(toAddr.second, 'g', 8) % " ZEC");
Amt->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(Amt, i, 1, 1, 1);
}
}
// Add sender
json params = json::array();
params.push_back(ui->inputsCombo->currentText().split("(")[0].trimmed().toStdString());
params.push_back(fromAddr.toStdString());
params.push_back(allRecepients);
// And show it in the confirm dialog
auto fromAddr = ui->inputsCombo->currentText().split("(")[0];
confirm.sendFrom->setText(fnSplitAddressForWrap(fromAddr));
// Show the dialog and submit it if the user confirms
@ -249,8 +276,32 @@ void MainWindow::sendButton() {
}
}
QString MainWindow::doSendTxValidations(QString fromAddr, QList<QPair<QString, double>> toAddrs) {
// 1. Addresses are valid format.
QRegExp zcexp("^zc[a-z0-9]{93}$", Qt::CaseInsensitive);
QRegExp zsexp("^zc[a-z0-9]{76}$", Qt::CaseInsensitive);
QRegExp texp("^t[a-z0-9]{34}$", Qt::CaseInsensitive);
auto matchesAnyAddr = [&] (QString addr) {
return zcexp.exactMatch(addr) ||
texp.exactMatch(addr) ||
zsexp.exactMatch(addr);
};
if (!matchesAnyAddr(fromAddr)) return QString("From Address is Invalid");
for (auto toAddr = toAddrs.begin(); toAddr != toAddrs.end(); toAddr++) {
if (!matchesAnyAddr(toAddr->first))
return QString("To Address ") % toAddr->first % " is Invalid";
};
return QString();
}
void MainWindow::cancelButton() {
removeExtraAddresses();
// Back to the balances tab
ui->tabWidget->setCurrentIndex(0);
}

2
src/txtablemodel.cpp

@ -53,7 +53,7 @@ void TxTableModel::setNewData(QList<TransactionItem>* data) {
case 0: return modeldata->at(index.row()).type;
case 1: return modeldata->at(index.row()).address;
case 2: return modeldata->at(index.row()).datetime;
case 3: return QVariant(QString::number(modeldata->at(index.row()).amount, 'f') % " ZEC");
case 3: return QVariant(QString::number(modeldata->at(index.row()).amount, 'g', 8) % " ZEC");
}
}

13
src/ui_mainwindow.h

@ -43,6 +43,7 @@ public:
QAction *actionExit;
QAction *actionAbout;
QAction *actionSettings;
QAction *actionDonate;
QWidget *centralWidget;
QGridLayout *gridLayout_3;
QTabWidget *tabWidget;
@ -134,13 +135,15 @@ public:
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(838, 595);
MainWindow->resize(889, 603);
actionExit = new QAction(MainWindow);
actionExit->setObjectName(QStringLiteral("actionExit"));
actionAbout = new QAction(MainWindow);
actionAbout->setObjectName(QStringLiteral("actionAbout"));
actionSettings = new QAction(MainWindow);
actionSettings->setObjectName(QStringLiteral("actionSettings"));
actionDonate = new QAction(MainWindow);
actionDonate->setObjectName(QStringLiteral("actionDonate"));
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
gridLayout_3 = new QGridLayout(centralWidget);
@ -327,7 +330,7 @@ public:
sendToScrollArea->setWidgetResizable(true);
sendToWidgets = new QWidget();
sendToWidgets->setObjectName(QStringLiteral("sendToWidgets"));
sendToWidgets->setGeometry(QRect(0, 0, 774, 276));
sendToWidgets->setGeometry(QRect(0, 0, 772, 218));
sendToLayout = new QVBoxLayout(sendToWidgets);
sendToLayout->setSpacing(6);
sendToLayout->setContentsMargins(11, 11, 11, 11);
@ -586,7 +589,7 @@ public:
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QStringLiteral("menuBar"));
menuBar->setGeometry(QRect(0, 0, 838, 21));
menuBar->setGeometry(QRect(0, 0, 889, 22));
menuBalance = new QMenu(menuBar);
menuBalance->setObjectName(QStringLiteral("menuBalance"));
menuHelp = new QMenu(menuBar);
@ -618,11 +621,12 @@ public:
menuBalance->addAction(actionSettings);
menuBalance->addSeparator();
menuBalance->addAction(actionExit);
menuHelp->addAction(actionDonate);
menuHelp->addAction(actionAbout);
retranslateUi(MainWindow);
tabWidget->setCurrentIndex(1);
tabWidget->setCurrentIndex(0);
QMetaObject::connectSlotsByName(MainWindow);
@ -634,6 +638,7 @@ public:
actionExit->setText(QApplication::translate("MainWindow", "Exit", nullptr));
actionAbout->setText(QApplication::translate("MainWindow", "About", nullptr));
actionSettings->setText(QApplication::translate("MainWindow", "Settings", nullptr));
actionDonate->setText(QApplication::translate("MainWindow", "Donate", nullptr));
groupBox->setTitle(QApplication::translate("MainWindow", "Summary", nullptr));
label->setText(QApplication::translate("MainWindow", "Shielded", nullptr));
balSheilded->setText(QString());

Loading…
Cancel
Save