Merge branch 'master' into embedded
This commit is contained in:
12
README.md
12
README.md
@@ -9,20 +9,20 @@ Head over to the releases page and grab the latest binary. https://github.com/ad
|
||||
### Linux
|
||||
Extract and run the binary
|
||||
```
|
||||
tar -xvf zec-qt-wallet-v0.2.7.tar.gz
|
||||
./zec-qt-wallet-v0.2.7/zec-qt-wallet
|
||||
tar -xvf zec-qt-wallet-v0.2.8.tar.gz
|
||||
./zec-qt-wallet-v0.2.8/zec-qt-wallet
|
||||
```
|
||||
|
||||
### Windows
|
||||
Unzip the release binary and double click on zec-qt-wallet to start.
|
||||
|
||||
## Prerequisites: zcashd
|
||||
zec-qt-wallet needs a Zcash node running zcashd. Linux users should download the zcash node software
|
||||
zec-qt-wallet needs a Zcash node running zcashd. Linux users should download the Zcash node software
|
||||
from [https://z.cash/download/](https://z.cash/download/), configure `zcash.conf`, download the parameters and start zcashd according to the [official documentation](https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html).
|
||||
|
||||
There is currently no official zcashd build for Windows so Windows users may either [cross-compile from source on Linux](https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html#installation) to generate the necessary zcashd executables or simply download community hosted pre-compiled executables such as those hosted by WinZEC developer [@radix42](https://github.com/radix42) at https://zcash.dl.mercerweiss.com/zcash-win-v2.0.1b.zip.
|
||||
|
||||
Alternitavely 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.
|
||||
|
||||
@@ -31,7 +31,7 @@ rpcuser=username
|
||||
rpcpassword=password
|
||||
```
|
||||
|
||||
Additionaly for Windows users the Zcash parameters must be manually downloaded and placed in `C:\Users\your-username\AppData\Roaming\ZcashParams`. The following files are required (and are around ~1.7GB in total).
|
||||
Additionally for Windows users the Zcash parameters must be manually downloaded and placed in `C:\Users\your-username\AppData\Roaming\ZcashParams`. The following files are required (and are around ~1.7GB in total).
|
||||
|
||||
```
|
||||
https://z.cash/downloads/sapling-spend.params
|
||||
@@ -87,7 +87,7 @@ The easiest way to connect to a remote node is probably to ssh to it with port f
|
||||
ssh -L8232:127.0.0.1:8232 user@remotehost
|
||||
```
|
||||
### 2. "Not enough balance" when sending transactions
|
||||
The most likely cause for this is that you are trying to spend unconfirmed funds. Unlike bitcoin, the zcash protocol doesn't let you spent unconfirmed funds yet. Please wait for
|
||||
The most likely cause for this is that you are trying to spend unconfirmed funds. Unlike Bitcoin, the Zcash protocol doesn't let you spent unconfirmed funds yet. Please wait for
|
||||
1-2 blocks for the funds to confirm and retry the transaction.
|
||||
|
||||
### Support or other questions
|
||||
|
||||
192
src/addressbook.cpp
Normal file
192
src/addressbook.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "addressbook.h"
|
||||
#include "ui_addressbook.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "settings.h"
|
||||
#include "mainwindow.h"
|
||||
#include "utils.h"
|
||||
|
||||
AddressBookModel::AddressBookModel(QTableView *parent)
|
||||
: QAbstractTableModel(parent) {
|
||||
headers << "Label" << "Address";
|
||||
|
||||
this->parent = parent;
|
||||
loadDataFromStorage();
|
||||
}
|
||||
|
||||
AddressBookModel::~AddressBookModel() {
|
||||
if (labels != nullptr)
|
||||
saveDataToStorage();
|
||||
|
||||
delete labels;
|
||||
}
|
||||
|
||||
void AddressBookModel::saveDataToStorage() {
|
||||
QFile file(writeableFile());
|
||||
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
|
||||
QSettings().setValue("addresstablegeometry", parent->horizontalHeader()->saveState());
|
||||
}
|
||||
|
||||
|
||||
void AddressBookModel::loadDataFromStorage() {
|
||||
QFile file(writeableFile());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void AddressBookModel::addNewLabel(QString label, QString addr) {
|
||||
labels->push_back(QPair<QString, QString>(label, addr));
|
||||
|
||||
dataChanged(index(0, 0), index(labels->size()-1, columnCount(index(0,0))-1));
|
||||
layoutChanged();
|
||||
}
|
||||
|
||||
void AddressBookModel::removeItemAt(int row) {
|
||||
if (row >= labels->size())
|
||||
return;
|
||||
labels->removeAt(row);
|
||||
|
||||
dataChanged(index(0, 0), index(labels->size()-1, columnCount(index(0,0))-1));
|
||||
layoutChanged();
|
||||
}
|
||||
|
||||
QPair<QString, QString> AddressBookModel::itemAt(int row) {
|
||||
if (row >= labels->size()) return QPair<QString, QString>();
|
||||
|
||||
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 {
|
||||
if (labels == nullptr) return 0;
|
||||
return labels->size();
|
||||
}
|
||||
|
||||
int AddressBookModel::columnCount(const QModelIndex&) const {
|
||||
return headers.size();
|
||||
}
|
||||
|
||||
|
||||
QVariant AddressBookModel::data(const QModelIndex &index, int role) const {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(index.column()) {
|
||||
case 0: return labels->at(index.row()).first;
|
||||
case 1: return labels->at(index.row()).second;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant AddressBookModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
return headers.at(section);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void AddressBook::open(MainWindow* parent, QLineEdit* target) {
|
||||
QDialog d(parent);
|
||||
Ui_addressBook ab;
|
||||
ab.setupUi(&d);
|
||||
|
||||
AddressBookModel model(ab.addresses);
|
||||
ab.addresses->setModel(&model);
|
||||
|
||||
// If there is no target, the we'll call the button "Ok", else "Pick"
|
||||
if (target != nullptr) {
|
||||
ab.buttonBox->button(QDialogButtonBox::Ok)->setText("Pick");
|
||||
}
|
||||
|
||||
// If there is a target then make it the addr for the "Add to" button
|
||||
if (target != nullptr && Utils::isValidAddress(target->text())) {
|
||||
ab.addr->setText(target->text());
|
||||
ab.label->setFocus();
|
||||
}
|
||||
|
||||
// Add new address button
|
||||
QObject::connect(ab.addNew, &QPushButton::clicked, [&] () {
|
||||
auto addr = ab.addr->text().trimmed();
|
||||
if (!addr.isEmpty() && !ab.label->text().isEmpty()) {
|
||||
// Test if address is valid.
|
||||
if (!Utils::isValidAddress(addr)) {
|
||||
QMessageBox::critical(parent, "Address Format Error", addr + " doesn't seem to be a valid Zcash address.", QMessageBox::Ok);
|
||||
} else {
|
||||
model.addNewLabel(ab.label->text(), ab.addr->text());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Double-Click picks the item
|
||||
QObject::connect(ab.addresses, &QTableView::doubleClicked, [&] (auto index) {
|
||||
if (index.row() < 0) return;
|
||||
|
||||
QString addr = model.itemAt(index.row()).second;
|
||||
d.accept();
|
||||
target->setText(addr);
|
||||
});
|
||||
|
||||
// Right-Click
|
||||
ab.addresses->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
QObject::connect(ab.addresses, &QTableView::customContextMenuRequested, [&] (QPoint pos) {
|
||||
QModelIndex index = ab.addresses->indexAt(pos);
|
||||
|
||||
if (index.row() < 0) return;
|
||||
|
||||
QString addr = model.itemAt(index.row()).second;
|
||||
|
||||
QMenu menu(parent);
|
||||
|
||||
if (target != nullptr) {
|
||||
menu.addAction("Pick", [&] () {
|
||||
target->setText(addr);
|
||||
});
|
||||
}
|
||||
|
||||
menu.addAction("Copy Address", [&] () {
|
||||
QGuiApplication::clipboard()->setText(addr);
|
||||
parent->ui->statusBar->showMessage("Copied to clipboard", 3 * 1000);
|
||||
});
|
||||
|
||||
menu.addAction("Delete Label", [&] () {
|
||||
model.removeItemAt(index.row());
|
||||
});
|
||||
|
||||
menu.exec(ab.addresses->viewport()->mapToGlobal(pos));
|
||||
});
|
||||
|
||||
if (d.exec() == QDialog::Accepted && target != nullptr) {
|
||||
auto selection = ab.addresses->selectionModel();
|
||||
if (selection->hasSelection()) {
|
||||
target->setText(model.itemAt(selection->selectedRows().at(0).row()).second);
|
||||
}
|
||||
};
|
||||
}
|
||||
39
src/addressbook.h
Normal file
39
src/addressbook.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef ADDRESSBOOK_H
|
||||
#define ADDRESSBOOK_H
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class AddressBookModel : public QAbstractTableModel {
|
||||
|
||||
public:
|
||||
AddressBookModel(QTableView* parent);
|
||||
~AddressBookModel();
|
||||
|
||||
void addNewLabel(QString label, QString addr);
|
||||
void removeItemAt(int row);
|
||||
QPair<QString, QString> itemAt(int row);
|
||||
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
private:
|
||||
void loadDataFromStorage();
|
||||
void saveDataToStorage();
|
||||
|
||||
QString writeableFile();
|
||||
|
||||
QTableView* parent;
|
||||
QList<QPair<QString, QString>>* labels = nullptr;
|
||||
QStringList headers;
|
||||
};
|
||||
|
||||
class AddressBook {
|
||||
public:
|
||||
static void open(MainWindow* parent, QLineEdit* target = nullptr);
|
||||
};
|
||||
|
||||
#endif // ADDRESSBOOK_H
|
||||
133
src/addressbook.ui
Normal file
133
src/addressbook.ui
Normal file
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>addressBook</class>
|
||||
<widget class="QDialog" name="addressBook">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>690</width>
|
||||
<height>562</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Address Book</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Add New Address</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>Address (z-Addr or t-Addr)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="addr"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Label</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="label"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addNew">
|
||||
<property name="text">
|
||||
<string>Add to Address Book</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="addresses">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>addressBook</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>addressBook</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>
|
||||
@@ -258,7 +258,7 @@ void ConnectionLoader::refreshZcashdState(Connection* connection) {
|
||||
} else if (err == QNetworkReply::NetworkError::AuthenticationRequiredError) {
|
||||
QString explanation = QString()
|
||||
% "Authentication failed. The username / password you specified was "
|
||||
% "not accepted by zcashd. Try changing it in the File->Settings menu";
|
||||
% "not accepted by zcashd. Try changing it in the Edit->Settings menu";
|
||||
|
||||
this->showError(explanation);
|
||||
} else if (err == QNetworkReply::NetworkError::InternalServerError && !res.is_discarded()) {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "mainwindow.h"
|
||||
#include "addressbook.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "ui_addressbook.h"
|
||||
#include "ui_zboard.h"
|
||||
#include "ui_privkey.h"
|
||||
#include "ui_about.h"
|
||||
#include "ui_settings.h"
|
||||
@@ -46,6 +49,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
// Export All Private Keys
|
||||
QObject::connect(ui->actionExport_All_Private_Keys, &QAction::triggered, this, &MainWindow::exportAllKeys);
|
||||
|
||||
// z-Board.net
|
||||
QObject::connect(ui->actionz_board_net, &QAction::triggered, this, &MainWindow::postToZBoard);
|
||||
|
||||
// Address Book
|
||||
QObject::connect(ui->action_Address_Book, &QAction::triggered, this, &MainWindow::addressBook);
|
||||
|
||||
// Set up about action
|
||||
QObject::connect(ui->actionAbout, &QAction::triggered, [=] () {
|
||||
QDialog aboutDialog(this);
|
||||
@@ -404,9 +413,23 @@ void MainWindow::setupSettingsModal() {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::addressBook() {
|
||||
// Check to see if there is a target.
|
||||
QRegExp re("Address[0-9]+", Qt::CaseInsensitive);
|
||||
for (auto target: ui->sendToWidgets->findChildren<QLineEdit *>(re)) {
|
||||
if (target->hasFocus()) {
|
||||
AddressBook::open(this, target);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// If there was no target, then just run with no target.
|
||||
AddressBook::open(this);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::donate() {
|
||||
// Set up a donation to me :)
|
||||
ui->Address1->setText(Utils::getDonationAddr(
|
||||
@@ -421,6 +444,80 @@ void MainWindow::donate() {
|
||||
ui->tabWidget->setCurrentIndex(1);
|
||||
}
|
||||
|
||||
void MainWindow::postToZBoard() {
|
||||
QDialog d(this);
|
||||
Ui_zboard zb;
|
||||
zb.setupUi(&d);
|
||||
|
||||
// Fill the from field with sapling addresses.
|
||||
for (auto i = rpc->getAllBalances()->keyBegin(); i != rpc->getAllBalances()->keyEnd(); i++) {
|
||||
if (Settings::getInstance()->isSaplingAddress(*i) && rpc->getAllBalances()->value(*i) > 0) {
|
||||
zb.fromAddr->addItem(*i);
|
||||
}
|
||||
}
|
||||
|
||||
// Testnet warning
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
zb.testnetWarning->setText("You are on testnet, your post won't actually appear on z-board.net");
|
||||
}
|
||||
else {
|
||||
zb.testnetWarning->setText("");
|
||||
}
|
||||
|
||||
zb.feeAmount->setText(Settings::getInstance()->getZECUSDDisplayFormat(Utils::getZboardAmount() + Utils::getMinerFee()));
|
||||
|
||||
QObject::connect(zb.memoTxt, &QPlainTextEdit::textChanged, [=] () {
|
||||
QString txt = zb.memoTxt->toPlainText();
|
||||
zb.memoSize->setText(QString::number(txt.toUtf8().size()) + "/512");
|
||||
|
||||
if (txt.toUtf8().size() <= 512) {
|
||||
// Everything is fine
|
||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
zb.memoSize->setStyleSheet("");
|
||||
}
|
||||
else {
|
||||
// Overweight
|
||||
zb.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
zb.memoSize->setStyleSheet("color: red;");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
zb.memoTxt->setFocus();
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
// Create a transaction.
|
||||
Tx tx;
|
||||
|
||||
// Send from your first sapling address that has a balance.
|
||||
tx.fromAddr = zb.fromAddr->currentText();
|
||||
if (tx.fromAddr.isEmpty()) {
|
||||
QMessageBox::critical(this, "Error Posting Message", "You need a sapling address with available balance to post", QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
auto memo = zb.memoTxt->toPlainText().trimmed();
|
||||
if (!zb.postAs->text().trimmed().isEmpty())
|
||||
memo = zb.postAs->text().trimmed() + ":: " + memo;
|
||||
|
||||
tx.toAddrs.push_back(ToFields{ Utils::getZboardAddr(), Utils::getZboardAmount(), memo, memo.toUtf8().toHex() });
|
||||
tx.fee = Utils::getMinerFee();
|
||||
|
||||
json params = json::array();
|
||||
rpc->fillTxJsonParams(params, tx);
|
||||
std::cout << std::setw(2) << params << std::endl;
|
||||
|
||||
// And send the Tx
|
||||
rpc->sendZTransaction(params, [=](const json& reply) {
|
||||
QString opid = QString::fromStdString(reply.get<json::string_t>());
|
||||
ui->statusBar->showMessage("Computing Tx: " % opid);
|
||||
|
||||
// And then start monitoring the transaction
|
||||
rpc->addNewTxToWatch(tx, opid);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::doImport(QList<QString>* keys) {
|
||||
qDebug() << keys->size();
|
||||
if (keys->isEmpty()) {
|
||||
@@ -644,10 +741,10 @@ void MainWindow::setupTransactionsTab() {
|
||||
void MainWindow::addNewZaddr(bool sapling) {
|
||||
rpc->newZaddr(sapling, [=] (json reply) {
|
||||
QString addr = QString::fromStdString(reply.get<json::string_t>());
|
||||
// Make sure the RPC class reloads the Z-addrs for future use
|
||||
// Make sure the RPC class reloads the z-addrs for future use
|
||||
rpc->refreshAddresses();
|
||||
|
||||
// Just double make sure the Z-address is still checked
|
||||
// Just double make sure the z-address is still checked
|
||||
if (( sapling && ui->rdioZSAddr->isChecked()) ||
|
||||
(!sapling && ui->rdioZAddr->isChecked())) {
|
||||
ui->listRecieveAddresses->insertItem(0, addr);
|
||||
@@ -688,7 +785,7 @@ void MainWindow::setupRecieveTab() {
|
||||
rpc->newTaddr([=] (json reply) {
|
||||
QString addr = QString::fromStdString(reply.get<json::string_t>());
|
||||
|
||||
// Just double make sure the T-address is still checked
|
||||
// Just double make sure the t-address is still checked
|
||||
if (ui->rdioTAddr->isChecked()) {
|
||||
ui->listRecieveAddresses->insertItem(0, addr);
|
||||
ui->listRecieveAddresses->setCurrentIndex(0);
|
||||
@@ -700,8 +797,8 @@ void MainWindow::setupRecieveTab() {
|
||||
|
||||
// Connect t-addr radio button
|
||||
QObject::connect(ui->rdioTAddr, &QRadioButton::toggled, [=] (bool checked) {
|
||||
// Whenever the T-address is selected, we generate a new address, because we don't
|
||||
// want to reuse T-addrs
|
||||
// Whenever the t-address is selected, we generate a new address, because we don't
|
||||
// want to reuse t-addrs
|
||||
if (checked && this->rpc->getUTXOs() != nullptr) {
|
||||
auto utxos = this->rpc->getUTXOs();
|
||||
ui->listRecieveAddresses->clear();
|
||||
@@ -733,12 +830,12 @@ void MainWindow::setupRecieveTab() {
|
||||
}
|
||||
});
|
||||
|
||||
// Focus enter for the Recieve Tab
|
||||
// Focus enter for the Receive Tab
|
||||
QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int tab) {
|
||||
if (tab == 2) {
|
||||
// Switched to recieve tab, so update everything.
|
||||
// Switched to receive tab, so update everything.
|
||||
|
||||
// Hide Sapling radio button if sapling is not active
|
||||
// Hide Sapling radio button if Sapling is not active
|
||||
if (Settings::getInstance()->isSaplingActive()) {
|
||||
ui->rdioZSAddr->setVisible(true);
|
||||
ui->rdioZSAddr->setChecked(true);
|
||||
@@ -746,7 +843,7 @@ void MainWindow::setupRecieveTab() {
|
||||
} else {
|
||||
ui->rdioZSAddr->setVisible(false);
|
||||
ui->rdioZAddr->setChecked(true);
|
||||
ui->rdioZAddr->setText("z-Addr"); // Don't use the "Sprout" label if there's no sapling
|
||||
ui->rdioZAddr->setText("z-Addr"); // Don't use the "Sprout" label if there's no Sapling
|
||||
}
|
||||
|
||||
// And then select the first one
|
||||
|
||||
@@ -81,6 +81,8 @@ private:
|
||||
QString doSendTxValidations(Tx tx);
|
||||
|
||||
void donate();
|
||||
void addressBook();
|
||||
void postToZBoard();
|
||||
void importPrivKey();
|
||||
void exportAllKeys();
|
||||
void doImport(QList<QString>* keys);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
@@ -343,6 +343,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="AddressBook1">
|
||||
<property name="text">
|
||||
<string>Address Book</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -727,8 +734,6 @@
|
||||
</property>
|
||||
<addaction name="actionImport_Private_Key"/>
|
||||
<addaction name="actionExport_All_Private_Keys"/>
|
||||
<addaction name="actionTurnstile_Migration"/>
|
||||
<addaction name="actionSettings"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
@@ -740,7 +745,23 @@
|
||||
<addaction name="actionCheck_for_Updates"/>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuApps">
|
||||
<property name="title">
|
||||
<string>&Apps</string>
|
||||
</property>
|
||||
<addaction name="actionTurnstile_Migration"/>
|
||||
<addaction name="actionz_board_net"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Edit">
|
||||
<property name="title">
|
||||
<string>&Edit</string>
|
||||
</property>
|
||||
<addaction name="action_Address_Book"/>
|
||||
<addaction name="actionSettings"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menu_Edit"/>
|
||||
<addaction name="menuApps"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
@@ -776,6 +797,9 @@
|
||||
<property name="text">
|
||||
<string>Sapling &Turnstile</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+A, Ctrl+T</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionImport_Private_Key">
|
||||
<property name="text">
|
||||
@@ -787,6 +811,22 @@
|
||||
<string>Export All Private Keys</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionz_board_net">
|
||||
<property name="text">
|
||||
<string>&z-board.net</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+A, Ctrl+Z</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Address_Book">
|
||||
<property name="text">
|
||||
<string>Address &Book</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+B</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>Memo</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <QClipboard>
|
||||
#include <QStringBuilder>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
#include <QScrollBar>
|
||||
@@ -19,6 +21,7 @@
|
||||
#include <QMovie>
|
||||
#include <QPair>
|
||||
#include <QDir>
|
||||
#include <QMenu>
|
||||
#include <QDateTime>
|
||||
#include <QTimer>
|
||||
#include <QSettings>
|
||||
|
||||
@@ -220,7 +220,7 @@ void RPC::getAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>
|
||||
|
||||
// A special function that will call the callback when two lists have been added
|
||||
auto holder = new QPair<int, QList<QPair<QString, QString>>>();
|
||||
holder->first = 0; // This is the number of times the callback has been called, initalized to 0
|
||||
holder->first = 0; // This is the number of times the callback has been called, initialized to 0
|
||||
auto fnCombineTwoLists = [=] (QList<QPair<QString, QString>> list) {
|
||||
// Increment the callback counter
|
||||
holder->first++;
|
||||
@@ -277,7 +277,7 @@ void RPC::getAllPrivKeys(const std::function<void(QList<QPair<QString, QString>>
|
||||
};
|
||||
|
||||
|
||||
// First get all the T and Z addresses.
|
||||
// First get all the t and z addresses.
|
||||
json payloadT = {
|
||||
{"jsonrpc", "1.0"},
|
||||
{"id", "someid"},
|
||||
@@ -707,7 +707,7 @@ void RPC::watchTxStatus() {
|
||||
conn->doRPCWithDefaultErrorHandling(payload, [=] (const json& reply) {
|
||||
// There's an array for each item in the status
|
||||
for (auto& it : reply.get<json::array_t>()) {
|
||||
// If we were watching this Tx and it's status became "success", then we'll show a status bar alert
|
||||
// If we were watching this Tx and its status became "success", then we'll show a status bar alert
|
||||
QString id = QString::fromStdString(it["id"]);
|
||||
if (watchingOps.contains(id)) {
|
||||
// And if it ended up successful
|
||||
@@ -763,7 +763,7 @@ void RPC::watchTxStatus() {
|
||||
|
||||
// Get the ZEC->USD price from coinmarketcap using their API
|
||||
void RPC::refreshZECPrice() {
|
||||
qDebug() << QString::fromStdString("Getting zec price");
|
||||
qDebug() << QString::fromStdString("Getting ZEC price");
|
||||
if (conn == nullptr)
|
||||
return noConnection();
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ echo "Linux"
|
||||
|
||||
echo -n "Configuring..."
|
||||
$QT_STATIC/bin/qmake zec-qt-wallet.pro -spec linux-clang CONFIG+=release > /dev/null
|
||||
#Mingw seems to have trouble with precompiled heades, so strip that option from the .pro file
|
||||
#Mingw seems to have trouble with precompiled headers, so strip that option from the .pro file
|
||||
echo "[OK]"
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "addressbook.h"
|
||||
#include "ui_confirm.h"
|
||||
#include "ui_memodialog.h"
|
||||
#include "settings.h"
|
||||
@@ -45,6 +46,12 @@ void MainWindow::setupSendTab() {
|
||||
this->addressChanged(1, text);
|
||||
});
|
||||
|
||||
// The first address book button
|
||||
QObject::connect(ui->AddressBook1, &QPushButton::clicked, [=] () {
|
||||
AddressBook::open(this, ui->Address1);
|
||||
});
|
||||
|
||||
|
||||
// The first Amount button
|
||||
QObject::connect(ui->Amount1, &QLineEdit::textChanged, [=] (auto text) {
|
||||
this->amountChanged(1, text);
|
||||
@@ -143,6 +150,16 @@ void MainWindow::addAddressSection() {
|
||||
});
|
||||
|
||||
horizontalLayout_12->addWidget(Address1);
|
||||
|
||||
auto addressBook1 = new QPushButton(verticalGroupBox);
|
||||
addressBook1->setObjectName(QStringLiteral("AddressBook") % QString::number(itemNumber));
|
||||
addressBook1->setText("Address Book");
|
||||
QObject::connect(addressBook1, &QPushButton::clicked, [=] () {
|
||||
AddressBook::open(this, Address1);
|
||||
});
|
||||
|
||||
horizontalLayout_12->addWidget(addressBook1);
|
||||
|
||||
sendAddressLayout->addLayout(horizontalLayout_12);
|
||||
|
||||
auto horizontalLayout_13 = new QHBoxLayout();
|
||||
@@ -217,7 +234,7 @@ void MainWindow::setMemoEnabled(int number, bool enabled) {
|
||||
memoBtn->setToolTip("");
|
||||
} else {
|
||||
memoBtn->setEnabled(false);
|
||||
memoBtn->setToolTip("Only Z addresses can have memos");
|
||||
memoBtn->setToolTip("Only z-addresses can have memos");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,8 +242,8 @@ void MainWindow::memoButtonClicked(int number) {
|
||||
// Memos can only be used with zAddrs. So check that first
|
||||
auto addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") + QString::number(number));
|
||||
if (!addr->text().trimmed().startsWith("z")) {
|
||||
QMessageBox msg(QMessageBox::Critical, "Memos can only be used with z Addresses",
|
||||
"The Memo field can only be used with a z Address.\n" + addr->text() + "\ndoesn't look like a z Address",
|
||||
QMessageBox msg(QMessageBox::Critical, "Memos can only be used with z-addresses",
|
||||
"The memo field can only be used with a z-address.\n" + addr->text() + "\ndoesn't look like a z-address",
|
||||
QMessageBox::Ok, this);
|
||||
|
||||
msg.exec();
|
||||
@@ -245,7 +262,17 @@ void MainWindow::memoButtonClicked(int number) {
|
||||
QString txt = memoDialog.memoTxt->toPlainText();
|
||||
memoDialog.memoSize->setText(QString::number(txt.toUtf8().size()) + "/512");
|
||||
|
||||
memoDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(txt.toUtf8().size() <= 512);
|
||||
if (txt.toUtf8().size() <= 512) {
|
||||
// Everything is fine
|
||||
memoDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
memoDialog.memoSize->setStyleSheet("");
|
||||
}
|
||||
else {
|
||||
// Overweight
|
||||
memoDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
memoDialog.memoSize->setStyleSheet("color: red;");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
memoDialog.memoTxt->setPlainText(currentMemo);
|
||||
@@ -261,7 +288,7 @@ void MainWindow::removeExtraAddresses() {
|
||||
// The last one is a spacer, so ignore that
|
||||
int totalItems = ui->sendToWidgets->children().size() - 2;
|
||||
|
||||
// Clear the first recepient fields
|
||||
// Clear the first recipient fields
|
||||
auto addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address1"));
|
||||
addr->clear();
|
||||
auto amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount1"));
|
||||
@@ -511,7 +538,7 @@ void MainWindow::sendButton() {
|
||||
}
|
||||
|
||||
QString MainWindow::doSendTxValidations(Tx tx) {
|
||||
// 1. Addresses are valid format.
|
||||
// 1. Addresses have valid format.
|
||||
QRegExp zcexp("^z[a-z0-9]{94}$", Qt::CaseInsensitive);
|
||||
QRegExp zsexp("^z[a-z0-9]{77}$", Qt::CaseInsensitive);
|
||||
QRegExp ztsexp("^ztestsapling[a-z0-9]{76}", Qt::CaseInsensitive);
|
||||
@@ -536,7 +563,5 @@ QString MainWindow::doSendTxValidations(Tx tx) {
|
||||
|
||||
void MainWindow::cancelButton() {
|
||||
removeExtraAddresses();
|
||||
// Back to the balances tab
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ void SentTxStore::addToSentTx(Tx tx, QString txid) {
|
||||
if (!Settings::getInstance()->getSaveZtxs())
|
||||
return;
|
||||
|
||||
// Also, only store outgoing Txs where the from address is a z-Addr. Else, regular zcashd
|
||||
// Also, only store outgoing txs where the from address is a z-Addr. Else, regular zcashd
|
||||
// stores it just fine
|
||||
if (!tx.fromAddr.startsWith("z"))
|
||||
return;
|
||||
|
||||
@@ -90,7 +90,7 @@ void Turnstile::planMigration(QString zaddr, QString destAddr, int numsplits, in
|
||||
auto bal = rpc->getAllBalances()->value(zaddr);
|
||||
auto splits = splitAmount(bal, numsplits);
|
||||
|
||||
// Then, generate an intermediate t-Address for each part using getBatchRPC
|
||||
// Then, generate an intermediate t-address for each part using getBatchRPC
|
||||
rpc->getConnection()->doBatchRPC<double>(splits,
|
||||
[=] (double /*unused*/) {
|
||||
json payload = {
|
||||
@@ -186,7 +186,7 @@ void Turnstile::fillAmounts(QList<double>& amounts, double amount, int count) {
|
||||
}
|
||||
|
||||
// Get a random amount off the amount (between half and full) and call recursively.
|
||||
// Multiply by hundered, because we'll operate on 0.01 ZEC minimum. We'll divide by 100 later
|
||||
// Multiply by hundred, because we'll operate on 0.01 ZEC minimum. We'll divide by 100 later
|
||||
double curAmount = std::rand() % (int)std::floor(amount * 100);
|
||||
|
||||
// Try to round it off
|
||||
@@ -319,14 +319,14 @@ void Turnstile::executeMigrationStep() {
|
||||
|
||||
} else if (nextStep->status == TurnstileMigrationItemStatus::SentToT) {
|
||||
// First thing to do is check to see if the funds are confirmed.
|
||||
// We'll check both the original sprout address and the intermediate T addr for safety.
|
||||
// We'll check both the original sprout address and the intermediate t-addr for safety.
|
||||
if (fnHasUnconfirmed(nextStep->intTAddr) || fnHasUnconfirmed(nextStep->fromAddr)) {
|
||||
//qDebug() << QString("unconfirmed, waiting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rpc->getAllBalances()->keys().contains(nextStep->intTAddr)) {
|
||||
qDebug() << QString("The intermediate Taddress doesn't have balance, even though it is confirmed");
|
||||
qDebug() << QString("The intermediate t-address doesn't have balance, even though it is confirmed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ const QString Utils::getDevAddr(Tx tx) {
|
||||
return devAddr;
|
||||
}
|
||||
|
||||
// t-Addr, find if it is going to a sprout or sapling address
|
||||
// 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()) {
|
||||
@@ -55,7 +55,7 @@ const QString Utils::getDevAddr(Tx tx) {
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a t-Addr -> t-Addr transaction, use the sapling address by default
|
||||
// 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!
|
||||
@@ -67,6 +67,19 @@ const QString Utils::getDevAddr(Tx tx) {
|
||||
double Utils::getMinerFee() {
|
||||
return 0.0001;
|
||||
}
|
||||
|
||||
double Utils::getZboardAmount() {
|
||||
return 0.0001;
|
||||
}
|
||||
|
||||
QString Utils::getZboardAddr() {
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
return getDonationAddr(true);
|
||||
}
|
||||
else {
|
||||
return "zs10m00rvkhfm4f7n23e4sxsx275r7ptnggx39ygl0vy46j9mdll5c97gl6dxgpk0njuptg2mn9w5s";
|
||||
}
|
||||
}
|
||||
double Utils::getDevFee() {
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
return 0.0001;
|
||||
@@ -74,4 +87,15 @@ double Utils::getDevFee() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double Utils::getTotalFee() { return getMinerFee() + getDevFee(); }
|
||||
|
||||
bool Utils::isValidAddress(QString addr) {
|
||||
QRegExp zcexp("^z[a-z0-9]{94}$", Qt::CaseInsensitive);
|
||||
QRegExp zsexp("^z[a-z0-9]{77}$", Qt::CaseInsensitive);
|
||||
QRegExp ztsexp("^ztestsapling[a-z0-9]{76}", Qt::CaseInsensitive);
|
||||
QRegExp texp("^t[a-z0-9]{34}$", Qt::CaseInsensitive);
|
||||
|
||||
return zcexp.exactMatch(addr) || texp.exactMatch(addr) ||
|
||||
ztsexp.exactMatch(addr) || zsexp.exactMatch(addr);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,13 @@ public:
|
||||
static const QString getDonationAddr(bool sapling);
|
||||
|
||||
static double getMinerFee();
|
||||
static double getZboardAmount();
|
||||
static QString getZboardAddr();
|
||||
static double getDevFee();
|
||||
static double getTotalFee();
|
||||
|
||||
static bool isValidAddress(QString addr);
|
||||
|
||||
static const int updateSpeed = 20 * 1000; // 20 sec
|
||||
static const int quickUpdateSpeed = 5 * 1000; // 5 sec
|
||||
static const int priceRefreshSpeed = 60 * 60 * 1000; // 1 hr
|
||||
|
||||
160
src/zboard.ui
Normal file
160
src/zboard.ui
Normal file
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>zboard</class>
|
||||
<widget class="QDialog" name="zboard">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>588</width>
|
||||
<height>431</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Post to z-board.net</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Total Fee</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QLabel" name="feeAmount">
|
||||
<property name="text">
|
||||
<string>feeamount</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLabel" name="memoSize">
|
||||
<property name="text">
|
||||
<string>0 / 512</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Memo</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="postAs">
|
||||
<property name="placeholderText">
|
||||
<string>(optional)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Send From</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Post As:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<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>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="2">
|
||||
<widget class="QPlainTextEdit" name="memoTxt"/>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QComboBox" name="fromAddr"/>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="testnetWarning">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>fromAddr</tabstop>
|
||||
<tabstop>postAs</tabstop>
|
||||
<tabstop>memoTxt</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>zboard</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>zboard</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>
|
||||
@@ -13,7 +13,7 @@ PRECOMPILED_HEADER = src/precompiled.h
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = zec-qt-wallet
|
||||
APP_VERSION=\\\"0.2.7\\\"
|
||||
APP_VERSION=\\\"0.2.8\\\"
|
||||
|
||||
|
||||
TEMPLATE = app
|
||||
@@ -54,7 +54,8 @@ SOURCES += \
|
||||
src/utils.cpp \
|
||||
src/qrcodelabel.cpp \
|
||||
src/connection.cpp \
|
||||
src/fillediconlabel.cpp
|
||||
src/fillediconlabel.cpp \
|
||||
src/addressbook.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/mainwindow.h \
|
||||
@@ -73,7 +74,8 @@ HEADERS += \
|
||||
src/utils.h \
|
||||
src/qrcodelabel.h \
|
||||
src/connection.h \
|
||||
src/fillediconlabel.h
|
||||
src/fillediconlabel.h \
|
||||
src/addressbook.h
|
||||
|
||||
FORMS += \
|
||||
src/mainwindow.ui \
|
||||
@@ -84,7 +86,9 @@ FORMS += \
|
||||
src/turnstileprogress.ui \
|
||||
src/privkey.ui \
|
||||
src/memodialog.ui \
|
||||
src/connection.ui
|
||||
src/connection.ui \
|
||||
src/zboard.ui \
|
||||
src/addressbook.ui
|
||||
|
||||
win32: RC_ICONS = res/icon.ico
|
||||
|
||||
|
||||
Reference in New Issue
Block a user