diff --git a/src/balancestablemodel.cpp b/src/balancestablemodel.cpp index 0ebaad8..569eeae 100644 --- a/src/balancestablemodel.cpp +++ b/src/balancestablemodel.cpp @@ -1,4 +1,5 @@ #include "balancestablemodel.h" +#include "utils.h" BalancesTableModel::BalancesTableModel(QObject *parent) : QAbstractTableModel(parent) @@ -46,17 +47,8 @@ int BalancesTableModel::columnCount(const QModelIndex&) const return 2; } - QVariant BalancesTableModel::data(const QModelIndex &index, int role) const { - auto fnSplitAddressForWrap = [=] (const QString& a) -> QString { - if (!a.startsWith("z")) return a; - - auto half = a.length() / 2; - auto splitted = a.left(half) + "\n" + a.right(a.length() - half); - return splitted; - }; - if (role == Qt::TextAlignmentRole && index.column() == 1) return QVariant(Qt::AlignRight | Qt::AlignVCenter); if (role == Qt::ForegroundRole) { @@ -78,8 +70,8 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole || role == Qt::ToolTipRole) { switch (index.column()) { - case 0: return fnSplitAddressForWrap(std::get<0>(modeldata->at(index.row()))); - case 1: return QVariant(std::get<1>(modeldata->at(index.row())) % " ZEC"); + case 0: return std::get<0>(modeldata->at(index.row())); + case 1: return QVariant(std::get<1>(modeldata->at(index.row())) % " " % Utils::getTokenName()); } } @@ -111,3 +103,4 @@ QVariant BalancesTableModel::headerData(int section, Qt::Orientation orientation } return QVariant(); } + diff --git a/src/confirm.ui b/src/confirm.ui index ef81f6a..5473136 100644 --- a/src/confirm.ui +++ b/src/confirm.ui @@ -83,9 +83,9 @@ - + - Fees: 0.0001 ZEC + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8bc39aa..1594b1e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -86,6 +86,11 @@ MainWindow::MainWindow(QWidget *parent) : // Set up donate action QObject::connect(ui->actionDonate, &QAction::triggered, this, &MainWindow::donate); + // Set up check for updates action + QObject::connect(ui->actionCheck_for_Updates, &QAction::triggered, [=] () { + QDesktopServices::openUrl(QUrl("https://github.com/adityapk00/zcash-qt-wallet/releases")); + }); + QObject::connect(ui->actionImport_Private_Keys, &QAction::triggered, this, &MainWindow::importPrivKeys); // Set up about action @@ -118,7 +123,7 @@ void MainWindow::donate() { ui->Address1->setCursorPosition(0); ui->Amount1->setText("0.01"); - ui->statusBar->showMessage("Donate 0.01 ZEC to support zcash-qt-wallet"); + ui->statusBar->showMessage("Donate 0.01 " % Utils::getTokenName() % " to support zcash-qt-wallet"); // And switch to the send tab. ui->tabWidget->setCurrentIndex(1); @@ -156,14 +161,27 @@ void MainWindow::setupBalancesTab() { if (index.row() < 0) return; index = index.sibling(index.row(), 0); + auto addr = ui->balancesTable->model()->data(index).toString(); QMenu menu(this); menu.addAction("Copy Address", [=] () { QClipboard *clipboard = QGuiApplication::clipboard(); - clipboard->setText(ui->balancesTable->model()->data(index).toString()); + clipboard->setText(addr); }); + if (addr.startsWith("t")) { + menu.addAction("View on block explorer", [=] () { + QString url; + if (Settings::getInstance()->isTestnet()) { + url = "https://explorer.testnet.z.cash/address/" + addr; + } else { + url = "https://explorer.zcha.in/accounts/" + addr; + } + QDesktopServices::openUrl(QUrl(url)); + }); + } + menu.exec(ui->balancesTable->viewport()->mapToGlobal(pos)); }); } @@ -177,15 +195,22 @@ void MainWindow::setupTransactionsTab() { QMenu menu(this); - menu.addAction("View txid", [=] () { - QMessageBox msg(this); - msg.setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); - msg.setIcon(QMessageBox::Icon::Information); - msg.setWindowTitle("Transaction ID"); - auto txModel = dynamic_cast(ui->transactionsTable->model()); - msg.setText("Transaction ID: \n\n" + txModel->getTxId(index.row())); - msg.exec(); + auto txModel = dynamic_cast(ui->transactionsTable->model()); + QString txid = txModel->getTxId(index.row()); + + menu.addAction("Copy txid to clipboard", [=] () { + QGuiApplication::clipboard()->setText(txid); }); + menu.addAction("View on block explorer", [=] () { + QString url; + if (Settings::getInstance()->isTestnet()) { + url = "https://explorer.testnet.z.cash/tx/" + txid; + } else { + url = "https://explorer.zcha.in/transactions/" + txid; + } + QDesktopServices::openUrl(QUrl(url)); + }); + menu.exec(ui->transactionsTable->viewport()->mapToGlobal(pos)); }); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index c08eb82..8c79e83 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -273,8 +273,8 @@ 0 0 - 825 - 284 + 823 + 226 @@ -428,9 +428,9 @@ - + - 0.0001 ZEC + true @@ -637,7 +637,7 @@ 0 0 889 - 21 + 22 @@ -654,6 +654,7 @@ Help + @@ -688,6 +689,11 @@ false + + + Check github.com for Updates + + @@ -699,7 +705,7 @@ Amount1 Max1 addAddressButton - lineEdit + sendTxFees sendTransactionButton cancelSendButton balancesTable diff --git a/src/precompiled.h b/src/precompiled.h index c9d8b13..87f7900 100644 --- a/src/precompiled.h +++ b/src/precompiled.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/src/rpc.cpp b/src/rpc.cpp index 8871e5d..51c600c 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -287,10 +287,18 @@ void RPC::getInfoThenRefresh() { {"method", "getinfo"} }; - doRPC(payload, [=] (json reply) { - QString statusText = QString::fromStdString("Connected (") - .append(QString::number(reply["blocks"].get())) - .append(")"); + doRPC(payload, [=] (const json& reply) { + // Testnet? + if (reply.find("testnet") != reply.end()) { + Settings::getInstance()->setTestnet(reply["testnet"].get()); + }; + + // Connected? + QString statusText = QString() % + "Connected (" % + (Settings::getInstance()->isTestnet() ? "testnet:" : "mainnet:") % + QString::number(reply["blocks"].get()) % + ")"; main->statusLabel->setText(statusText); QIcon i(":/icons/res/connected.png"); main->statusIcon->setPixmap(i.pixmap(16, 16)); @@ -317,9 +325,9 @@ void RPC::refreshAddresses() { void RPC::refreshBalances() { // 1. Get the Balances getBalance([=] (json reply) { - ui->balSheilded ->setText(QString::fromStdString(reply["private"]) % " ZEC"); - ui->balTransparent ->setText(QString::fromStdString(reply["transparent"]) % " ZEC"); - ui->balTotal ->setText(QString::fromStdString(reply["total"]) % " ZEC"); + ui->balSheilded ->setText(QString::fromStdString(reply["private"]) % " " % Utils::getTokenName()); + ui->balTransparent ->setText(QString::fromStdString(reply["transparent"]) % " " % Utils::getTokenName()); + ui->balTotal ->setText(QString::fromStdString(reply["total"]) % " " % Utils::getTokenName()); }); // 2. Get the UTXOs @@ -364,7 +372,7 @@ void RPC::refreshBalances() { ui->inputsCombo->clear(); auto i = allBalances->constBegin(); while (i != allBalances->constEnd()) { - QString item = i.key() % "(" % QString::number(i.value(), 'g', 8) % " ZEC)"; + QString item = i.key() % "(" % QString::number(i.value(), 'g', 8) % " " % Utils::getTokenName() % ")"; ui->inputsCombo->addItem(item); if (item.startsWith(lastFromAddr)) ui->inputsCombo->setCurrentText(item); diff --git a/src/scripts/mkrelease.sh b/src/scripts/mkrelease.sh index ea44f52..b4a7216 100755 --- a/src/scripts/mkrelease.sh +++ b/src/scripts/mkrelease.sh @@ -40,7 +40,10 @@ cp zcash-qt-wallet bin/zcash-qt-wallet-v$APP_VERSION > /dev/null cp README.md bin/zcash-qt-wallet-v$APP_VERSION > /dev/null cp LICENSE bin/zcash-qt-wallet-v$APP_VERSION > /dev/null cd bin && tar cvf linux-zcash-qt-wallet-v$APP_VERSION.tar.gz zcash-qt-wallet-v$APP_VERSION/ > /dev/null +cd .. echo "[OK]" -echo "Done. Build is bin/linux-zcash-qt-wallet-v$APP_VERSION.tar.gz" \ No newline at end of file +echo "Done. Build is bin/linux-zcash-qt-wallet-v$APP_VERSION.tar.gz" +echo "Package contents:" +tar tf "bin/linux-zcash-qt-wallet-v$APP_VERSION.tar.gz" \ No newline at end of file diff --git a/src/sendtab.cpp b/src/sendtab.cpp index c3981ed..4bfa568 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -3,6 +3,7 @@ #include "ui_confirm.h" #include "settings.h" #include "rpc.h" +#include "utils.h" #include "precompiled.h" @@ -32,6 +33,14 @@ void MainWindow::setupSendTab() { // Max available Checkbox QObject::connect(ui->Max1, &QCheckBox::stateChanged, this, &MainWindow::maxAmountChecked); + // Set up focus enter to set fees + QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int pos) { + if (pos == 1) { + // Set the fees + ui->sendTxFees->setText("0.0001 " + Utils::getTokenName()); + } + }); + } void MainWindow::setDefaultPayFrom() { @@ -66,7 +75,7 @@ void MainWindow::setDefaultPayFrom() { void MainWindow::inputComboTextChanged(const QString& text) { auto bal = rpc->getAllBalances()->value(text.split("(")[0].trimmed()); - auto balFmt = QString::number(bal, 'g', 8) + " ZEC"; + auto balFmt = QString::number(bal, 'g', 8) + " " % Utils::getTokenName(); ui->sendAddressBalance->setText(balFmt); } @@ -246,7 +255,7 @@ void MainWindow::sendButton() { auto Amt = new QLabel(confirm.sendToAddrs); Amt->setObjectName(QString("Amt") % QString::number(i + 1)); - Amt->setText(QString::number(toAddr.second, 'g', 8) % " ZEC"); + Amt->setText(QString::number(toAddr.second, 'g', 8) % " " % Utils::getTokenName()); Amt->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter); confirm.gridLayout->addWidget(Amt, i, 1, 1, 1); } @@ -260,6 +269,9 @@ void MainWindow::sendButton() { // And show it in the confirm dialog confirm.sendFrom->setText(fnSplitAddressForWrap(fromAddr)); + // Fees in the confirm dialog + confirm.feesLabel->setText("Fees: 0.0001 " % Utils::getTokenName()); + // Show the dialog and submit it if the user confirms if (d.exec() == QDialog::Accepted) { rpc->sendZTransaction(params, [=](const json& reply) { diff --git a/src/settings.cpp b/src/settings.cpp index 2de4ee4..350c421 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -65,9 +65,6 @@ void Settings::loadFromFile() { return; } - // If file was found, then setup some defaults - overridePort = "8232"; - QTextStream in(&file); while (!in.atEnd()) { @@ -93,3 +90,11 @@ void Settings::loadFromFile() { file.close(); } + +bool Settings::isTestnet() { + return _isTestnet; +} + +void Settings::setTestnet(bool isTestnet) { + this->_isTestnet = isTestnet; +} \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index a811d3d..58e97a5 100644 --- a/src/settings.h +++ b/src/settings.h @@ -18,6 +18,10 @@ public: double fees() { return 0.0001; } void loadFromSettings(); void loadFromFile(); + + bool isTestnet(); + void setTestnet(bool isTestnet); + private: // This class can only be accessed through Settings::getInstance() Settings() = default; @@ -30,6 +34,8 @@ private: QString password; QString overridePort; + + bool _isTestnet = false; }; #endif // SETTINGS_H \ No newline at end of file diff --git a/src/txtablemodel.cpp b/src/txtablemodel.cpp index 1c1c6bb..c6a1f25 100644 --- a/src/txtablemodel.cpp +++ b/src/txtablemodel.cpp @@ -1,10 +1,10 @@ #include "txtablemodel.h" +#include "utils.h" - TxTableModel::TxTableModel(QObject *parent) - : QAbstractTableModel(parent) - { +TxTableModel::TxTableModel(QObject *parent) + : QAbstractTableModel(parent) { headers << "Category" << "Address" << "Date/Time" << "Amount"; - } +} TxTableModel::~TxTableModel() { delete modeldata; @@ -53,7 +53,7 @@ void TxTableModel::setNewData(QList* 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, 'g', 8) % " ZEC"); + case 3: return QVariant(QString::number(modeldata->at(index.row()).amount, 'g', 8) % " " % Utils::getTokenName()); } } diff --git a/src/ui_confirm.h b/src/ui_confirm.h index adca2f3..ff1fb97 100644 --- a/src/ui_confirm.h +++ b/src/ui_confirm.h @@ -35,7 +35,7 @@ public: QLabel *Amt1; QSpacerItem *verticalSpacer; QFrame *line; - QLabel *label; + QLabel *feesLabel; QDialogButtonBox *buttonBox; void setupUi(QDialog *confirm) @@ -88,10 +88,10 @@ public: verticalLayout->addWidget(line); - label = new QLabel(confirm); - label->setObjectName(QStringLiteral("label")); + feesLabel = new QLabel(confirm); + feesLabel->setObjectName(QStringLiteral("feesLabel")); - verticalLayout->addWidget(label); + verticalLayout->addWidget(feesLabel); buttonBox = new QDialogButtonBox(confirm); buttonBox->setObjectName(QStringLiteral("buttonBox")); @@ -116,7 +116,7 @@ public: sendToAddrs->setTitle(QApplication::translate("confirm", "To", nullptr)); Addr1->setText(QApplication::translate("confirm", "TextLabel", nullptr)); Amt1->setText(QApplication::translate("confirm", "TextLabel", nullptr)); - label->setText(QApplication::translate("confirm", "Fees: 0.0001 ZEC", nullptr)); + feesLabel->setText(QString()); } // retranslateUi }; diff --git a/src/ui_mainwindow.h b/src/ui_mainwindow.h index 4989951..2070bea 100644 --- a/src/ui_mainwindow.h +++ b/src/ui_mainwindow.h @@ -46,6 +46,7 @@ public: QAction *actionSettings; QAction *actionDonate; QAction *actionImport_Private_Keys; + QAction *actionCheck_for_Updates; QWidget *centralWidget; QGridLayout *gridLayout_3; QTabWidget *tabWidget; @@ -104,7 +105,7 @@ public: QVBoxLayout *verticalLayout_10; QHBoxLayout *horizontalLayout_14; QLabel *label_7; - QLineEdit *lineEdit; + QLineEdit *sendTxFees; QSpacerItem *horizontalSpacer_5; QHBoxLayout *horizontalLayout_6; QSpacerItem *horizontalSpacer; @@ -153,6 +154,8 @@ public: actionImport_Private_Keys = new QAction(MainWindow); actionImport_Private_Keys->setObjectName(QStringLiteral("actionImport_Private_Keys")); actionImport_Private_Keys->setVisible(false); + actionCheck_for_Updates = new QAction(MainWindow); + actionCheck_for_Updates->setObjectName(QStringLiteral("actionCheck_for_Updates")); centralWidget = new QWidget(MainWindow); centralWidget->setObjectName(QStringLiteral("centralWidget")); gridLayout_3 = new QGridLayout(centralWidget); @@ -349,7 +352,7 @@ public: sendToScrollArea->setWidgetResizable(true); sendToWidgets = new QWidget(); sendToWidgets->setObjectName(QStringLiteral("sendToWidgets")); - sendToWidgets->setGeometry(QRect(0, 0, 825, 284)); + sendToWidgets->setGeometry(QRect(0, 0, 823, 226)); sendToLayout = new QVBoxLayout(sendToWidgets); sendToLayout->setSpacing(6); sendToLayout->setContentsMargins(11, 11, 11, 11); @@ -450,11 +453,11 @@ public: horizontalLayout_14->addWidget(label_7); - lineEdit = new QLineEdit(groupBox_7); - lineEdit->setObjectName(QStringLiteral("lineEdit")); - lineEdit->setReadOnly(true); + sendTxFees = new QLineEdit(groupBox_7); + sendTxFees->setObjectName(QStringLiteral("sendTxFees")); + sendTxFees->setReadOnly(true); - horizontalLayout_14->addWidget(lineEdit); + horizontalLayout_14->addWidget(sendTxFees); horizontalSpacer_5 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); @@ -605,7 +608,7 @@ public: MainWindow->setCentralWidget(centralWidget); menuBar = new QMenuBar(MainWindow); menuBar->setObjectName(QStringLiteral("menuBar")); - menuBar->setGeometry(QRect(0, 0, 889, 21)); + menuBar->setGeometry(QRect(0, 0, 889, 22)); menuBalance = new QMenu(menuBar); menuBalance->setObjectName(QStringLiteral("menuBalance")); menuHelp = new QMenu(menuBar); @@ -621,8 +624,8 @@ public: QWidget::setTabOrder(Address1, Amount1); QWidget::setTabOrder(Amount1, Max1); QWidget::setTabOrder(Max1, addAddressButton); - QWidget::setTabOrder(addAddressButton, lineEdit); - QWidget::setTabOrder(lineEdit, sendTransactionButton); + QWidget::setTabOrder(addAddressButton, sendTxFees); + QWidget::setTabOrder(sendTxFees, sendTransactionButton); QWidget::setTabOrder(sendTransactionButton, cancelSendButton); QWidget::setTabOrder(cancelSendButton, balancesTable); QWidget::setTabOrder(balancesTable, rdioZAddr); @@ -639,6 +642,7 @@ public: menuBalance->addSeparator(); menuBalance->addAction(actionExit); menuHelp->addAction(actionDonate); + menuHelp->addAction(actionCheck_for_Updates); menuHelp->addAction(actionAbout); retranslateUi(MainWindow); @@ -657,6 +661,7 @@ public: actionSettings->setText(QApplication::translate("MainWindow", "Settings", nullptr)); actionDonate->setText(QApplication::translate("MainWindow", "Donate", nullptr)); actionImport_Private_Keys->setText(QApplication::translate("MainWindow", "Import Private Keys", nullptr)); + actionCheck_for_Updates->setText(QApplication::translate("MainWindow", "Check github.com for Updates", nullptr)); groupBox->setTitle(QApplication::translate("MainWindow", "Summary", nullptr)); label->setText(QApplication::translate("MainWindow", "Shielded", nullptr)); balSheilded->setText(QString()); @@ -679,7 +684,7 @@ public: addAddressButton->setText(QApplication::translate("MainWindow", "Add Address", nullptr)); groupBox_7->setTitle(QApplication::translate("MainWindow", "Fees", nullptr)); label_7->setText(QApplication::translate("MainWindow", "Fee", nullptr)); - lineEdit->setText(QApplication::translate("MainWindow", "0.0001 ZEC", nullptr)); + sendTxFees->setText(QString()); sendTransactionButton->setText(QApplication::translate("MainWindow", "Send", nullptr)); cancelSendButton->setText(QApplication::translate("MainWindow", "Cancel", nullptr)); tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("MainWindow", "Send", nullptr)); diff --git a/utils.cpp b/utils.cpp index 4021a08..a0c5b1f 100644 --- a/utils.cpp +++ b/utils.cpp @@ -1,3 +1,12 @@ #include "utils.h" +#include "settings.h" -const QString Utils::txidStatusMessage = QString("Tx submitted (right click to copy) txid:"); \ No newline at end of file +const QString Utils::txidStatusMessage = QString("Tx submitted (right click to copy) txid:"); + +const QString Utils::getTokenName() { + if (Settings::getInstance()->isTestnet()) { + return "TAZ"; + } else { + return "ZEC"; + } +} \ No newline at end of file diff --git a/utils.h b/utils.h index 7fca4e7..db0b139 100644 --- a/utils.h +++ b/utils.h @@ -7,6 +7,8 @@ class Utils { public: static const QString txidStatusMessage; + + static const QString getTokenName(); private: Utils() = delete; };