diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ba41ba3..05b5f1e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -397,7 +397,9 @@ void MainWindow::setupTransactionsTab() { QMenu menu(this); auto txModel = dynamic_cast(ui->transactionsTable->model()); + QString txid = txModel->getTxId(index.row()); + QString memo = txModel->getMemo(index.row()); menu.addAction("Copy txid", [=] () { QGuiApplication::clipboard()->setText(txid); @@ -412,6 +414,11 @@ void MainWindow::setupTransactionsTab() { } QDesktopServices::openUrl(QUrl(url)); }); + if (!memo.isEmpty()) { + menu.addAction("View Memo", [=] () { + QMessageBox::information(this, "Memo", memo, QMessageBox::Ok); + }); + } menu.exec(ui->transactionsTable->viewport()->mapToGlobal(pos)); }); diff --git a/src/memodialog.ui b/src/memodialog.ui new file mode 100644 index 0000000..0cbe59a --- /dev/null +++ b/src/memodialog.ui @@ -0,0 +1,97 @@ + + + MemoDialog + + + + 0 + 0 + 618 + 115 + + + + Dialog + + + + + + + + + Memo + + + + + + + 6 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + buttonBox + accepted() + MemoDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MemoDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/rpc.cpp b/src/rpc.cpp index 016a263..fa8e942 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -347,11 +347,23 @@ void RPC::refreshReceivedZTrans(QList zaddrs) { // Process all txids, removing duplicates. This can happen if the same address // appears multiple times in a single tx's outputs. QSet txids; + QMap memos; for (auto it = zaddrTxids->constBegin(); it != zaddrTxids->constEnd(); it++) { for (auto& i : it.value().get()) { // Filter out change txs - if (! i["change"].get()) - txids.insert(QString::fromStdString(i["txid"].get())); + if (! i["change"].get()) { + auto txid = QString::fromStdString(i["txid"].get()); + txids.insert(txid); + + // Check for Memos + QString memoBytes = QString::fromStdString(i["memo"].get()); + if (!memoBytes.startsWith("f600")) { + QString memo(QByteArray::fromHex( + QByteArray::fromStdString(i["memo"].get()))); + if (!memo.trimmed().isEmpty()) + memos[txid] = memo; + } + } } } @@ -391,9 +403,10 @@ void RPC::refreshReceivedZTrans(QList zaddrs) { } auto amount = i["amount"].get(); - auto confirmations = txidInfo["confirmations"].get(); + auto confirmations = txidInfo["confirmations"].get(); - TransactionItem tx{ QString("receive"), timestamp, zaddr, txid, amount, confirmations, "" }; + TransactionItem tx{ QString("receive"), timestamp, zaddr, txid, amount, + confirmations, "", memos.value(txid, "") }; txdata.push_front(tx); } } @@ -584,8 +597,7 @@ void RPC::refreshTransactions() { QString::fromStdString(it["txid"]), it["amount"].get() + fee, it["confirmations"].get(), - "" - }; + "", "" }; txdata.push_back(tx); } diff --git a/src/rpc.h b/src/rpc.h index dd9b3dd..5c19132 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -21,6 +21,7 @@ struct TransactionItem { double amount; unsigned long confirmations; QString fromAddr; + QString memo; }; class RPC diff --git a/src/sendtab.cpp b/src/sendtab.cpp index fc1c502..41a0102 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -1,6 +1,7 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "ui_confirm.h" +#include "ui_memodialog.h" #include "settings.h" #include "rpc.h" #include "utils.h" @@ -236,13 +237,30 @@ void MainWindow::memoButtonClicked(int number) { QString currentMemo = memoTxt->text(); // Ref to see if the button was clicked - bool ok; - QString newMemo = QInputDialog::getText(this, "Memo", - "Please type a memo to include with the amount. The memo will be visible to the recepient", - QLineEdit::Normal, currentMemo, &ok); - if (ok) { - memoTxt->setText(newMemo); + // bool ok; + // QString newMemo = QInputDialog::getText(this, "Memo", + // "Please type a memo to include with the amount. The memo will be visible to the recepient", + // QLineEdit::Normal, currentMemo, &ok); + Ui_MemoDialog memoDialog; + QDialog dialog(this); + memoDialog.setupUi(&dialog); + + QObject::connect(memoDialog.memoTxt, &QLineEdit::textChanged, [=] (QString txt) { + memoDialog.memoSize->setText(QString::number(txt.toUtf8().size()) + "/512"); + + memoDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(txt.toUtf8().size() <= 512); + if (txt.toUtf8().size() > 512) { + memoDialog.memoSize->setStyleSheet("color: red;"); + } else { + memoDialog.memoSize->setStyleSheet(""); + } + }); + memoDialog.memoTxt->setText(currentMemo); + + if (dialog.exec() == QDialog::Accepted) { + memoTxt->setText(memoDialog.memoTxt->text()); } + } void MainWindow::removeExtraAddresses() { diff --git a/src/senttxstore.cpp b/src/senttxstore.cpp index 256ced4..656fe05 100644 --- a/src/senttxstore.cpp +++ b/src/senttxstore.cpp @@ -42,7 +42,7 @@ QList SentTxStore::readSentTxFile() { sentTx["address"].toString(), sentTx["txid"].toString(), sentTx["amount"].toDouble() + sentTx["fee"].toDouble(), - 0, sentTx["from"].toString()}; + 0, sentTx["from"].toString(), ""}; items.push_back(t); } diff --git a/src/settings.cpp b/src/settings.cpp index c7fd3a2..6f90042 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -101,6 +101,8 @@ bool Settings::loadFromFile() { #ifdef Q_OS_LINUX confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, ".zcash/zcash.conf"); +#elif defined(Q_OS_DARWIN) + confLocation = QStandardPaths::locate(QStandardPaths::HomeLocation, "/Library/Application Support/Zcash/zcash.conf"); #else confLocation = QStandardPaths::locate(QStandardPaths::AppDataLocation, "../../Zcash/zcash.conf"); #endif diff --git a/src/txtablemodel.cpp b/src/txtablemodel.cpp index 7a9eb97..f86c860 100644 --- a/src/txtablemodel.cpp +++ b/src/txtablemodel.cpp @@ -131,4 +131,8 @@ void TxTableModel::updateAllData() { QString TxTableModel::getTxId(int row) { return modeldata->at(row).txid; +} + +QString TxTableModel::getMemo(int row) { + return modeldata->at(row).memo; } \ No newline at end of file diff --git a/src/txtablemodel.h b/src/txtablemodel.h index b03e7a2..27de88f 100644 --- a/src/txtablemodel.h +++ b/src/txtablemodel.h @@ -16,6 +16,7 @@ public: void addZRecvData(const QList& data); QString getTxId(int row); + QString getMemo(int row); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; diff --git a/src/ui_memodialog.h b/src/ui_memodialog.h new file mode 100644 index 0000000..bd00d49 --- /dev/null +++ b/src/ui_memodialog.h @@ -0,0 +1,90 @@ +/******************************************************************************** +** Form generated from reading UI file 'memodialog.ui' +** +** Created by: Qt User Interface Compiler version 5.11.2 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_MEMODIALOG_H +#define UI_MEMODIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_MemoDialog +{ +public: + QGridLayout *gridLayout; + QLineEdit *memoTxt; + QLabel *label; + QLabel *memoSize; + QDialogButtonBox *buttonBox; + QSpacerItem *verticalSpacer; + + void setupUi(QDialog *MemoDialog) + { + if (MemoDialog->objectName().isEmpty()) + MemoDialog->setObjectName(QStringLiteral("MemoDialog")); + MemoDialog->resize(618, 115); + gridLayout = new QGridLayout(MemoDialog); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + memoTxt = new QLineEdit(MemoDialog); + memoTxt->setObjectName(QStringLiteral("memoTxt")); + + gridLayout->addWidget(memoTxt, 1, 0, 1, 2); + + label = new QLabel(MemoDialog); + label->setObjectName(QStringLiteral("label")); + + gridLayout->addWidget(label, 0, 0, 1, 1); + + memoSize = new QLabel(MemoDialog); + memoSize->setObjectName(QStringLiteral("memoSize")); + memoSize->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + + gridLayout->addWidget(memoSize, 0, 1, 1, 1); + + buttonBox = new QDialogButtonBox(MemoDialog); + buttonBox->setObjectName(QStringLiteral("buttonBox")); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + + gridLayout->addWidget(buttonBox, 3, 0, 1, 2); + + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + gridLayout->addItem(verticalSpacer, 2, 0, 1, 2); + + + retranslateUi(MemoDialog); + QObject::connect(buttonBox, SIGNAL(accepted()), MemoDialog, SLOT(accept())); + QObject::connect(buttonBox, SIGNAL(rejected()), MemoDialog, SLOT(reject())); + + QMetaObject::connectSlotsByName(MemoDialog); + } // setupUi + + void retranslateUi(QDialog *MemoDialog) + { + MemoDialog->setWindowTitle(QApplication::translate("MemoDialog", "Dialog", nullptr)); + label->setText(QApplication::translate("MemoDialog", "Memo", nullptr)); + memoSize->setText(QApplication::translate("MemoDialog", "6 / 512", nullptr)); + } // retranslateUi + +}; + +namespace Ui { + class MemoDialog: public Ui_MemoDialog {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MEMODIALOG_H diff --git a/zec-qt-wallet.pro b/zec-qt-wallet.pro index 1b40335..2c71f05 100644 --- a/zec-qt-wallet.pro +++ b/zec-qt-wallet.pro @@ -76,6 +76,7 @@ FORMS += \ src/confirm.ui \ src/turnstile.ui \ src/turnstileprogress.ui + src/memodialog.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin