merge
This commit is contained in:
12
README.md
12
README.md
@@ -9,8 +9,8 @@ Head over to the releases page and grab the latest binary. https://github.com/ad
|
|||||||
### Linux
|
### Linux
|
||||||
Extract and run the binary
|
Extract and run the binary
|
||||||
```
|
```
|
||||||
tar -xvf zec-qt-wallet-v0.2.8.tar.gz
|
tar -xvf zec-qt-wallet-v0.2.9.tar.gz
|
||||||
./zec-qt-wallet-v0.2.8/zec-qt-wallet
|
./zec-qt-wallet-v0.2.9/zec-qt-wallet
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
@@ -24,7 +24,7 @@ There is currently no official zcashd build for Windows so Windows users may eit
|
|||||||
|
|
||||||
Alternatively run zcashd inside [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
|
Alternatively run zcashd inside [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
|
||||||
|
|
||||||
For all installations zcashd needs to run with RPC enabled (`server=1`, which is the default) and with a RPC username/password set. Add the following entries into `~/.zcash/zcash.conf` for Linux or` C:\Users\your-username\AppData\Roaming\Zcash\zcash.conf` on Windows replacing the default values with a strong password. zec-qt-wallet should detect these settings but if that fails you may edit the connection settings manually via the `File->Settings` menu.
|
For all installations zcashd needs to run with RPC enabled (`server=1`, which is the default) and with a RPC username/password set. Add the following entries into `~/.zcash/zcash.conf` for Linux or` C:\Users\your-username\AppData\Roaming\Zcash\zcash.conf` on Windows replacing the default values with a strong password. zec-qt-wallet should detect these settings but if that fails you may edit the connection settings manually via the `Edit->Settings` menu.
|
||||||
|
|
||||||
```
|
```
|
||||||
rpcuser=username
|
rpcuser=username
|
||||||
@@ -41,7 +41,7 @@ https://z.cash/downloads/sprout-proving.key
|
|||||||
https://z.cash/downloads/sprout-verifying.key
|
https://z.cash/downloads/sprout-verifying.key
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are running zcashd on WSL, then please set the connection parameters in the `File->Settings` menu.
|
If you are running zcashd on WSL, then please set the connection parameters in the `Edit->Settings` menu.
|
||||||
|
|
||||||
## Compiling from source
|
## Compiling from source
|
||||||
zec-qt-wallet is written in C++ 14, and can be compiled with g++/clang++/visual c++. It also depends on Qt5, which you can get from here: https://www.qt.io/download
|
zec-qt-wallet is written in C++ 14, and can be compiled with g++/clang++/visual c++. It also depends on Qt5, which you can get from here: https://www.qt.io/download
|
||||||
@@ -49,6 +49,8 @@ zec-qt-wallet is written in C++ 14, and can be compiled with g++/clang++/visual
|
|||||||
### Compiling on Linux
|
### Compiling on Linux
|
||||||
|
|
||||||
```
|
```
|
||||||
|
sudo apt install libgl1-mesa-dev
|
||||||
|
|
||||||
git clone https://github.com/adityapk00/zec-qt-wallet.git
|
git clone https://github.com/adityapk00/zec-qt-wallet.git
|
||||||
cd zec-qt-wallet
|
cd zec-qt-wallet
|
||||||
/path/to/qt5/bin/qmake zec-qt-wallet.pro CONFIG+=debug
|
/path/to/qt5/bin/qmake zec-qt-wallet.pro CONFIG+=debug
|
||||||
@@ -64,7 +66,7 @@ From the VS Tools command prompt
|
|||||||
```
|
```
|
||||||
git clone https://github.com/adityapk00/zec-qt-wallet.git
|
git clone https://github.com/adityapk00/zec-qt-wallet.git
|
||||||
cd zec-qt-wallet
|
cd zec-qt-wallet
|
||||||
c:\Qt5\bin\qmake.exe zec-qt-wallet.pro CONFIG+=debug
|
c:\Qt5\bin\qmake.exe zec-qt-wallet.pro -spec win32-msvc CONFIG+=debug
|
||||||
nmake
|
nmake
|
||||||
|
|
||||||
debug\zec-qt-wallet.exe
|
debug\zec-qt-wallet.exe
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<file>res/Ubuntu-R.ttf</file>
|
<file>res/Ubuntu-R.ttf</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/icons">
|
<qresource prefix="/icons">
|
||||||
<file>res/connected.png</file>
|
<file>res/connected.gif</file>
|
||||||
<file>res/loading.gif</file>
|
<file>res/loading.gif</file>
|
||||||
<file>res/icon.ico</file>
|
<file>res/icon.ico</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 72 KiB |
BIN
res/connected.gif
Normal file
BIN
res/connected.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.3 KiB |
@@ -10,83 +10,56 @@ AddressBookModel::AddressBookModel(QTableView *parent)
|
|||||||
headers << "Label" << "Address";
|
headers << "Label" << "Address";
|
||||||
|
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
loadDataFromStorage();
|
loadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressBookModel::~AddressBookModel() {
|
AddressBookModel::~AddressBookModel() {
|
||||||
if (labels != nullptr)
|
saveData();
|
||||||
saveDataToStorage();
|
|
||||||
|
|
||||||
delete labels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookModel::saveDataToStorage() {
|
void AddressBookModel::saveData() {
|
||||||
QFile file(writeableFile());
|
AddressBook::writeToStorage(labels);
|
||||||
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
|
||||||
QDataStream out(&file); // we will serialize the data into the file
|
|
||||||
out << QString("v1") << *labels;
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
// Save column positions
|
// Save column positions
|
||||||
QSettings().setValue("addresstablegeometry", parent->horizontalHeader()->saveState());
|
QSettings().setValue("addresstablegeometry", parent->horizontalHeader()->saveState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AddressBookModel::loadDataFromStorage() {
|
void AddressBookModel::loadData() {
|
||||||
QFile file(writeableFile());
|
labels = AddressBook::readFromStorage();
|
||||||
|
|
||||||
delete labels;
|
|
||||||
labels = new QList<QPair<QString, QString>>();
|
|
||||||
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
QDataStream in(&file); // read the data serialized from the file
|
|
||||||
QString version;
|
|
||||||
in >> version >> *labels;
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
parent->horizontalHeader()->restoreState(QSettings().value("addresstablegeometry").toByteArray());
|
parent->horizontalHeader()->restoreState(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::writeToStorage(labels);
|
||||||
|
|
||||||
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;
|
||||||
labels->removeAt(row);
|
|
||||||
|
|
||||||
dataChanged(index(0, 0), index(labels->size()-1, columnCount(index(0,0))-1));
|
labels.removeAt(row);
|
||||||
|
AddressBook::writeToStorage(labels);
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressBookModel::writeableFile() {
|
|
||||||
auto filename = QStringLiteral("addresslabels.dat");
|
|
||||||
|
|
||||||
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
|
||||||
if (!dir.exists())
|
|
||||||
QDir().mkpath(dir.absolutePath());
|
|
||||||
|
|
||||||
if (Settings::getInstance()->isTestnet()) {
|
|
||||||
return dir.filePath("testnet-" % filename);
|
|
||||||
} else {
|
|
||||||
return dir.filePath(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int AddressBookModel::rowCount(const QModelIndex&) const {
|
int AddressBookModel::rowCount(const QModelIndex&) const {
|
||||||
if (labels == nullptr) return 0;
|
return labels.size();
|
||||||
return labels->size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AddressBookModel::columnCount(const QModelIndex&) const {
|
int AddressBookModel::columnCount(const QModelIndex&) const {
|
||||||
@@ -97,12 +70,12 @@ int AddressBookModel::columnCount(const QModelIndex&) const {
|
|||||||
QVariant AddressBookModel::data(const QModelIndex &index, int role) const {
|
QVariant AddressBookModel::data(const QModelIndex &index, int role) const {
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
switch(index.column()) {
|
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 {
|
||||||
@@ -117,6 +90,7 @@ 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);
|
||||||
|
|
||||||
AddressBookModel model(ab.addresses);
|
AddressBookModel model(ab.addresses);
|
||||||
ab.addresses->setModel(&model);
|
ab.addresses->setModel(&model);
|
||||||
@@ -126,6 +100,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
ab.buttonBox->button(QDialogButtonBox::Ok)->setText("Pick");
|
ab.buttonBox->button(QDialogButtonBox::Ok)->setText("Pick");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect the dialog's closing to updating the label address completor
|
||||||
|
QObject::connect(&d, &QDialog::finished, [=] (auto) { parent->updateLabelsAutoComplete(); });
|
||||||
|
|
||||||
// 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 && Utils::isValidAddress(target->text())) {
|
if (target != nullptr && Utils::isValidAddress(target->text())) {
|
||||||
ab.addr->setText(target->text());
|
ab.addr->setText(target->text());
|
||||||
@@ -145,13 +122,18 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr) {
|
||||||
|
target->setText(label % "/" % addr);
|
||||||
|
};
|
||||||
|
|
||||||
// Double-Click picks the item
|
// Double-Click picks the item
|
||||||
QObject::connect(ab.addresses, &QTableView::doubleClicked, [&] (auto index) {
|
QObject::connect(ab.addresses, &QTableView::doubleClicked, [&] (auto index) {
|
||||||
if (index.row() < 0) return;
|
if (index.row() < 0) return;
|
||||||
|
|
||||||
|
QString lbl = model.itemAt(index.row()).first;
|
||||||
QString addr = model.itemAt(index.row()).second;
|
QString addr = model.itemAt(index.row()).second;
|
||||||
d.accept();
|
d.accept();
|
||||||
target->setText(addr);
|
fnSetTargetLabelAddr(target, lbl, addr);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Right-Click
|
// Right-Click
|
||||||
@@ -161,13 +143,15 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
|
|
||||||
if (index.row() < 0) return;
|
if (index.row() < 0) return;
|
||||||
|
|
||||||
|
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", [&] () {
|
||||||
target->setText(addr);
|
d.accept();
|
||||||
|
fnSetTargetLabelAddr(target, lbl, addr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +170,46 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
|||||||
if (d.exec() == QDialog::Accepted && target != nullptr) {
|
if (d.exec() == QDialog::Accepted && target != nullptr) {
|
||||||
auto selection = ab.addresses->selectionModel();
|
auto selection = ab.addresses->selectionModel();
|
||||||
if (selection->hasSelection()) {
|
if (selection->hasSelection()) {
|
||||||
target->setText(model.itemAt(selection->selectedRows().at(0).row()).second);
|
auto item = model.itemAt(selection->selectedRows().at(0).row());
|
||||||
|
fnSetTargetLabelAddr(target, item.first, item.second);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPair<QString, QString>> AddressBook::readFromStorage() {
|
||||||
|
QFile file(AddressBook::writeableFile());
|
||||||
|
|
||||||
|
QList<QPair<QString, QString>> labels;
|
||||||
|
|
||||||
|
file.open(QIODevice::ReadOnly);
|
||||||
|
QDataStream in(&file); // read the data serialized from the file
|
||||||
|
QString version;
|
||||||
|
in >> version >> labels;
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AddressBook::writeToStorage(QList<QPair<QString, QString>> labels) {
|
||||||
|
QFile file(AddressBook::writeableFile());
|
||||||
|
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
||||||
|
QDataStream out(&file); // we will serialize the data into the file
|
||||||
|
out << QString("v1") << labels;
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AddressBook::writeableFile() {
|
||||||
|
auto filename = QStringLiteral("addresslabels.dat");
|
||||||
|
|
||||||
|
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||||
|
if (!dir.exists())
|
||||||
|
QDir().mkpath(dir.absolutePath());
|
||||||
|
|
||||||
|
if (Settings::getInstance()->isTestnet()) {
|
||||||
|
return dir.filePath("testnet-" % filename);
|
||||||
|
} else {
|
||||||
|
return dir.filePath(filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,19 +21,22 @@ public:
|
|||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadDataFromStorage();
|
void loadData();
|
||||||
void saveDataToStorage();
|
void saveData();
|
||||||
|
|
||||||
QString writeableFile();
|
|
||||||
|
|
||||||
QTableView* parent;
|
QTableView* parent;
|
||||||
QList<QPair<QString, QString>>* labels = nullptr;
|
QList<QPair<QString, QString>> labels;
|
||||||
QStringList headers;
|
QStringList headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddressBook {
|
class AddressBook {
|
||||||
public:
|
public:
|
||||||
static void open(MainWindow* parent, QLineEdit* target = nullptr);
|
static void open(MainWindow* parent, QLineEdit* target = nullptr);
|
||||||
|
|
||||||
|
static QList<QPair<QString, QString>> readFromStorage();
|
||||||
|
static void writeToStorage(QList<QPair<QString, QString>> labels);
|
||||||
|
|
||||||
|
static QString writeableFile();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ADDRESSBOOK_H
|
#endif // ADDRESSBOOK_H
|
||||||
@@ -18,7 +18,7 @@ int main(int argc, char *argv[])
|
|||||||
qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false));
|
qApp->setFont(QFont("Ubuntu", 11, QFont::Normal, false));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::srand(std::time(nullptr));
|
std::srand(static_cast<unsigned int>(std::time(nullptr)));
|
||||||
Settings::init();
|
Settings::init();
|
||||||
Settings::getInstance()->setExecName(argv[0]);
|
Settings::getInstance()->setExecName(argv[0]);
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ void MainWindow::turnstileProgress() {
|
|||||||
Ui_TurnstileProgress progress;
|
Ui_TurnstileProgress progress;
|
||||||
QDialog d(this);
|
QDialog d(this);
|
||||||
progress.setupUi(&d);
|
progress.setupUi(&d);
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||||
progress.msgIcon->setPixmap(icon.pixmap(64, 64));
|
progress.msgIcon->setPixmap(icon.pixmap(64, 64));
|
||||||
@@ -189,6 +190,7 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
|
|||||||
Ui_Turnstile turnstile;
|
Ui_Turnstile turnstile;
|
||||||
QDialog d(this);
|
QDialog d(this);
|
||||||
turnstile.setupUi(&d);
|
turnstile.setupUi(&d);
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
|
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
|
||||||
turnstile.msgIcon->setPixmap(icon.pixmap(64, 64));
|
turnstile.msgIcon->setPixmap(icon.pixmap(64, 64));
|
||||||
@@ -240,8 +242,7 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
|
|||||||
if (!fromAddr.isEmpty())
|
if (!fromAddr.isEmpty())
|
||||||
turnstile.migrateZaddList->setCurrentText(fromAddr);
|
turnstile.migrateZaddList->setCurrentText(fromAddr);
|
||||||
|
|
||||||
fnUpdateSproutBalance(turnstile.migrateZaddList->currentText());
|
fnUpdateSproutBalance(turnstile.migrateZaddList->currentText());
|
||||||
|
|
||||||
|
|
||||||
// Combo box selection event
|
// Combo box selection event
|
||||||
QObject::connect(turnstile.migrateZaddList, &QComboBox::currentTextChanged, fnUpdateSproutBalance);
|
QObject::connect(turnstile.migrateZaddList, &QComboBox::currentTextChanged, fnUpdateSproutBalance);
|
||||||
@@ -349,6 +350,7 @@ void MainWindow::setupSettingsModal() {
|
|||||||
QDialog settingsDialog(this);
|
QDialog settingsDialog(this);
|
||||||
Ui_Settings settings;
|
Ui_Settings settings;
|
||||||
settings.setupUi(&settingsDialog);
|
settings.setupUi(&settingsDialog);
|
||||||
|
Settings::saveRestore(&settingsDialog);
|
||||||
|
|
||||||
// Setup save sent check box
|
// Setup save sent check box
|
||||||
QObject::connect(settings.chkSaveTxs, &QCheckBox::stateChanged, [=](auto checked) {
|
QObject::connect(settings.chkSaveTxs, &QCheckBox::stateChanged, [=](auto checked) {
|
||||||
@@ -412,7 +414,7 @@ void MainWindow::setupSettingsModal() {
|
|||||||
auto cl = new ConnectionLoader(this, rpc);
|
auto cl = new ConnectionLoader(this, rpc);
|
||||||
cl->loadConnection();
|
cl->loadConnection();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,6 +451,10 @@ void MainWindow::postToZBoard() {
|
|||||||
QDialog d(this);
|
QDialog d(this);
|
||||||
Ui_zboard zb;
|
Ui_zboard zb;
|
||||||
zb.setupUi(&d);
|
zb.setupUi(&d);
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
|
if (rpc->getConnection() == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
// Fill the from field with sapling addresses.
|
// Fill the from field with sapling addresses.
|
||||||
for (auto i = rpc->getAllBalances()->keyBegin(); i != rpc->getAllBalances()->keyEnd(); i++) {
|
for (auto i = rpc->getAllBalances()->keyBegin(); i != rpc->getAllBalances()->keyEnd(); i++) {
|
||||||
@@ -457,6 +463,18 @@ void MainWindow::postToZBoard() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMap<QString, QString> topics;
|
||||||
|
// Insert the main topic automatically
|
||||||
|
topics.insert("#Main_Area", Utils::getZboardAddr());
|
||||||
|
zb.topicsList->addItem(topics.firstKey());
|
||||||
|
// Then call the API to get topics, and if it returns successfully, then add the rest of the topics
|
||||||
|
rpc->getZboardTopics([&](QMap<QString, QString> topicsMap) {
|
||||||
|
for (auto t : topicsMap.keys()) {
|
||||||
|
topics.insert(t, topicsMap[t]);
|
||||||
|
zb.topicsList->addItem(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Testnet warning
|
// Testnet warning
|
||||||
if (Settings::getInstance()->isTestnet()) {
|
if (Settings::getInstance()->isTestnet()) {
|
||||||
zb.testnetWarning->setText("You are on testnet, your post won't actually appear on z-board.net");
|
zb.testnetWarning->setText("You are on testnet, your post won't actually appear on z-board.net");
|
||||||
@@ -465,10 +483,20 @@ void MainWindow::postToZBoard() {
|
|||||||
zb.testnetWarning->setText("");
|
zb.testnetWarning->setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRegExpValidator v(QRegExp("^[a-zA-Z0-9_]{3,20}$"), zb.postAs);
|
||||||
|
zb.postAs->setValidator(&v);
|
||||||
|
|
||||||
zb.feeAmount->setText(Settings::getInstance()->getZECUSDDisplayFormat(Utils::getZboardAmount() + Utils::getMinerFee()));
|
zb.feeAmount->setText(Settings::getInstance()->getZECUSDDisplayFormat(Utils::getZboardAmount() + Utils::getMinerFee()));
|
||||||
|
|
||||||
QObject::connect(zb.memoTxt, &QPlainTextEdit::textChanged, [=] () {
|
auto fnBuildNameMemo = [=]() -> QString {
|
||||||
QString txt = zb.memoTxt->toPlainText();
|
auto memo = zb.memoTxt->toPlainText().trimmed();
|
||||||
|
if (!zb.postAs->text().trimmed().isEmpty())
|
||||||
|
memo = zb.postAs->text().trimmed() + ":: " + memo;
|
||||||
|
return memo;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto fnUpdateMemoSize = [=]() {
|
||||||
|
QString txt = fnBuildNameMemo();
|
||||||
zb.memoSize->setText(QString::number(txt.toUtf8().size()) + "/512");
|
zb.memoSize->setText(QString::number(txt.toUtf8().size()) + "/512");
|
||||||
|
|
||||||
if (txt.toUtf8().size() <= 512) {
|
if (txt.toUtf8().size() <= 512) {
|
||||||
@@ -477,14 +505,26 @@ void MainWindow::postToZBoard() {
|
|||||||
zb.memoSize->setStyleSheet("");
|
zb.memoSize->setStyleSheet("");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Overweight
|
// Overweight
|
||||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
zb.memoSize->setStyleSheet("color: red;");
|
zb.memoSize->setStyleSheet("color: red;");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
// Disallow blank memos
|
||||||
|
if (zb.memoTxt->toPlainText().trimmed().isEmpty()) {
|
||||||
|
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Memo text changed
|
||||||
|
QObject::connect(zb.memoTxt, &QPlainTextEdit::textChanged, fnUpdateMemoSize);
|
||||||
|
QObject::connect(zb.postAs, &QLineEdit::textChanged, fnUpdateMemoSize);
|
||||||
|
|
||||||
zb.memoTxt->setFocus();
|
zb.memoTxt->setFocus();
|
||||||
|
fnUpdateMemoSize();
|
||||||
|
|
||||||
if (d.exec() == QDialog::Accepted) {
|
if (d.exec() == QDialog::Accepted) {
|
||||||
// Create a transaction.
|
// Create a transaction.
|
||||||
@@ -501,7 +541,8 @@ void MainWindow::postToZBoard() {
|
|||||||
if (!zb.postAs->text().trimmed().isEmpty())
|
if (!zb.postAs->text().trimmed().isEmpty())
|
||||||
memo = zb.postAs->text().trimmed() + ":: " + memo;
|
memo = zb.postAs->text().trimmed() + ":: " + memo;
|
||||||
|
|
||||||
tx.toAddrs.push_back(ToFields{ Utils::getZboardAddr(), Utils::getZboardAmount(), memo, memo.toUtf8().toHex() });
|
auto toAddr = topics[zb.topicsList->currentText()];
|
||||||
|
tx.toAddrs.push_back(ToFields{ toAddr, Utils::getZboardAmount(), memo, memo.toUtf8().toHex() });
|
||||||
tx.fee = Utils::getMinerFee();
|
tx.fee = Utils::getMinerFee();
|
||||||
|
|
||||||
json params = json::array();
|
json params = json::array();
|
||||||
@@ -520,7 +561,6 @@ void MainWindow::postToZBoard() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::doImport(QList<QString>* keys) {
|
void MainWindow::doImport(QList<QString>* keys) {
|
||||||
qDebug() << keys->size();
|
|
||||||
if (keys->isEmpty()) {
|
if (keys->isEmpty()) {
|
||||||
delete keys;
|
delete keys;
|
||||||
ui->statusBar->showMessage("Private key import rescan finished");
|
ui->statusBar->showMessage("Private key import rescan finished");
|
||||||
@@ -545,6 +585,7 @@ void MainWindow::importPrivKey() {
|
|||||||
QDialog d(this);
|
QDialog d(this);
|
||||||
Ui_PrivKey pui;
|
Ui_PrivKey pui;
|
||||||
pui.setupUi(&d);
|
pui.setupUi(&d);
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
|
pui.buttonBox->button(QDialogButtonBox::Save)->setVisible(false);
|
||||||
pui.helpLbl->setText(QString() %
|
pui.helpLbl->setText(QString() %
|
||||||
@@ -577,11 +618,14 @@ void MainWindow::exportAllKeys() {
|
|||||||
QDialog d(this);
|
QDialog d(this);
|
||||||
Ui_PrivKey pui;
|
Ui_PrivKey pui;
|
||||||
pui.setupUi(&d);
|
pui.setupUi(&d);
|
||||||
|
|
||||||
|
// Make the window big by default
|
||||||
auto ps = this->geometry();
|
auto ps = this->geometry();
|
||||||
QMargins margin = QMargins() + 50;
|
QMargins margin = QMargins() + 50;
|
||||||
d.setGeometry(ps.marginsRemoved(margin));
|
d.setGeometry(ps.marginsRemoved(margin));
|
||||||
|
|
||||||
|
Settings::saveRestore(&d);
|
||||||
|
|
||||||
pui.privKeyTxt->setPlainText("Loading...");
|
pui.privKeyTxt->setPlainText("Loading...");
|
||||||
pui.privKeyTxt->setReadOnly(true);
|
pui.privKeyTxt->setReadOnly(true);
|
||||||
pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
|
pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
|
||||||
@@ -706,9 +750,19 @@ void MainWindow::setupZcashdTab() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupTransactionsTab() {
|
void MainWindow::setupTransactionsTab() {
|
||||||
|
// Double click opens up memo if one exists
|
||||||
|
QObject::connect(ui->transactionsTable, &QTableView::doubleClicked, [=] (auto index) {
|
||||||
|
auto txModel = dynamic_cast<TxTableModel *>(ui->transactionsTable->model());
|
||||||
|
QString memo = txModel->getMemo(index.row());
|
||||||
|
|
||||||
|
if (!memo.isEmpty()) {
|
||||||
|
QMessageBox::information(this, "Memo", memo, QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Set up context menu on transactions tab
|
// Set up context menu on transactions tab
|
||||||
ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
// Table right click
|
||||||
QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) {
|
QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) {
|
||||||
QModelIndex index = ui->transactionsTable->indexAt(pos);
|
QModelIndex index = ui->transactionsTable->indexAt(pos);
|
||||||
if (index.row() < 0) return;
|
if (index.row() < 0) return;
|
||||||
@@ -877,6 +931,7 @@ MainWindow::~MainWindow()
|
|||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
delete rpc;
|
delete rpc;
|
||||||
|
delete labelCompleter;
|
||||||
|
|
||||||
delete loadingMovie;
|
delete loadingMovie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ public:
|
|||||||
explicit MainWindow(QWidget *parent = nullptr);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
|
void updateLabelsAutoComplete();
|
||||||
|
|
||||||
Ui::MainWindow* ui;
|
Ui::MainWindow* ui;
|
||||||
|
|
||||||
QLabel* statusLabel;
|
QLabel* statusLabel;
|
||||||
@@ -90,9 +92,10 @@ private:
|
|||||||
|
|
||||||
void restoreSavedStates();
|
void restoreSavedStates();
|
||||||
|
|
||||||
RPC* rpc = nullptr;
|
RPC* rpc = nullptr;
|
||||||
|
QCompleter* labelCompleter = nullptr;
|
||||||
|
|
||||||
QMovie* loadingMovie;
|
QMovie* loadingMovie;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QCompleter>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|||||||
57
src/rpc.cpp
57
src/rpc.cpp
@@ -470,7 +470,7 @@ void RPC::getInfoThenRefresh(bool force) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Connected, so display checkmark.
|
// Connected, so display checkmark.
|
||||||
QIcon i(":/icons/res/connected.png");
|
QIcon i(":/icons/res/connected.gif");
|
||||||
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
||||||
|
|
||||||
static int lastBlock = 0;
|
static int lastBlock = 0;
|
||||||
@@ -899,3 +899,58 @@ void RPC::shutdownZcashd() {
|
|||||||
// Wait for the zcash process to exit.
|
// Wait for the zcash process to exit.
|
||||||
d.exec();
|
d.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fetch the Z-board topics list
|
||||||
|
void RPC::getZboardTopics(std::function<void(QMap<QString, QString>)> cb) {
|
||||||
|
if (conn == nullptr)
|
||||||
|
return noConnection();
|
||||||
|
|
||||||
|
QUrl cmcURL("http://z-board.net/listTopics");
|
||||||
|
|
||||||
|
QNetworkRequest req;
|
||||||
|
req.setUrl(cmcURL);
|
||||||
|
|
||||||
|
QNetworkReply *reply = conn->restclient->get(req);
|
||||||
|
|
||||||
|
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (reply->error() != QNetworkReply::NoError) {
|
||||||
|
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
||||||
|
if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
|
||||||
|
qDebug() << QString::fromStdString(parsed["error"]["message"]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qDebug() << reply->errorString();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto all = reply->readAll();
|
||||||
|
|
||||||
|
auto parsed = json::parse(all, nullptr, false);
|
||||||
|
if (parsed.is_discarded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QString> topics;
|
||||||
|
for (const json& item : parsed["topics"].get<json::array_t>()) {
|
||||||
|
if (item.find("addr") == item.end() || item.find("topicName") == item.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString addr = QString::fromStdString(item["addr"].get<json::string_t>());
|
||||||
|
QString topic = QString::fromStdString(item["topicName"].get<json::string_t>());
|
||||||
|
|
||||||
|
topics.insert(topic, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(topics);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// If anything at all goes wrong, just set the price to 0 and move on.
|
||||||
|
qDebug() << QString("Caught something nasty");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ public:
|
|||||||
void refresh(bool force = false);
|
void refresh(bool force = false);
|
||||||
|
|
||||||
void refreshAddresses();
|
void refreshAddresses();
|
||||||
|
|
||||||
void refreshZECPrice();
|
void refreshZECPrice();
|
||||||
|
void getZboardTopics(std::function<void(QMap<QString, QString>)> cb);
|
||||||
|
|
||||||
void fillTxJsonParams(json& params, Tx tx);
|
void fillTxJsonParams(json& params, Tx tx);
|
||||||
void sendZTransaction (json params, const std::function<void(json)>& cb);
|
void sendZTransaction (json params, const std::function<void(json)>& cb);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ echo "[OK]"
|
|||||||
|
|
||||||
echo -n "Cleaning.........."
|
echo -n "Cleaning.........."
|
||||||
rm -rf bin/*
|
rm -rf bin/*
|
||||||
|
rm -rf artifacts/*
|
||||||
make distclean > /dev/null
|
make distclean > /dev/null
|
||||||
echo "[OK]"
|
echo "[OK]"
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ echo "[OK]"
|
|||||||
|
|
||||||
echo -n "Packaging........."
|
echo -n "Packaging........."
|
||||||
mkdir bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
mkdir bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
||||||
|
strip zec-qt-wallet
|
||||||
cp zec-qt-wallet bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
cp zec-qt-wallet bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
||||||
cp ../zcash/artifacts/zcashd bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
cp ../zcash/artifacts/zcashd bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
||||||
cp README.md bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
cp README.md bin/zec-qt-wallet-v$APP_VERSION > /dev/null
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ void MainWindow::setupSendTab() {
|
|||||||
QObject::connect(ui->Address1, &QLineEdit::textChanged, [=] (auto text) {
|
QObject::connect(ui->Address1, &QLineEdit::textChanged, [=] (auto text) {
|
||||||
this->addressChanged(1, text);
|
this->addressChanged(1, text);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// This is the damnest thing ever. If we do AddressBook::readFromStorage() directly, the whole file
|
||||||
|
// doesn't get read. It needs to run in a timer after everything has finished to be able to read
|
||||||
|
// the file properly.
|
||||||
|
QTimer::singleShot(100, [=]() { updateLabelsAutoComplete(); });
|
||||||
|
|
||||||
// The first address book button
|
// The first address book button
|
||||||
QObject::connect(ui->AddressBook1, &QPushButton::clicked, [=] () {
|
QObject::connect(ui->AddressBook1, &QPushButton::clicked, [=] () {
|
||||||
@@ -87,6 +92,25 @@ void MainWindow::setupSendTab() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateLabelsAutoComplete() {
|
||||||
|
QList<QString> list;
|
||||||
|
auto labels = AddressBook::readFromStorage();
|
||||||
|
|
||||||
|
std::transform(labels.begin(), labels.end(), std::back_inserter(list), [=] (auto la) -> QString {
|
||||||
|
return la.first % "/" % la.second;
|
||||||
|
});
|
||||||
|
|
||||||
|
delete labelCompleter;
|
||||||
|
labelCompleter = new QCompleter(list, this);
|
||||||
|
labelCompleter->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
// Then, find all the address fields and update the completer.
|
||||||
|
QRegExp re("Address[0-9]+", Qt::CaseInsensitive);
|
||||||
|
for (auto target: ui->sendToWidgets->findChildren<QLineEdit *>(re)) {
|
||||||
|
target->setCompleter(labelCompleter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::setDefaultPayFrom() {
|
void MainWindow::setDefaultPayFrom() {
|
||||||
auto findMax = [=] (QString startsWith) {
|
auto findMax = [=] (QString startsWith) {
|
||||||
double max_amt = 0;
|
double max_amt = 0;
|
||||||
@@ -148,6 +172,7 @@ void MainWindow::addAddressSection() {
|
|||||||
QObject::connect(Address1, &QLineEdit::textChanged, [=] (auto text) {
|
QObject::connect(Address1, &QLineEdit::textChanged, [=] (auto text) {
|
||||||
this->addressChanged(itemNumber, text);
|
this->addressChanged(itemNumber, text);
|
||||||
});
|
});
|
||||||
|
Address1->setCompleter(labelCompleter);
|
||||||
|
|
||||||
horizontalLayout_12->addWidget(Address1);
|
horizontalLayout_12->addWidget(Address1);
|
||||||
|
|
||||||
@@ -350,6 +375,9 @@ Tx MainWindow::createTxFromSendPage() {
|
|||||||
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
||||||
for (int i=0; i < totalItems; i++) {
|
for (int i=0; i < totalItems; i++) {
|
||||||
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
||||||
|
// Remove label if it exists
|
||||||
|
addr = addr.split("/").last();
|
||||||
|
|
||||||
double amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble();
|
double amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble();
|
||||||
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
||||||
|
|
||||||
|
|||||||
@@ -120,3 +120,11 @@ QString Settings::getZECUSDDisplayFormat(double bal) {
|
|||||||
else
|
else
|
||||||
return getZECDisplayFormat(bal);
|
return getZECDisplayFormat(bal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Settings::saveRestore(QDialog* d) {
|
||||||
|
d->restoreGeometry(QSettings().value(d->objectName() % "geometry").toByteArray());
|
||||||
|
|
||||||
|
QObject::connect(d, &QDialog::finished, [=](auto) {
|
||||||
|
QSettings().setValue(d->objectName() % "geometry", d->saveGeometry());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ public:
|
|||||||
static Settings* init();
|
static Settings* init();
|
||||||
static Settings* getInstance();
|
static Settings* getInstance();
|
||||||
|
|
||||||
|
static void saveRestore(QDialog* d);
|
||||||
|
|
||||||
Config getSettings();
|
Config getSettings();
|
||||||
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
|
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
|
||||||
|
|
||||||
@@ -48,8 +50,7 @@ public:
|
|||||||
|
|
||||||
void setZECPrice(double p) { zecPrice = p; }
|
void setZECPrice(double p) { zecPrice = p; }
|
||||||
double getZECPrice();
|
double getZECPrice();
|
||||||
|
|
||||||
|
|
||||||
QString getUSDFormat (double bal);
|
QString getUSDFormat (double bal);
|
||||||
QString getZECDisplayFormat (double bal);
|
QString getZECDisplayFormat (double bal);
|
||||||
QString getZECUSDDisplayFormat(double bal);
|
QString getZECUSDDisplayFormat(double bal);
|
||||||
|
|||||||
71
src/txid.ui
71
src/txid.ui
@@ -1,71 +0,0 @@
|
|||||||
<ui version="4.0" >
|
|
||||||
<author></author>
|
|
||||||
<comment></comment>
|
|
||||||
<exportmacro></exportmacro>
|
|
||||||
<class>Dialog</class>
|
|
||||||
<widget class="QDialog" name="Dialog" >
|
|
||||||
<property name="geometry" >
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>300</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle" >
|
|
||||||
<string>Dialog</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
|
||||||
<property name="geometry" >
|
|
||||||
<rect>
|
|
||||||
<x>30</x>
|
|
||||||
<y>240</y>
|
|
||||||
<width>341</width>
|
|
||||||
<height>32</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="orientation" >
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons" >
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<pixmapfunction></pixmapfunction>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>Dialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel" >
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel" >
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>Dialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel" >
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel" >
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
@@ -30,37 +30,8 @@ const QString Utils::getDevSproutAddr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the dev fee address based on the transaction
|
// Get the dev fee address based on the transaction
|
||||||
const QString Utils::getDevAddr(Tx tx) {
|
const QString Utils::getDevAddr(Tx) {
|
||||||
auto testnetAddrLookup = [=] (const QString& addr) -> QString {
|
return QString();
|
||||||
if (addr.startsWith("ztestsapling")) {
|
|
||||||
return "ztestsapling1kdp74adyfsmm9838jaupgfyx3npgw8ut63stjjx757pc248cuc0ymzphqeux60c64qe5qt68ygh";
|
|
||||||
} else if (addr.startsWith("zt")) {
|
|
||||||
return getDevSproutAddr();
|
|
||||||
} else {
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Settings::getInstance()->isTestnet()) {
|
|
||||||
auto devAddr = testnetAddrLookup(tx.fromAddr);
|
|
||||||
if (!devAddr.isEmpty()) {
|
|
||||||
return devAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// t-Addr, find if it is going to a Sprout or Sapling address
|
|
||||||
for (const ToFields& to : tx.toAddrs) {
|
|
||||||
devAddr = testnetAddrLookup(to.addr);
|
|
||||||
if (!devAddr.isEmpty()) {
|
|
||||||
return devAddr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a t-Addr -> t-Addr transaction, use the Sapling address by default
|
|
||||||
return testnetAddrLookup("ztestsapling");
|
|
||||||
} else {
|
|
||||||
// Mainnet doesn't have a fee yet!
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -82,7 +53,7 @@ QString Utils::getZboardAddr() {
|
|||||||
}
|
}
|
||||||
double Utils::getDevFee() {
|
double Utils::getDevFee() {
|
||||||
if (Settings::getInstance()->isTestnet()) {
|
if (Settings::getInstance()->isTestnet()) {
|
||||||
return 0.0001;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p>ZBoard: Fully anonymous and untraceable chat messages based on the ZCash blockchain. <a href="http://www.z-board.net/"><span style=" text-decoration: underline; color:#0000ff;">http://www.z-board.net/</span></a></p><p>Posting to ZBoard: #Main_Area</p></body></html></string>
|
<string><html><head/><body><p>ZBoard: Fully anonymous and untraceable chat messages based on the ZCash blockchain. <a href="http://www.z-board.net/"><span style=" text-decoration: underline; color:#0000ff;">http://www.z-board.net/</span></a></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -115,6 +115,16 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="topicsList"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Posting to Board</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ PRECOMPILED_HEADER = src/precompiled.h
|
|||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
TARGET = zec-qt-wallet
|
TARGET = zec-qt-wallet
|
||||||
APP_VERSION=\\\"0.2.8\\\"
|
APP_VERSION=\\\"0.2.9\\\"
|
||||||
|
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
|
|||||||
Reference in New Issue
Block a user