From db87dab03bb6ec6aab64e9bc73410bad146763d8 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 25 Apr 2020 18:30:49 +0200 Subject: [PATCH 001/253] initial HushChat push: Add HushChat tab and a few QWidgets - work in progress --- src/mainwindow.ui | 126 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index d7caf5d..f54a0a2 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -22,7 +22,7 @@ - 0 + 5 @@ -1324,6 +1324,125 @@ + + + HushChat + + + + + 0 + 80 + 341 + 561 + + + + + + + 6 + 40 + 311 + 20 + + + + <html><head/><body><p align="center">Contact</p></body></html> + + + + + + 340 + 80 + 871 + 361 + + + + + + + 357 + 460 + 329 + 17 + + + + Memo + + + + + + 357 + 483 + 851 + 128 + + + + + + + 360 + 620 + 158 + 25 + + + + Include Reply Address + + + + + + 692 + 618 + 189 + 25 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 1110 + 460 + 91 + 17 + + + + 0 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 340 + 50 + 861 + 20 + + + + <html><head/><body><p align="center">Messages</p></body></html> + + + @@ -1509,6 +1628,11 @@ QLabel
fillediconlabel.h
+ + MemoEdit + QPlainTextEdit +
memoedit.h
+
Address1 From d398709da95d30760da6c466e65b7d1d1ac9f0e4 Mon Sep 17 00:00:00 2001 From: Strider Date: Sat, 25 Apr 2020 20:30:53 +0200 Subject: [PATCH 002/253] update// added speechbubble wigdets --- silentdragon-lite.pro | 12 ++++++--- src/chatbubbleme.cpp | 14 ++++++++++ src/chatbubbleme.h | 22 +++++++++++++++ src/chatbubbleme.ui | 57 +++++++++++++++++++++++++++++++++++++++ src/chatbubblepartner.cpp | 14 ++++++++++ src/chatbubblepartner.h | 22 +++++++++++++++ src/chatbubblepartner.ui | 57 +++++++++++++++++++++++++++++++++++++++ src/mainwindow.ui | 16 +++++------ 8 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 src/chatbubbleme.cpp create mode 100644 src/chatbubbleme.h create mode 100644 src/chatbubbleme.ui create mode 100644 src/chatbubblepartner.cpp create mode 100644 src/chatbubblepartner.h create mode 100644 src/chatbubblepartner.ui diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index cc9092d..e8c50d5 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -65,7 +65,9 @@ SOURCES += \ src/datamodel.cpp \ src/controller.cpp \ src/liteinterface.cpp \ - src/camount.cpp + src/camount.cpp \ + src/chatbubbleme.cpp \ + src/chatbubblepartner.cpp HEADERS += \ src/firsttimewizard.h \ @@ -94,7 +96,9 @@ HEADERS += \ src/controller.h \ src/liteinterface.h \ src/camount.h \ - lib/silentdragonlitelib.h + lib/silentdragonlitelib.h \ + src/chatbubbleme.h \ + src/chatbubblepartner.h FORMS += \ src/encryption.ui \ @@ -117,7 +121,9 @@ FORMS += \ src/recurringdialog.ui \ src/newrecurring.ui \ src/requestdialog.ui \ - src/recurringmultiple.ui + src/recurringmultiple.ui \ + src/chatbubbleme.ui \ + src/chatbubblepartner.ui TRANSLATIONS = res/silentdragonlite_es.ts \ diff --git a/src/chatbubbleme.cpp b/src/chatbubbleme.cpp new file mode 100644 index 0000000..1f17250 --- /dev/null +++ b/src/chatbubbleme.cpp @@ -0,0 +1,14 @@ +#include "chatbubbleme.h" +#include "ui_chatbubbleme.h" + +ChatBubbleMe::ChatBubbleMe(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChatBubbleMe) +{ + ui->setupUi(this); +} + +ChatBubbleMe::~ChatBubbleMe() +{ + delete ui; +} diff --git a/src/chatbubbleme.h b/src/chatbubbleme.h new file mode 100644 index 0000000..86e9c6f --- /dev/null +++ b/src/chatbubbleme.h @@ -0,0 +1,22 @@ +#ifndef CHATBUBBLEME_H +#define CHATBUBBLEME_H + +#include + +namespace Ui { +class ChatBubbleMe; +} + +class ChatBubbleMe : public QWidget +{ + Q_OBJECT + +public: + explicit ChatBubbleMe(QWidget *parent = nullptr); + ~ChatBubbleMe(); + +private: + Ui::ChatBubbleMe *ui; +}; + +#endif // CHATBUBBLEME_H diff --git a/src/chatbubbleme.ui b/src/chatbubbleme.ui new file mode 100644 index 0000000..f35baaa --- /dev/null +++ b/src/chatbubbleme.ui @@ -0,0 +1,57 @@ + + + ChatBubbleMe + + + + 0 + 0 + 646 + 76 + + + + Form + + + QWidget{ + background: whitesmoke; + border: 1px solid #afafaf; + border-radius: 3px; +} +QLabel +{ + background: none; + border: none; +} + + + + + 10 + 30 + 611 + 41 + + + + Lorem ipsum dolor sit amet + + + + + + 10 + 10 + 611 + 17 + + + + 12/03/2020 12:34 + + + + + + diff --git a/src/chatbubblepartner.cpp b/src/chatbubblepartner.cpp new file mode 100644 index 0000000..690f608 --- /dev/null +++ b/src/chatbubblepartner.cpp @@ -0,0 +1,14 @@ +#include "chatbubblepartner.h" +#include "ui_chatbubblepartner.h" + +ChatBubblePartner::ChatBubblePartner(QWidget *parent) : + QWidget(parent), + ui(new Ui::ChatBubblePartner) +{ + ui->setupUi(this); +} + +ChatBubblePartner::~ChatBubblePartner() +{ + delete ui; +} diff --git a/src/chatbubblepartner.h b/src/chatbubblepartner.h new file mode 100644 index 0000000..feb950b --- /dev/null +++ b/src/chatbubblepartner.h @@ -0,0 +1,22 @@ +#ifndef CHATBUBBLEPARTNER_H +#define CHATBUBBLEPARTNER_H + +#include + +namespace Ui { +class ChatBubblePartner; +} + +class ChatBubblePartner : public QWidget +{ + Q_OBJECT + +public: + explicit ChatBubblePartner(QWidget *parent = nullptr); + ~ChatBubblePartner(); + +private: + Ui::ChatBubblePartner *ui; +}; + +#endif // CHATBUBBLEPARTNER_H diff --git a/src/chatbubblepartner.ui b/src/chatbubblepartner.ui new file mode 100644 index 0000000..4decec9 --- /dev/null +++ b/src/chatbubblepartner.ui @@ -0,0 +1,57 @@ + + + ChatBubblePartner + + + + 0 + 0 + 646 + 76 + + + + Form + + + QWidget{ + background: #c8e1ff; + border: 1px solid #fefefe; + border-radius: 3px; +} +QLabel +{ + background: none; + border: none; +} + + + + + 10 + 30 + 611 + 41 + + + + Lorem ipsum dolor sit amet + + + + + + 10 + 10 + 611 + 17 + + + + 12/03/2020 12:34 + + + + + + diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f54a0a2..5ccfb7a 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1356,7 +1356,7 @@ 340 80 - 871 + 908 361 @@ -1379,7 +1379,7 @@ 357 483 - 851 + 891 128 @@ -1416,7 +1416,7 @@ - 1110 + 1150 460 91 17 @@ -1613,6 +1613,11 @@ + + MemoEdit + QPlainTextEdit +
memoedit.h
+
AddressCombo QComboBox @@ -1628,11 +1633,6 @@ QLabel
fillediconlabel.h
- - MemoEdit - QPlainTextEdit -
memoedit.h
-
Address1 From 8793d96e39c79d5b1ef77b8565a47b598a9ecef4 Mon Sep 17 00:00:00 2001 From: Strider Date: Sun, 26 Apr 2020 11:03:22 +0200 Subject: [PATCH 003/253] update// changed small things of chat tab --- src/mainwindow.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 5ccfb7a..a43877e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1360,6 +1360,9 @@ 361 + + QListView::Adjust + From 22cc12212002af83b68f254aedbd1b9d20898546 Mon Sep 17 00:00:00 2001 From: Strider Date: Sun, 26 Apr 2020 21:50:49 +0200 Subject: [PATCH 004/253] update// addec chatmodel.h chatmodel.cpp to realize the whole chat history --- silentdragon-lite.pro | 6 ++- src/chatmodel.cpp | 49 ++++++++++++++++++++++ src/chatmodel.h | 94 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 src/chatmodel.cpp create mode 100644 src/chatmodel.h diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index e8c50d5..b692159 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -67,7 +67,8 @@ SOURCES += \ src/liteinterface.cpp \ src/camount.cpp \ src/chatbubbleme.cpp \ - src/chatbubblepartner.cpp + src/chatbubblepartner.cpp \ + src/chatmodel.cpp HEADERS += \ src/firsttimewizard.h \ @@ -98,7 +99,8 @@ HEADERS += \ src/camount.h \ lib/silentdragonlitelib.h \ src/chatbubbleme.h \ - src/chatbubblepartner.h + src/chatbubblepartner.h \ + src/chatmodel.h FORMS += \ src/encryption.ui \ diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp new file mode 100644 index 0000000..b65bd4a --- /dev/null +++ b/src/chatmodel.cpp @@ -0,0 +1,49 @@ +#include "chatmodel.h" + +ChatModel::ChatModel(std::map chatItems) +{ + this->chatItems = chatItems; +} + +ChatModel::ChatModel(std::vector chatItems) +{ + this->setItems(chatItems); +} + +std::map ChatModel::getItems() +{ + return this->chatItems; +} + +void ChatModel::setItems(std::map items) +{ + this->chatItems = chatItems; +} + +void ChatModel::setItems(std::vector items) +{ + for(ChatItem c : items) + { + this->chatItems[c.getTimestamp()] = c; + } +} + +void ChatModel::renderChatBox(QListView &view) +{ + for(ChatItem c : items) + { + view.getItems().add(QString("[Timestamp] : lorem ipsum ....")); + } + + //todo render items to view +} + +void ChatModel::renderChatBox(QListView *view) +{ + for(ChatItem c : items) + { + view->getItems().add(QString("[Timestamp] : lorem ipsum ....")); + } + + //todo render items to view +} \ No newline at end of file diff --git a/src/chatmodel.h b/src/chatmodel.h new file mode 100644 index 0000000..5dd8904 --- /dev/null +++ b/src/chatmodel.h @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +class ChatItem +{ + private: + long timestamp; + std::string address; + std::string contact; + std::string memo; + bool outgoing = false; + + public: + ChatItem() {} + ChatItem(long timestamp, std::string address, std::string contact, std::string memo); + ChatItem(long timestamp, std::string address, std::string contact, std::string memo, bool outgoing = false); + + long getTimestamp() + { + return this->timestamp; + } + + std::string getAddress() + { + return this->address; + } + + std::string getContact() + { + return this->contact; + } + + std::string getMemo() + { + return this->memo; + } + + bool isOutgoing() + { + return this->outgoing; + } + + void setTimestamp(long timestamp) + { + this->timestamp = timestamp; + } + + void setAddress(std::string address) + { + this->address = address; + } + + void setContact(std::string contact) + { + this->contact = contact; + } + + void setMemo(std::string memo) + { + this->memo = memo; + } + + void toggleOutgo() + { + this->outgoing = true; + } + + ~ChatItem() + { + delete timestamp; + delete address; + delete contact; + delete memo; + delete outgoing; + } +}; + +class ChatModel +{ + private: + std::map chatItems; + + public: + ChatModel() {}; + ChatModel(std::map chatItems); + ChatModel(std::vector chatItems); + std::map getItems(); + void setItems(std::map items); + void setItems(std::vector items); + void renderChatBox(QListView &view); + void renderChatBox(QListView *view); +}; \ No newline at end of file From 008d3fd6c2fbe22c68e188f076c70d1aab0d45bf Mon Sep 17 00:00:00 2001 From: Strider Date: Sun, 26 Apr 2020 22:28:27 +0200 Subject: [PATCH 005/253] update// fixed stuff --- src/chatmodel.cpp | 39 +++++++++++++++++++++++++++++++-------- src/chatmodel.h | 32 ++++++++++++++++++-------------- src/controller.cpp | 24 +++++++++++++++++++++++- src/controller.h | 3 +++ 4 files changed, 75 insertions(+), 23 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b65bd4a..f6fbb84 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -28,22 +28,45 @@ void ChatModel::setItems(std::vector items) } } +void ChatModel::clear() +{ + this->chatItems.clear(); +} + +void ChatModel::addMessage(ChatItem item) +{ + this->chatItems[item.getTimestamp()] = item; +} + +void ChatModel::addMessage(long timestamp, ChatItem item) +{ + this->chatItems[timestamp] = item; +} + +void ChatModel::showMessages() +{ + for(auto &c : this->chatItems) + { + qDebug() << "[" << c.second.getTimestamp() << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); + } +} + void ChatModel::renderChatBox(QListView &view) { - for(ChatItem c : items) + /*for(auto &c : this->chatItems) { - view.getItems().add(QString("[Timestamp] : lorem ipsum ....")); - } - + //view.getItems().add(QString("[Timestamp] : lorem ipsum ....")); + }*/ + qDebug() << "not implemented yet"; //todo render items to view } void ChatModel::renderChatBox(QListView *view) { - for(ChatItem c : items) + /*for(auto &c : this->chatItems) { - view->getItems().add(QString("[Timestamp] : lorem ipsum ....")); - } - + //view->getItems().add(QString("[Timestamp] : lorem ipsum ....")); + }*/ + qDebug() << "not implemented yet blyat"; //todo render items to view } \ No newline at end of file diff --git a/src/chatmodel.h b/src/chatmodel.h index 5dd8904..5a35db9 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -7,32 +7,32 @@ class ChatItem { private: long timestamp; - std::string address; - std::string contact; - std::string memo; + QString address; + QString contact; + QString memo; bool outgoing = false; public: ChatItem() {} - ChatItem(long timestamp, std::string address, std::string contact, std::string memo); - ChatItem(long timestamp, std::string address, std::string contact, std::string memo, bool outgoing = false); + ChatItem(long timestamp, QString address, QString contact, QString memo); + ChatItem(long timestamp, QString address, QString contact, QString memo, bool outgoing = false); long getTimestamp() { return this->timestamp; } - std::string getAddress() + QString getAddress() { return this->address; } - std::string getContact() + QString getContact() { return this->contact; } - std::string getMemo() + QString getMemo() { return this->memo; } @@ -47,17 +47,17 @@ class ChatItem this->timestamp = timestamp; } - void setAddress(std::string address) + void setAddress(QString address) { this->address = address; } - void setContact(std::string contact) + void setContact(QString contact) { this->contact = contact; } - void setMemo(std::string memo) + void setMemo(QString memo) { this->memo = memo; } @@ -69,11 +69,11 @@ class ChatItem ~ChatItem() { - delete timestamp; + /*delete timestamp; delete address; delete contact; delete memo; - delete outgoing; + delete outgoing;*/ } }; @@ -91,4 +91,8 @@ class ChatModel void setItems(std::vector items); void renderChatBox(QListView &view); void renderChatBox(QListView *view); + void showMessages(); + void clear(); + void addMessage(ChatItem item); + void addMessage(long timestamp, ChatItem item); }; \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 18a158e..0661b06 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -876,7 +876,18 @@ void Controller::refreshTransactions() QString memo; if (!o["memo"].is_null()) + { + ChatItem item = ChatItem( + datetime, + address, + QString(""), + memo, + true // is an outgoing message + ); + chatModel->addMessage(item); memo = QString::fromStdString(o["memo"]); + } + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -913,6 +924,15 @@ void Controller::refreshTransactions() model->markAddressUsed(address); QString memo; if (!it["memo"].is_null()) + { + ChatItem item = ChatItem( + datetime, + address, + QString(""), + memo + ); + chatModel->addMessage(item); + } memo = QString::fromStdString(it["memo"]); items.push_back( @@ -958,7 +978,9 @@ void Controller::refreshTransactions() updateUIBalances(); // Update model data, which updates the table view - transactionsTableModel->replaceData(txdata); + transactionsTableModel->replaceData(txdata); + //chatModel->renderChatBox(); + chatModel->showMessages(); }); } diff --git a/src/controller.h b/src/controller.h index 29d5c0d..5071dee 100644 --- a/src/controller.h +++ b/src/controller.h @@ -11,9 +11,12 @@ #include "mainwindow.h" #include "liteinterface.h" #include "connection.h" +#include "chatmodel.h" using json = nlohmann::json; +ChatModel *chatModel = new ChatModel(); + struct WatchedTx { QString opid; Tx tx; From a8ee1c68be5999f2a3b03544100be27e3a4c4fb5 Mon Sep 17 00:00:00 2001 From: Strider Date: Mon, 27 Apr 2020 20:18:14 +0200 Subject: [PATCH 006/253] update// moved class to a normal variable instace --- src/chatmodel.h | 57 +++++++++++++++++++++++++++++++--------------- src/controller.cpp | 7 ++++-- src/controller.h | 2 -- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/chatmodel.h b/src/chatmodel.h index 5a35db9..d44a35f 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -1,3 +1,5 @@ +#ifndef CHATMODEL_H +#define CHATMODEL_H #include #include #include @@ -6,65 +8,83 @@ class ChatItem { private: - long timestamp; - QString address; - QString contact; - QString memo; - bool outgoing = false; + long _timestamp; + QString _address; + QString _contact; + QString _memo; + bool _outgoing = false; public: ChatItem() {} - ChatItem(long timestamp, QString address, QString contact, QString memo); - ChatItem(long timestamp, QString address, QString contact, QString memo, bool outgoing = false); + + ChatItem(long timestamp, QString address, QString contact, QString memo) + { + _timestamp = timestamp; + _address = address; + _contact = contact; + _memo = memo; + _outgoing = false; + + } + + ChatItem(long timestamp, QString address, QString contact, QString memo, bool outgoing) + { + _timestamp = timestamp; + _address = address; + _contact = contact; + _memo = memo; + _outgoing = outgoing; + + } long getTimestamp() { - return this->timestamp; + return _timestamp; } QString getAddress() { - return this->address; + return _address; } QString getContact() { - return this->contact; + return _contact; } QString getMemo() { - return this->memo; + return _memo; } bool isOutgoing() { - return this->outgoing; + return _outgoing; } void setTimestamp(long timestamp) { - this->timestamp = timestamp; + _timestamp = timestamp; } void setAddress(QString address) { - this->address = address; + _address = address; } void setContact(QString contact) { - this->contact = contact; + _contact = contact; } void setMemo(QString memo) { - this->memo = memo; + _memo = memo; } void toggleOutgo() { - this->outgoing = true; + _outgoing = true; } ~ChatItem() @@ -95,4 +115,5 @@ class ChatModel void clear(); void addMessage(ChatItem item); void addMessage(long timestamp, ChatItem item); -}; \ No newline at end of file +}; +#endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 0661b06..b7c5dba 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -10,6 +10,7 @@ template<> DataStore* DataStore::instance = nullptr; template<> bool DataStore::instanced = false; +ChatModel *chatModel = new ChatModel(); using json = nlohmann::json; @@ -877,6 +878,7 @@ void Controller::refreshTransactions() QString memo; if (!o["memo"].is_null()) { + memo = QString::fromStdString(o["memo"]); ChatItem item = ChatItem( datetime, address, @@ -885,7 +887,7 @@ void Controller::refreshTransactions() true // is an outgoing message ); chatModel->addMessage(item); - memo = QString::fromStdString(o["memo"]); + } @@ -925,6 +927,7 @@ void Controller::refreshTransactions() QString memo; if (!it["memo"].is_null()) { + memo = QString::fromStdString(it["memo"]); ChatItem item = ChatItem( datetime, address, @@ -933,7 +936,7 @@ void Controller::refreshTransactions() ); chatModel->addMessage(item); } - memo = QString::fromStdString(it["memo"]); + items.push_back( TransactionItemDetail{ diff --git a/src/controller.h b/src/controller.h index 5071dee..a5f0fee 100644 --- a/src/controller.h +++ b/src/controller.h @@ -15,8 +15,6 @@ using json = nlohmann::json; -ChatModel *chatModel = new ChatModel(); - struct WatchedTx { QString opid; Tx tx; From fd7170cf2a6811411d32955f7d920dd5d63d7e52 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 27 Apr 2020 21:01:06 +0200 Subject: [PATCH 007/253] add switch to QListWidget for Chat --- src/mainwindow.ui | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index a43877e..700892d 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1328,7 +1328,7 @@ HushChat - + 0 @@ -1351,19 +1351,6 @@ <html><head/><body><p align="center">Contact</p></body></html> - - - - 340 - 80 - 908 - 361 - - - - QListView::Adjust - - @@ -1445,6 +1432,16 @@ <html><head/><body><p align="center">Messages</p></body></html> + + + + 340 + 80 + 921 + 371 + + + From b69297f9da79d15dfaa87c80c8ad18e83c68303f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 27 Apr 2020 21:04:11 +0200 Subject: [PATCH 008/253] rename QListWidget --- src/mainwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 700892d..39e5e9e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1432,7 +1432,7 @@ <html><head/><body><p align="center">Messages</p></body></html> - + 340 From b79334a497dbcca30f57bd5795d4931a88f660ff Mon Sep 17 00:00:00 2001 From: Strider Date: Mon, 27 Apr 2020 21:53:37 +0200 Subject: [PATCH 009/253] update// added chatmessages to chatwindow --- src/chatmodel.cpp | 27 ++++++++++++++++++++------- src/chatmodel.h | 6 +++--- src/controller.cpp | 10 ++++++++-- src/controller.h | 1 + src/mainwindow.cpp | 7 ++++++- src/mainwindow.h | 1 + src/mainwindow.ui | 2 +- 7 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index f6fbb84..e1962c9 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -51,7 +51,7 @@ void ChatModel::showMessages() } } -void ChatModel::renderChatBox(QListView &view) +void ChatModel::renderChatBox(QListWidget &view) { /*for(auto &c : this->chatItems) { @@ -61,12 +61,25 @@ void ChatModel::renderChatBox(QListView &view) //todo render items to view } -void ChatModel::renderChatBox(QListView *view) +void ChatModel::renderChatBox(QListWidget *view) { - /*for(auto &c : this->chatItems) + qDebug() << "called ChatModel::renderChatBox(QListWidget *view)"; + QString line = ""; + while(view->count() > 0) { - //view->getItems().add(QString("[Timestamp] : lorem ipsum ....")); - }*/ - qDebug() << "not implemented yet blyat"; - //todo render items to view + view->takeItem(0); + } + + for(auto &c : this->chatItems) + { + QDateTime myDateTime; + + myDateTime.setTime_t(c.second.getTimestamp()); + qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); + line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); + line += QString("<") + QString(c.second.getAddress()) + QString("> :"); + line += QString(c.second.getMemo()); + view->addItem(line); + line =""; + } } \ No newline at end of file diff --git a/src/chatmodel.h b/src/chatmodel.h index d44a35f..56db136 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include class ChatItem { @@ -109,8 +109,8 @@ class ChatModel std::map getItems(); void setItems(std::map items); void setItems(std::vector items); - void renderChatBox(QListView &view); - void renderChatBox(QListView *view); + void renderChatBox(QListWidget &view); + void renderChatBox(QListWidget *view); void showMessages(); void clear(); void addMessage(ChatItem item); diff --git a/src/controller.cpp b/src/controller.cpp index b7c5dba..daace4e 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -982,11 +982,17 @@ void Controller::refreshTransactions() // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); - //chatModel->renderChatBox(); - chatModel->showMessages(); + chatModel->renderChatBox(ui->listChatMemo); + //chatModel->showMessages(); }); } +void Controller::refreshChat(QListWidget *listWidget) +{ + qDebug() << "Called Controller::refreshChat(QListWidget *listWidget)"; + chatModel->renderChatBox(listWidget); +} + // If the wallet is encrpyted and locked, we need to unlock it void Controller::unlockIfEncrypted(std::function cb, std::function error) { diff --git a/src/controller.h b/src/controller.h index a5f0fee..32d843b 100644 --- a/src/controller.h +++ b/src/controller.h @@ -71,6 +71,7 @@ public: void refreshGBPCAP(); void refreshAUDCAP(); + void refreshChat(QListWidget *listWidget); void executeStandardUITransaction(Tx tx); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5352a95..b268750 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -900,7 +900,6 @@ void MainWindow::setupTransactionsTab() { // Set up context menu on transactions tab ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu); - // Table right click QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) { QModelIndex index = ui->transactionsTable->indexAt(pos); @@ -983,6 +982,12 @@ void MainWindow::setupTransactionsTab() { }); } +void MainWindow::updateChat() +{ + qDebug() << "Called MainWindow::updateChat()"; + rpc->refreshChat(ui->listChatMemo); +} + void MainWindow::addNewZaddr(bool sapling) { rpc->createNewZaddr(sapling, [=] (json reply) { QString addr = QString::fromStdString(reply.get()[0]); diff --git a/src/mainwindow.h b/src/mainwindow.h index 50f833a..85f3595 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -85,6 +85,7 @@ private: void setupSendTab(); void setupTransactionsTab(); + void updateChat(); void setupReceiveTab(); void setupBalancesTab(); void setuphushdTab(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 39e5e9e..6e8dcfe 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1432,7 +1432,7 @@ <html><head/><body><p align="center">Messages</p></body></html> - + 340 From 38a1d6966aab880e2e21370423218149b96db005 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 27 Apr 2020 23:10:42 +0200 Subject: [PATCH 010/253] add sending ability for HushChat tab --- src/chatmodel.cpp | 205 ++++++++++++++++++++++++++++++++++++++++++++- src/chatmodel.h | 18 ++++ src/mainwindow.cpp | 1 + src/mainwindow.h | 7 +- src/mainwindow.ui | 42 ++++++---- 5 files changed, 253 insertions(+), 20 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index e1962c9..25e012d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -1,4 +1,13 @@ #include "chatmodel.h" +#include "settings.h" +#include "ui_confirm.h" +#include "controller.h" +#include "mainwindow.h" +#include "ui_mainwindow.h" +#include "addressbook.h" +#include "ui_memodialog.h" + + ChatModel::ChatModel(std::map chatItems) { @@ -77,9 +86,203 @@ void ChatModel::renderChatBox(QListWidget *view) myDateTime.setTime_t(c.second.getTimestamp()); qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString("<") + QString(c.second.getAddress()) + QString("> :"); + line += QString("<") + QString(c.second.getAddress()) + QString("> :\n"); line += QString(c.second.getMemo()); view->addItem(line); line =""; } +} + +void MainWindow::setupchatTab() { + +// Send button + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + + } + +ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { + QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); +} + +void ChatMemoEdit::updateDisplay() { + QString txt = this->toPlainText(); + if (lenDisplayLabel) + lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); + + if (txt.toUtf8().size() <= maxlen) { + // Everything is fine + if (sendChatButton) + sendChatButton->setEnabled(true); + + if (lenDisplayLabel) + lenDisplayLabel->setStyleSheet(""); + } + else { + // Overweight + if (sendChatButton) + sendChatButton->setEnabled(false); + + if (lenDisplayLabel) + lenDisplayLabel->setStyleSheet("color: red;"); + } +} + +void ChatMemoEdit::setMaxLen(int len) { + this->maxlen = len; + updateDisplay(); +} + +void ChatMemoEdit::setLenDisplayLabel(QLabel* label) { + this->lenDisplayLabel = label; +} + +void ChatMemoEdit::setSendChatButton(QPushButton* button) { + this->sendChatButton = button; +} + +// Create a Tx from the current state of the Chat page. +Tx MainWindow::createTxFromChatPage() { + Tx tx; + CAmount totalAmt; + // For each addr/amt in the Chat tab + { + QString addr = ""; // We need to set the reply Address for our Contact here + // Remove label if it exists + addr = AddressBook::addressFromAddressLabel(addr); + + QString amtStr = "0.00001"; + + // bool ok; + CAmount amt; + + + amt = CAmount::fromDecimalString("0.00001"); + totalAmt = totalAmt + amt; + + + QString memo = ui->memoTxtChat->toPlainText().trimmed(); + //ui->chatmemoSize->setLenDisplayLabel() + + + tx.toAddrs.push_back(ToFields{addr, amt, memo,}) ; + + qDebug() << "pushback chattx"; + } + + tx.fee = Settings::getMinerFee(); + + return tx; + + qDebug() << "ChatTx created"; +} + +void MainWindow::sendChatButton() { + // Create a Tx from the values on the send tab. Note that this Tx object + // might not be valid yet. + + // Memos can only be used with zAddrs. So check that first + //auto addr = "zs1fllv4hgrjddnz2yz5dng9kchcg3wkhs0j2v5v3nc89w3r3kntkgq2sefcz2a9k2ycc8f6t0gm2q"; + // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), + // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), + // QMessageBox::Ok, this); + + // msg.exec(); + //return; + //} + + Tx tx = createTxFromChatPage(); + + QString error = doSendChatTxValidations(tx); + + if (!error.isEmpty()) { + // Something went wrong, so show an error and exit + QMessageBox msg(QMessageBox::Critical, tr("Message Error"), error, + QMessageBox::Ok, this); + + msg.exec(); + + // abort the Tx + return; + qDebug() << "Tx aborted"; + } + + // Create a new Dialog to show that we are computing/sending the Tx + auto d = new QDialog(this); + auto connD = new Ui_ConnectionDialog(); + connD->setupUi(d); + QPixmap logo(":/img/res/logobig.gif"); + connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + + connD->status->setText(tr("Please wait...")); + connD->statusDetail->setText(tr("Your Message will be send")); + + d->show(); + + // And send the Tx + rpc->executeTransaction(tx, + [=] (QString txid) { + ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid); + + connD->status->setText(tr("Done!")); + connD->statusDetail->setText(txid); + + QTimer::singleShot(1000, [=]() { + d->accept(); + d->close(); + delete connD; + delete d; + + }); + + // Force a UI update so we get the unconfirmed Tx + rpc->refresh(true); + + }, + // Errored out + [=] (QString opid, QString errStr) { + ui->statusBar->showMessage(QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000); + + d->accept(); + d->close(); + delete connD; + delete d; + + if (!opid.isEmpty()) + errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; + + QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); + } + ); + } + + +QString MainWindow::doSendChatTxValidations(Tx tx) { + // Check to see if we have enough verified funds to send the Tx. + + CAmount total; + for (auto toAddr : tx.toAddrs) { + if (!Settings::isValidAddress(toAddr.addr)) { + QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr); + return QString(tr("Recipient Address ")) % addr % tr(" is Invalid"); + } + + // This technically shouldn't be possible, but issue #62 seems to have discovered a bug + // somewhere, so just add a check to make sure. + if (toAddr.amount.toqint64() < 0) { + return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr)); + } + + total = total + toAddr.amount; + } + total = total + tx.fee; + + auto available = rpc->getModel()->getAvailableBalance(); + + if (available < total) { + return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") + .arg(available.toDecimalhushString(), total.toDecimalhushString()); + } + + return ""; } \ No newline at end of file diff --git a/src/chatmodel.h b/src/chatmodel.h index 56db136..e893acf 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -116,4 +116,22 @@ class ChatModel void addMessage(ChatItem item); void addMessage(long timestamp, ChatItem item); }; + +class ChatMemoEdit : public QPlainTextEdit +{ +public: + ChatMemoEdit(QWidget* parent); + + void setMaxLen(int len); + void setLenDisplayLabel(QLabel* label); + void setSendChatButton(QPushButton* button); + void includeReplyTo(QString replyToAddress); + void updateDisplay(); + +private: + int maxlen = 512; + QLabel* lenDisplayLabel = nullptr; + QPushButton* sendChatButton = nullptr; +}; + #endif \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b268750..b17f086 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -152,6 +152,7 @@ MainWindow::MainWindow(QWidget *parent) : setupReceiveTab(); setupBalancesTab(); setuphushdTab(); + setupchatTab(); rpc = new Controller(this); diff --git a/src/mainwindow.h b/src/mainwindow.h index 85f3595..17194b4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -47,6 +47,7 @@ public: QRegExpValidator* getAmountValidator() { return amtValidator; } QString doSendTxValidations(Tx tx); + QString doSendChatTxValidations(Tx tx); void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); @@ -85,10 +86,11 @@ private: void setupSendTab(); void setupTransactionsTab(); - void updateChat(); void setupReceiveTab(); void setupBalancesTab(); void setuphushdTab(); + void setupchatTab(); + void updateChat(); void setupSettingsModal(); void setupStatusBar(); @@ -98,11 +100,14 @@ private: Tx createTxFromSendPage(); bool confirmTx(Tx tx, RecurringPaymentInfo* rpi); + Tx createTxFromChatPage(); + void encryptWallet(); void removeWalletEncryption(); void cancelButton(); void sendButton(); + void sendChatButton(); void addAddressSection(); void maxAmountChecked(int checked); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 6e8dcfe..6d493af 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1367,9 +1367,9 @@ - 357 + 347 483 - 891 + 901 128 @@ -1387,22 +1387,6 @@ Include Reply Address - - - - 692 - 618 - 189 - 25 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - @@ -1442,6 +1426,28 @@ + + + + 1130 + 620 + 114 + 25 + + + + + 100 + 0 + + + + Send + + + false + + From ec5057e4ce2e73138c5936bf0e2839f2a5134f77 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 27 Apr 2020 23:12:43 +0200 Subject: [PATCH 011/253] set amt to 0 for HushChat Memos --- src/chatmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 25e012d..e3374f1 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -150,7 +150,7 @@ Tx MainWindow::createTxFromChatPage() { // Remove label if it exists addr = AddressBook::addressFromAddressLabel(addr); - QString amtStr = "0.00001"; + QString amtStr = "0"; // bool ok; CAmount amt; From 2efec07e42cf107a8e4cdc219ffe9e2c5922794c Mon Sep 17 00:00:00 2001 From: Strider Date: Tue, 28 Apr 2020 20:24:50 +0200 Subject: [PATCH 012/253] update// refactored addressbook with new storage format --- compile.log | 5 +++ src/addressbook.cpp | 98 +++++++++++++++++++++++++++++--------------- src/addressbook.h | 17 ++++---- src/chatmodel.cpp | 4 +- src/contactmodel.cpp | 9 ++++ src/contactmodel.h | 68 ++++++++++++++++++++++++++++++ src/controller.cpp | 1 + src/controller.h | 1 + src/mainwindow.cpp | 4 +- src/sendtab.cpp | 2 +- 10 files changed, 165 insertions(+), 44 deletions(-) create mode 100644 compile.log create mode 100644 src/contactmodel.cpp create mode 100644 src/contactmodel.h diff --git a/compile.log b/compile.log new file mode 100644 index 0000000..6c6584f --- /dev/null +++ b/compile.log @@ -0,0 +1,5 @@ +Compiling SilentDragonLite 1.2.2 with 4 threads... +g++ -c -include bin/SilentDragonLite -pipe -g -std=gnu++1y -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQAPPLICATION_CLASS=QApplication -D_FORTIFY_SOURCE=2 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -Isrc/3rdparty -Isrc -Isingleapplication -Ires -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtWebSockets -isystem /usr/include/x86_64-linux-gnu/qt5/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -Ibin -Isrc -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o bin/mainwindow.o src/mainwindow.cpp +g++ -c -include bin/SilentDragonLite -pipe -g -std=gnu++1y -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQAPPLICATION_CLASS=QApplication -D_FORTIFY_SOURCE=2 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -Isrc/3rdparty -Isrc -Isingleapplication -Ires -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtWebSockets -isystem /usr/include/x86_64-linux-gnu/qt5/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -Ibin -Isrc -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o bin/sendtab.o src/sendtab.cpp +g++ -c -include bin/SilentDragonLite -pipe -g -std=gnu++1y -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQAPPLICATION_CLASS=QApplication -D_FORTIFY_SOURCE=2 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -Isrc/3rdparty -Isrc -Isingleapplication -Ires -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtWebSockets -isystem /usr/include/x86_64-linux-gnu/qt5/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -Ibin -Isrc -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o bin/addressbook.o src/addressbook.cpp +g++ -c -include bin/SilentDragonLite -pipe -g -std=gnu++1y -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQAPPLICATION_CLASS=QApplication -D_FORTIFY_SOURCE=2 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_WEBSOCKETS_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -Isrc/3rdparty -Isrc -Isingleapplication -Ires -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtWebSockets -isystem /usr/include/x86_64-linux-gnu/qt5/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -Ibin -Isrc -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o bin/addresscombo.o src/addresscombo.cpp diff --git a/src/addressbook.cpp b/src/addressbook.cpp index a00a355..060b5ca 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -38,10 +38,10 @@ void AddressBookModel::loadData() ); } -void AddressBookModel::addNewLabel(QString label, QString addr) +void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr) { //labels.push_back(QPair(label, addr)); - AddressBook::getInstance()->addAddressLabel(label, addr); + AddressBook::getInstance()->addAddressLabel(label, addr, myAddr); labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); @@ -53,22 +53,27 @@ void AddressBookModel::removeItemAt(int row) if (row >= labels.size()) return; - AddressBook::getInstance()->removeAddressLabel(labels[row].first, labels[row].second); + AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress()); labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); layoutChanged(); } -QPair AddressBookModel::itemAt(int row) +ContactItem AddressBookModel::itemAt(int row) { - if (row >= labels.size()) - return QPair(); + if (row >= labels.size()) + { + ContactItem item = ContactItem("", "", ""); + return item; + } + return labels.at(row); } + int AddressBookModel::rowCount(const QModelIndex&) const { return labels.size(); @@ -86,8 +91,8 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const { switch(index.column()) { - case 0: return labels.at(index.row()).first; - case 1: return labels.at(index.row()).second; + case 0: return labels.at(index.row()).getName(); + case 1: return labels.at(index.row()).getPartnerAddress(); } } @@ -171,7 +176,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) return; } - model.addNewLabel(newLabel, ab.addr->text()); + model.addNewLabel(newLabel, ab.addr->text(), ""); }); // Import Button @@ -209,7 +214,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) continue; // Add label, address. - model.addNewLabel(items.at(1), items.at(0)); + model.addNewLabel(items.at(1), items.at(0), ""); numImported++; } @@ -233,8 +238,8 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) if (index.row() < 0) return; - QString lbl = model.itemAt(index.row()).first; - QString addr = model.itemAt(index.row()).second; + QString lbl = model.itemAt(index.row()).getName(); + QString addr = model.itemAt(index.row()).getPartnerAddress(); d.accept(); fnSetTargetLabelAddr(target, lbl, addr); }); @@ -246,8 +251,8 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) if (index.row() < 0) return; - QString lbl = model.itemAt(index.row()).first; - QString addr = model.itemAt(index.row()).second; + QString lbl = model.itemAt(index.row()).getName(); + QString addr = model.itemAt(index.row()).getPartnerAddress(); QMenu menu(parent); @@ -273,7 +278,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto selection = ab.addresses->selectionModel(); if (selection && selection->hasSelection() && selection->selectedRows().size() > 0) { auto item = model.itemAt(selection->selectedRows().at(0).row()); - fnSetTargetLabelAddr(target, item.first, item.second); + fnSetTargetLabelAddr(target, item.getName(), item.getPartnerAddress()); } }; @@ -307,15 +312,35 @@ void AddressBook::readFromStorage() file.open(QIODevice::ReadOnly); QDataStream in(&file); // read the data serialized from the file QString version; - in >> version >> allLabels; + in >> version; + qDebug() << "Detected old addressbook format"; + // Convert old addressbook format v1 to v2 + QList> stuff; + in >> stuff; + qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) + { + //qDebug() << "0:" << stuff[i][0]; + //qDebug() << "1:" << stuff[i][1]; + //qDebug() << "2:" << stuff[i][2]; + ContactItem contact = ContactItem(stuff[i][2], stuff[i][1], stuff[i][0]); + qDebug() << "contact=" << contact.toQTString(); + allLabels.push_back(contact); + } + + qDebug() << "Read " << version << " Hush contacts from disk..."; file.close(); } + else + { + qDebug() << "No Hush contacts found on disk!"; + } // Special. // Add the default silentdragon donation address if it isn't already present // QList allAddresses; // std::transform(allLabels.begin(), allLabels.end(), - // std::back_inserter(allAddresses), [=] (auto i) { return i.second; }); + // std::back_inserter(allAddresses), [=] (auto i) { return i.getPartnerAddress(); }); // if (!allAddresses.contains(Settings::getDonationAddr(true))) { // allLabels.append(QPair("silentdragon donation", Settings::getDonationAddr(true))); // } @@ -326,7 +351,16 @@ void AddressBook::writeToStorage() QFile file(AddressBook::writeableFile()); file.open(QIODevice::ReadWrite | QIODevice::Truncate); QDataStream out(&file); // we will serialize the data into the file - out << QString("v1") << allLabels; + QList> contacts; + for(auto &item: allLabels) + { + QList c; + c.push_back(item.getName()); + c.push_back(item.getPartnerAddress()); + c.push_back(item.getMyAddress()); + contacts.push_back(c); + } + out << QString("v1") << contacts; file.close(); } @@ -346,17 +380,17 @@ QString AddressBook::writeableFile() // Add a new address/label to the database -void AddressBook::addAddressLabel(QString label, QString address) +void AddressBook::addAddressLabel(QString label, QString address, QString myAddr) { Q_ASSERT(Settings::isValidAddress(address)); - - // First, remove any existing label + // getName(), remove any existing label // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) - if (allLabels[i].first == label) - removeAddressLabel(allLabels[i].first, allLabels[i].second); + if (allLabels[i].getName() == label) + removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress()); - allLabels.push_back(QPair(label, address)); + ContactItem item = ContactItem(myAddr, address, label); + allLabels.push_back(item); writeToStorage(); } @@ -366,7 +400,7 @@ void AddressBook::removeAddressLabel(QString label, QString address) // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) { - if (allLabels[i].first == label && allLabels[i].second == address) + if (allLabels[i].getName() == label && allLabels[i].getPartnerAddress() == address) { allLabels.removeAt(i); writeToStorage(); @@ -380,9 +414,9 @@ void AddressBook::updateLabel(QString oldlabel, QString address, QString newlabe // Iterate over the list and update the label/address for (int i = 0; i < allLabels.size(); i++) { - if (allLabels[i].first == oldlabel && allLabels[i].second == address) + if (allLabels[i].getName() == oldlabel && allLabels[i].getPartnerAddress() == address) { - allLabels[i].first = newlabel; + allLabels[i].setName(newlabel); writeToStorage(); return; } @@ -390,7 +424,7 @@ void AddressBook::updateLabel(QString oldlabel, QString address, QString newlabe } // Read all addresses -const QList>& AddressBook::getAllAddressLabels() +const QList& AddressBook::getAllAddressLabels() { if (allLabels.isEmpty()) readFromStorage(); @@ -402,8 +436,8 @@ const QList>& AddressBook::getAllAddressLabels() QString AddressBook::getLabelForAddress(QString addr) { for (auto i : allLabels) - if (i.second == addr) - return i.first; + if (i.getPartnerAddress() == addr) + return i.getName(); return ""; } @@ -412,8 +446,8 @@ QString AddressBook::getLabelForAddress(QString addr) QString AddressBook::getAddressForLabel(QString label) { for (auto i: allLabels) - if (i.first == label) - return i.second; + if (i.getName() == label) + return i.getPartnerAddress(); return ""; } diff --git a/src/addressbook.h b/src/addressbook.h index af64c07..13ba606 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -2,6 +2,7 @@ #define ADDRESSBOOK_H #include "precompiled.h" +#include "contactmodel.h" class MainWindow; @@ -10,10 +11,11 @@ class AddressBookModel : public QAbstractTableModel { public: AddressBookModel(QTableView* parent); ~AddressBookModel(); - - void addNewLabel(QString label, QString addr); + + void addNewLabel(QString label, QString address, QString myAddr); void removeItemAt(int row); - QPair itemAt(int row); + //QPair itemAt(int row); + ContactItem itemAt(int row); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; @@ -25,7 +27,8 @@ private: void saveData(); QTableView* parent; - QList> labels; + //QList> labels; + QList labels; QStringList headers; }; @@ -39,7 +42,7 @@ public: static QString addressFromAddressLabel(const QString& lblAddr); // Add a new address/label to the database - void addAddressLabel(QString label, QString address); + void addAddressLabel(QString label, QString address, QString myAddr); // Remove a new address/label from the database void removeAddressLabel(QString label, QString address); @@ -48,7 +51,7 @@ public: void updateLabel(QString oldlabel, QString address, QString newlabel); // Read all addresses - const QList>& getAllAddressLabels(); + const QList& getAllAddressLabels(); // Get an address's first label QString getLabelForAddress(QString address); @@ -61,7 +64,7 @@ private: void writeToStorage(); QString writeableFile(); - QList> allLabels; + QList allLabels; static AddressBook* instance; }; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index e3374f1..1561d4e 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -86,8 +86,8 @@ void ChatModel::renderChatBox(QListWidget *view) myDateTime.setTime_t(c.second.getTimestamp()); qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString("<") + QString(c.second.getAddress()) + QString("> :\n"); - line += QString(c.second.getMemo()); + line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); + line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; } diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp new file mode 100644 index 0000000..60df97b --- /dev/null +++ b/src/contactmodel.cpp @@ -0,0 +1,9 @@ +#include "contactmodel.h" + +void ContactModel::renderContactList(QListWidget* view) +{ + for(auto &c : this->_contacts) + { + view->addItem(c.getName()); + } +} \ No newline at end of file diff --git a/src/contactmodel.h b/src/contactmodel.h new file mode 100644 index 0000000..d1ce239 --- /dev/null +++ b/src/contactmodel.h @@ -0,0 +1,68 @@ +#ifndef CONTACTMODEL_H +#define CONTACTMODEL_H + +#include +#include +#include + +class ContactItem +{ + private: + QString _myAddress; + QString _partnerAddress; + QString _name; + + public: + ContactItem(); + ContactItem(QString myAddress, QString partnerAddress, QString name) + { + _myAddress = myAddress; + _partnerAddress = partnerAddress; + _name = name; + } + + QString getName() const + { + return _name; + } + + QString getMyAddress() const + { + return _myAddress; + } + + QString getPartnerAddress() const + { + return _partnerAddress; + } + + void setName(QString name) + { + _name = name; + } + + void setMyAddress(QString myAddress) + { + _myAddress = myAddress; + } + + void setPartnerAddress(QString partnerAddress) + { + _partnerAddress = partnerAddress; + } + + QString toQTString() + { + return _name + "|" + _partnerAddress + "|" + _myAddress; + } + +}; + +class ContactModel +{ + public: + ContactModel() {} + void renderContactList(QListWidget* view); +}; + +#endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index daace4e..24560e3 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -11,6 +11,7 @@ DataStore* DataStore::instance = nullptr; template<> bool DataStore::instanced = false; ChatModel *chatModel = new ChatModel(); +ContactModel *contactModel = new ContactModel(); using json = nlohmann::json; diff --git a/src/controller.h b/src/controller.h index 32d843b..7684863 100644 --- a/src/controller.h +++ b/src/controller.h @@ -12,6 +12,7 @@ #include "liteinterface.h" #include "connection.h" #include "chatmodel.h" +#include "contactmodel.h" using json = nlohmann::json; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b17f086..b243a6f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1241,7 +1241,7 @@ void MainWindow::setupReceiveTab() { } else if (curLabel.isEmpty() && !label.isEmpty()) { info = "Added Label '" % label % "'"; - AddressBook::getInstance()->addAddressLabel(label, addr); + AddressBook::getInstance()->addAddressLabel(label, addr, ""); } // Update labels everywhere on the UI @@ -1291,7 +1291,7 @@ void MainWindow::updateTAddrCombo(bool checked) { auto allTaddrs = this->rpc->getModel()->getAllTAddresses(); QSet labels; for (auto p : AddressBook::getInstance()->getAllAddressLabels()) { - labels.insert(p.second); + labels.insert(p.getPartnerAddress()); } std::for_each(allTaddrs.begin(), allTaddrs.end(), [=, &addrs] (auto& taddr) { // If the address is in the address book, add it. diff --git a/src/sendtab.cpp b/src/sendtab.cpp index 3fc5510..6d4ba38 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -207,7 +207,7 @@ void MainWindow::updateLabelsAutoComplete() { auto labels = AddressBook::getInstance()->getAllAddressLabels(); std::transform(labels.begin(), labels.end(), std::back_inserter(list), [=] (auto la) -> QString { - return la.first % "/" % la.second; + return la.getName() % "/" % la.getPartnerAddress(); }); delete labelCompleter; From 555ac40ec28d9e9b239e2cdda083e9dba0d3146f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 28 Apr 2020 20:32:31 +0200 Subject: [PATCH 013/253] Add Headermemo, work in Progress --- src/chatmodel.cpp | 70 ++++++++++++++++------------------------------ src/chatmodel.h | 18 +----------- src/mainwindow.cpp | 48 +++++++++++++++++++++++++++++++ src/mainwindow.h | 18 ++++++++++++ src/mainwindow.ui | 8 ------ 5 files changed, 91 insertions(+), 71 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 1561d4e..b799abd 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -6,6 +6,8 @@ #include "ui_mainwindow.h" #include "addressbook.h" #include "ui_memodialog.h" +#include "addressbook.h" +#include @@ -93,51 +95,23 @@ void ChatModel::renderChatBox(QListWidget *view) } } -void MainWindow::setupchatTab() { - -// Send button - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); +QString MainWindow::createHeaderMemo(QString cid, QString zaddr, int version=0, int headerNumber=1) +{ + QString header=""; + QJsonDocument j; + QJsonObject h; + // We use short keynames to use less space for metadata and so allow + // the user to send more actual data in memos + h["h"] = headerNumber; // header number + h["v"] = version; // HushChat version + h["z"] = zaddr; // zaddr to respond to + h["cid"] = cid; // conversation id - } + j.setObject(h); + header = j.toJson(); + qDebug() << "made header=" << header; -ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { - QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); -} - -void ChatMemoEdit::updateDisplay() { - QString txt = this->toPlainText(); - if (lenDisplayLabel) - lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); - - if (txt.toUtf8().size() <= maxlen) { - // Everything is fine - if (sendChatButton) - sendChatButton->setEnabled(true); - - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet(""); - } - else { - // Overweight - if (sendChatButton) - sendChatButton->setEnabled(false); - - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet("color: red;"); - } -} - -void ChatMemoEdit::setMaxLen(int len) { - this->maxlen = len; - updateDisplay(); -} - -void ChatMemoEdit::setLenDisplayLabel(QLabel* label) { - this->lenDisplayLabel = label; -} - -void ChatMemoEdit::setSendChatButton(QPushButton* button) { - this->sendChatButton = button; + return header; } // Create a Tx from the current state of the Chat page. @@ -158,13 +132,17 @@ Tx MainWindow::createTxFromChatPage() { amt = CAmount::fromDecimalString("0.00001"); totalAmt = totalAmt + amt; - + QString cid = QString::number( time(NULL) % std::rand() ); // low entropy for testing! + // QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // Needs to get a fix + QString hmemo= createHeaderMemo(cid,"ZADDR"); QString memo = ui->memoTxtChat->toPlainText().trimmed(); - //ui->chatmemoSize->setLenDisplayLabel() + // ui->memoSizeChat->setLenDisplayLabel(); - tx.toAddrs.push_back(ToFields{addr, amt, memo,}) ; + tx.toAddrs.push_back(ToFields{addr, amt, hmemo.toUtf8().toHex()}) ; + qDebug()< #include #include +#include "precompiled.h" class ChatItem { @@ -117,21 +118,4 @@ class ChatModel void addMessage(long timestamp, ChatItem item); }; -class ChatMemoEdit : public QPlainTextEdit -{ -public: - ChatMemoEdit(QWidget* parent); - - void setMaxLen(int len); - void setLenDisplayLabel(QLabel* label); - void setSendChatButton(QPushButton* button); - void includeReplyTo(QString replyToAddress); - void updateDisplay(); - -private: - int maxlen = 512; - QLabel* lenDisplayLabel = nullptr; - QPushButton* sendChatButton = nullptr; -}; - #endif \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b243a6f..a6af0d0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -983,6 +983,54 @@ void MainWindow::setupTransactionsTab() { }); } +void MainWindow::setupchatTab() { + +// Send button + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + + } + +ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { + QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); +} + +void ChatMemoEdit::updateDisplay() { + QString txt = this->toPlainText(); + if (lenDisplayLabel) + lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); + + if (txt.toUtf8().size() <= maxlen) { + // Everything is fine + if (sendChatButton) + sendChatButton->setEnabled(true); + + if (lenDisplayLabel) + lenDisplayLabel->setStyleSheet(""); + } + else { + // Overweight + if (sendChatButton) + sendChatButton->setEnabled(false); + + if (lenDisplayLabel) + lenDisplayLabel->setStyleSheet("color: red;"); + } +} + +void ChatMemoEdit::setMaxLen(int len) { + this->maxlen = len; + updateDisplay(); +} + +void ChatMemoEdit::setLenDisplayLabel(QLabel* label_40) { + this->lenDisplayLabel = label_40; +} + +void ChatMemoEdit::setSendChatButton(QPushButton* button) { + this->sendChatButton = button; +} + + void MainWindow::updateChat() { qDebug() << "Called MainWindow::updateChat()"; diff --git a/src/mainwindow.h b/src/mainwindow.h index 17194b4..6ce5fd5 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -76,6 +76,7 @@ public: Logger* logger; void doClose(); + QString createHeaderMemo(QString cid, QString zaddr, int version, int headerNumnber); public slots: void slot_change_theme(const QString& themeName); @@ -153,4 +154,21 @@ private: QMovie* loadingMovie; }; +class ChatMemoEdit : public QPlainTextEdit +{ +public: + ChatMemoEdit(QWidget* parent); + + void setMaxLen(int len); + void setLenDisplayLabel(QLabel* label_40); + void setSendChatButton(QPushButton* button); + void includeReplyTo(QString replyToAddress); + void updateDisplay(); + +private: + int maxlen = 512; + QLabel* lenDisplayLabel = nullptr; + QPushButton* sendChatButton = nullptr; +}; + #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 6d493af..f08d9be 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1388,14 +1388,6 @@ - - - 1150 - 460 - 91 - 17 - - 0 / 512 From 08fdee2557a20001712fc10bd5ddb7837ae29808 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 28 Apr 2020 20:34:44 +0200 Subject: [PATCH 014/253] set amt 0 for HushChat Memo --- src/chatmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b799abd..0cec51a 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -130,7 +130,7 @@ Tx MainWindow::createTxFromChatPage() { CAmount amt; - amt = CAmount::fromDecimalString("0.00001"); + amt = CAmount::fromDecimalString("0"); totalAmt = totalAmt + amt; QString cid = QString::number( time(NULL) % std::rand() ); // low entropy for testing! // QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // Needs to get a fix From 30edee0470e7463b8824ef601ff079e6ac1e4a3a Mon Sep 17 00:00:00 2001 From: Strider Date: Tue, 28 Apr 2020 22:05:40 +0200 Subject: [PATCH 015/253] update// added rederfcuntion to contactlist (causes segfaul on compiling) --- silentdragon-lite.pro | 6 ++++-- src/addressbook.cpp | 29 +++++++++++++++++++++++++---- src/addressbook.h | 1 + src/chatmodel.cpp | 2 +- src/contactmodel.cpp | 3 ++- src/controller.cpp | 11 +++++++++-- src/controller.h | 1 + src/mainwindow.cpp | 7 ++++++- src/mainwindow.h | 1 + 9 files changed, 50 insertions(+), 11 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index b692159..c76b209 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -68,7 +68,8 @@ SOURCES += \ src/camount.cpp \ src/chatbubbleme.cpp \ src/chatbubblepartner.cpp \ - src/chatmodel.cpp + src/chatmodel.cpp \ + src/contactmodel.cpp HEADERS += \ src/firsttimewizard.h \ @@ -100,7 +101,8 @@ HEADERS += \ lib/silentdragonlitelib.h \ src/chatbubbleme.h \ src/chatbubblepartner.h \ - src/chatmodel.h + src/chatmodel.h \ + src/contactmodel.h FORMS += \ src/encryption.ui \ diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 060b5ca..6ed874c 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -42,6 +42,12 @@ void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr) { //labels.push_back(QPair(label, addr)); AddressBook::getInstance()->addAddressLabel(label, addr, myAddr); + updateUi(); + +} + +void AddressBookModel::updateUi() +{ labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); @@ -175,8 +181,22 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ); return; } - - model.addNewLabel(newLabel, ab.addr->text(), ""); + Controller* rpc = parent->getRPC(); + bool sapling = true; + rpc->createNewZaddr(sapling, [=] (json reply) { + QString myAddr = QString::fromStdString(reply.get()[0]); + QString message = QString("New Chat Address for your partner: ") + myAddr; + QMessageBox::critical( + parent, + QObject::tr("Success"), + message, //todo traslate this shit + QMessageBox::Ok + ); + qDebug() << "new generated myAddr" << myAddr; + AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr); + }); + model.updateUi(); //todo fix updating gui after adding + }); // Import Button @@ -284,6 +304,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) // Refresh after the dialog is closed to update the labels everywhere. parent->getRPC()->refresh(true); + model.updateUi(); //todo fix updating gui after adding } //============= @@ -317,14 +338,14 @@ void AddressBook::readFromStorage() // Convert old addressbook format v1 to v2 QList> stuff; in >> stuff; - qDebug() << "Stuff: " << stuff; + //qDebug() << "Stuff: " << stuff; for (int i=0; i < stuff.size(); i++) { //qDebug() << "0:" << stuff[i][0]; //qDebug() << "1:" << stuff[i][1]; //qDebug() << "2:" << stuff[i][2]; ContactItem contact = ContactItem(stuff[i][2], stuff[i][1], stuff[i][0]); - qDebug() << "contact=" << contact.toQTString(); + //qDebug() << "contact=" << contact.toQTString(); allLabels.push_back(contact); } diff --git a/src/addressbook.h b/src/addressbook.h index 13ba606..fc3d4b9 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -13,6 +13,7 @@ public: ~AddressBookModel(); void addNewLabel(QString label, QString address, QString myAddr); + void updateUi(); void removeItemAt(int row); //QPair itemAt(int row); ContactItem itemAt(int row); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 1561d4e..5bb9718 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -84,7 +84,7 @@ void ChatModel::renderChatBox(QListWidget *view) QDateTime myDateTime; myDateTime.setTime_t(c.second.getTimestamp()); - qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); + //qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 60df97b..ad6a8fb 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -1,8 +1,9 @@ #include "contactmodel.h" +#include "addressbook.h" void ContactModel::renderContactList(QListWidget* view) { - for(auto &c : this->_contacts) + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { view->addItem(c.getName()); } diff --git a/src/controller.cpp b/src/controller.cpp index 24560e3..dd46217 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -984,16 +984,23 @@ void Controller::refreshTransactions() // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); chatModel->renderChatBox(ui->listChatMemo); - //chatModel->showMessages(); + refreshContacts( + ui->listContactWidget + ); }); } void Controller::refreshChat(QListWidget *listWidget) { - qDebug() << "Called Controller::refreshChat(QListWidget *listWidget)"; chatModel->renderChatBox(listWidget); } +void Controller::refreshContacts(QListWidget *listWidget) +{ + qDebug() << "Called Controller::refreshContacts(QListWidget *listWidget)"; + contactModel->renderContactList(listWidget); +} + // If the wallet is encrpyted and locked, we need to unlock it void Controller::unlockIfEncrypted(std::function cb, std::function error) { diff --git a/src/controller.h b/src/controller.h index 7684863..4a0835f 100644 --- a/src/controller.h +++ b/src/controller.h @@ -73,6 +73,7 @@ public: void refreshAUDCAP(); void refreshChat(QListWidget *listWidget); + void refreshContacts(QListWidget *listWidget); void executeStandardUITransaction(Tx tx); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b243a6f..92e233f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -985,10 +985,15 @@ void MainWindow::setupTransactionsTab() { void MainWindow::updateChat() { - qDebug() << "Called MainWindow::updateChat()"; rpc->refreshChat(ui->listChatMemo); } +void MainWindow::updateContacts() +{ + qDebug() << "Called MainWindow::updateContacts()"; + rpc->refreshContacts(ui->listContactWidget); +} + void MainWindow::addNewZaddr(bool sapling) { rpc->createNewZaddr(sapling, [=] (json reply) { QString addr = QString::fromStdString(reply.get()[0]); diff --git a/src/mainwindow.h b/src/mainwindow.h index 17194b4..eb30a9a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -91,6 +91,7 @@ private: void setuphushdTab(); void setupchatTab(); void updateChat(); + void updateContacts(); void setupSettingsModal(); void setupStatusBar(); From 96ea7278d8c780f6ec1b6a61a1120123269aecf9 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 28 Apr 2020 22:16:29 +0200 Subject: [PATCH 016/253] refresh contactlist on HushChat tab --- src/contactmodel.cpp | 5 +++++ src/mainwindow.ui | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index ad6a8fb..3423be1 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -3,8 +3,13 @@ void ContactModel::renderContactList(QListWidget* view) { + while(view->count() > 0) + { + view->takeItem(0); + } for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { view->addItem(c.getName()); + } } \ No newline at end of file diff --git a/src/mainwindow.ui b/src/mainwindow.ui index f08d9be..02c074c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1388,6 +1388,14 @@ + + + 1180 + 460 + 47 + 17 + + 0 / 512 From a5020cbe24c5578f2fd8b30ad24db6f815ffa94c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 28 Apr 2020 23:01:11 +0200 Subject: [PATCH 017/253] render HushChat Address in Addressbook --- src/addressbook.cpp | 22 +++++++------ src/addressbook.h | 2 +- src/addressbook.ui | 76 +++++++++++++++++++++------------------------ src/mainwindow.cpp | 2 +- src/mainwindow.ui | 15 +++++++++ 5 files changed, 66 insertions(+), 51 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 6ed874c..178cbdf 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -8,7 +8,7 @@ AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) { - headers << tr("Label") << tr("Address"); + headers << tr("Label") << tr("Address") << tr("HushChatAddress"); this->parent = parent; loadData(); } @@ -59,7 +59,7 @@ void AddressBookModel::removeItemAt(int row) if (row >= labels.size()) return; - AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress()); + AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress()); labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); @@ -99,6 +99,7 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const { case 0: return labels.at(index.row()).getName(); case 1: return labels.at(index.row()).getPartnerAddress(); + case 2: return labels.at(index.row()).getMyAddress(); } } @@ -192,6 +193,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) message, //todo traslate this shit QMessageBox::Ok ); + // ab.addr_chat->setText(myAddr); qDebug() << "new generated myAddr" << myAddr; AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr); }); @@ -245,8 +247,8 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ); }); - auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr) { - target->setText(label % "/" % addr); + auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr, QString myAddr) { + target->setText(label % "/" % addr % myAddr); }; // Double-Click picks the item @@ -260,8 +262,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString lbl = model.itemAt(index.row()).getName(); QString addr = model.itemAt(index.row()).getPartnerAddress(); + QString myAddr = model.itemAt(index.row()).getMyAddress(); d.accept(); - fnSetTargetLabelAddr(target, lbl, addr); + fnSetTargetLabelAddr(target, lbl, addr, myAddr); }); // Right-Click @@ -273,13 +276,14 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString lbl = model.itemAt(index.row()).getName(); QString addr = model.itemAt(index.row()).getPartnerAddress(); + QString myAddr = model.itemAt(index.row()).getMyAddress(); QMenu menu(parent); if (target != nullptr) menu.addAction("Pick", [&] () { d.accept(); - fnSetTargetLabelAddr(target, lbl, addr); + fnSetTargetLabelAddr(target, lbl, addr, myAddr); }); menu.addAction(QObject::tr("Copy address"), [&] () { @@ -298,7 +302,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto selection = ab.addresses->selectionModel(); if (selection && selection->hasSelection() && selection->selectedRows().size() > 0) { auto item = model.itemAt(selection->selectedRows().at(0).row()); - fnSetTargetLabelAddr(target, item.getName(), item.getPartnerAddress()); + fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress()); } }; @@ -408,7 +412,7 @@ void AddressBook::addAddressLabel(QString label, QString address, QString myAddr // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) if (allLabels[i].getName() == label) - removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress()); + removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress()); ContactItem item = ContactItem(myAddr, address, label); allLabels.push_back(item); @@ -416,7 +420,7 @@ void AddressBook::addAddressLabel(QString label, QString address, QString myAddr } // Remove a new address/label from the database -void AddressBook::removeAddressLabel(QString label, QString address) +void AddressBook::removeAddressLabel(QString label, QString address, QString myAddr) { // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) diff --git a/src/addressbook.h b/src/addressbook.h index fc3d4b9..ec3b6fe 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -46,7 +46,7 @@ public: void addAddressLabel(QString label, QString address, QString myAddr); // Remove a new address/label from the database - void removeAddressLabel(QString label, QString address); + void removeAddressLabel(QString label, QString address, QString myAddr); // Update a label/address void updateLabel(QString oldlabel, QString address, QString newlabel); diff --git a/src/addressbook.ui b/src/addressbook.ui index a20ee8f..20104b9 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -13,65 +13,61 @@ Address Book - - + + Add New Address - - + + + + + HushChat Address - give this Address only to your contact + + + + + + + Address (z-Addr or t-Addr) - - - - - - - Label - - - - + 40 - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add to Address Book - - - - + + + + + + + Label + + + + + + + + + + Add to Address Book + + - + QAbstractItemView::SingleSelection @@ -87,7 +83,7 @@ - + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7ab2da2..d1c331e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1286,7 +1286,7 @@ void MainWindow::setupReceiveTab() { if (!curLabel.isEmpty() && label.isEmpty()) { info = "Removed Label '" % curLabel % "'"; - AddressBook::getInstance()->removeAddressLabel(curLabel, addr); + AddressBook::getInstance()->removeAddressLabel(curLabel, addr, ""); } else if (!curLabel.isEmpty() && !label.isEmpty()) { info = "Updated Label '" % curLabel % "' to '" % label % "'"; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 02c074c..8dd559f 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1417,6 +1417,9 @@ + + true + 340 @@ -1425,6 +1428,18 @@ 371 + + QAbstractItemView::NoEditTriggers + + + false + + + Qt::IgnoreAction + + + QAbstractItemView::NoSelection + From e9ae0e78c5f21402b8f87ba4df6a0dde5cdfa731 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 00:51:07 +0200 Subject: [PATCH 018/253] send Memo to selected Contact --- lib/Cargo.lock | 6 ++--- lib/Cargo.toml | 2 +- src/chatmodel.cpp | 17 ++++++++++---- src/contactmodel.cpp | 4 +++- src/mainwindow.cpp | 15 ++++++++++++ src/mainwindow.ui | 55 +++++++++++++++++++++++++++++++++++++------- 6 files changed, 82 insertions(+), 17 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 089d4ac..96d8bdf 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=7efa024660cbe08e7eadf2524134e153c89c51ad)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d3a66550ed8c6216b13002ce6e5b425367f30770)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/MyHush/silentdragonlite-cli?rev=7efa024660cbe08e7eadf2524134e153c89c51ad#7efa024660cbe08e7eadf2524134e153c89c51ad" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d3a66550ed8c6216b13002ce6e5b425367f30770#d3a66550ed8c6216b13002ce6e5b425367f30770" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2630,7 +2630,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=7efa024660cbe08e7eadf2524134e153c89c51ad)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d3a66550ed8c6216b13002ce6e5b425367f30770)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 65c97ad..bd615ca 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/MyHush/silentdragonlite-cli", rev = "7efa024660cbe08e7eadf2524134e153c89c51ad" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d3a66550ed8c6216b13002ce6e5b425367f30770" } diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 43e929e..64a781b 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -74,6 +74,7 @@ void ChatModel::renderChatBox(QListWidget &view) void ChatModel::renderChatBox(QListWidget *view) { + qDebug() << "called ChatModel::renderChatBox(QListWidget *view)"; QString line = ""; while(view->count() > 0) @@ -97,6 +98,7 @@ void ChatModel::renderChatBox(QListWidget *view) QString MainWindow::createHeaderMemo(QString cid, QString zaddr, int version=0, int headerNumber=1) { + QString header=""; QJsonDocument j; QJsonObject h; @@ -120,7 +122,14 @@ Tx MainWindow::createTxFromChatPage() { CAmount totalAmt; // For each addr/amt in the Chat tab { - QString addr = ""; // We need to set the reply Address for our Contact here + + + + // ui->ContactZaddr->setText("Zaddr"); + + + + QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here // Remove label if it exists addr = AddressBook::addressFromAddressLabel(addr); @@ -134,15 +143,15 @@ Tx MainWindow::createTxFromChatPage() { totalAmt = totalAmt + amt; QString cid = QString::number( time(NULL) % std::rand() ); // low entropy for testing! // QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // Needs to get a fix - QString hmemo= createHeaderMemo(cid,"ZADDR"); + QString hmemo= createHeaderMemo(cid,"Some ZADDR"); QString memo = ui->memoTxtChat->toPlainText().trimmed(); // ui->memoSizeChat->setLenDisplayLabel(); - tx.toAddrs.push_back(ToFields{addr, amt, hmemo.toUtf8().toHex()}) ; + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; qDebug()<getAllAddressLabels()) { - view->addItem(c.getName()); + view->addItem(c.getPartnerAddress()); + } } \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d1c331e..cf063b1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -988,7 +988,22 @@ void MainWindow::setupchatTab() { // Send button QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + +///////// Set selected Zaddr for Chat with Doubleklick + + QObject::connect(ui->listContactWidget, &QTableView::doubleClicked, [=] () { + for (auto p : AddressBook::getInstance()->getAllAddressLabels()) { + QModelIndex index = ui->listContactWidget->currentIndex(); + QString itemText = index.data(Qt::DisplayRole).toString(); + ui->ContactZaddr->setText(itemText); + + } + + /// ui->listContactWidget->setCurrentRow(1) + + }); +} ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 8dd559f..a2e83da 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1354,9 +1354,9 @@ - 357 - 460 - 329 + 340 + 490 + 61 17 @@ -1367,8 +1367,8 @@ - 347 - 483 + 340 + 510 901 128 @@ -1377,8 +1377,8 @@ - 360 - 620 + 350 + 650 158 25 @@ -1445,7 +1445,7 @@ 1130 - 620 + 650 114 25 @@ -1463,6 +1463,45 @@ false + + + + 410 + 490 + 67 + 17 + + + + To: + + + + + + 520 + 490 + 67 + 17 + + + + + + + + + + 740 + 490 + 171 + 17 + + + + + + From 205bb29f4a52c9ce662838bceceb94aaef61fd70 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 01:24:38 +0200 Subject: [PATCH 019/253] show only memos from selcted contact - work in progress --- src/chatmodel.cpp | 13 +++++++++++++ src/chatmodel.h | 1 + src/mainwindow.cpp | 7 +------ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 64a781b..c037fa5 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -62,6 +62,8 @@ void ChatModel::showMessages() } } + + void ChatModel::renderChatBox(QListWidget &view) { /*for(auto &c : this->chatItems) @@ -82,8 +84,15 @@ void ChatModel::renderChatBox(QListWidget *view) view->takeItem(0); } + //QModelIndex index = parent->listContactWidget->currentIndex(); + // QString itemText = index.data(Qt::DisplayRole).toString(); + + for(auto &c : this->chatItems) + { + + // if ("" == QString(c.second.getAddress())){ ////// ToDo: render only memos from selected contact QDateTime myDateTime; myDateTime.setTime_t(c.second.getTimestamp()); @@ -93,6 +102,10 @@ void ChatModel::renderChatBox(QListWidget *view) line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; + // } + // else{ + + // } } } diff --git a/src/chatmodel.h b/src/chatmodel.h index 8472028..524ce61 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -102,6 +102,7 @@ class ChatModel { private: std::map chatItems; + QTableView* parent; public: ChatModel() {}; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cf063b1..21f922a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -992,15 +992,10 @@ void MainWindow::setupchatTab() { ///////// Set selected Zaddr for Chat with Doubleklick QObject::connect(ui->listContactWidget, &QTableView::doubleClicked, [=] () { - for (auto p : AddressBook::getInstance()->getAllAddressLabels()) { + QModelIndex index = ui->listContactWidget->currentIndex(); QString itemText = index.data(Qt::DisplayRole).toString(); ui->ContactZaddr->setText(itemText); - - - } - - /// ui->listContactWidget->setCurrentRow(1) }); } From 17cc83ab7b3ec0c48e116532f46f86ef81a1bdfd Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 14:40:13 +0200 Subject: [PATCH 020/253] use quuid as cid in headermemo --- src/chatmodel.cpp | 11 ++++++----- src/mainwindow.cpp | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c037fa5..552116c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -140,9 +140,9 @@ Tx MainWindow::createTxFromChatPage() { // ui->ContactZaddr->setText("Zaddr"); - + - QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here + QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here // Remove label if it exists addr = AddressBook::addressFromAddressLabel(addr); @@ -154,12 +154,13 @@ Tx MainWindow::createTxFromChatPage() { amt = CAmount::fromDecimalString("0"); totalAmt = totalAmt + amt; - QString cid = QString::number( time(NULL) % std::rand() ); // low entropy for testing! - // QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // Needs to get a fix + + // QString cid = QString::number( time(NULL) % std::rand() ); // low entropy for testing! + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // Needs to get a fix QString hmemo= createHeaderMemo(cid,"Some ZADDR"); QString memo = ui->memoTxtChat->toPlainText().trimmed(); - // ui->memoSizeChat->setLenDisplayLabel(); + // ui->memoSizeChat->setLenDisplayLabel(); tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 21f922a..b703b53 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -991,11 +991,11 @@ void MainWindow::setupchatTab() { ///////// Set selected Zaddr for Chat with Doubleklick - QObject::connect(ui->listContactWidget, &QTableView::doubleClicked, [=] () { + QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { QModelIndex index = ui->listContactWidget->currentIndex(); - QString itemText = index.data(Qt::DisplayRole).toString(); - ui->ContactZaddr->setText(itemText); + QString zaddr = index.data(Qt::DisplayRole).toString(); + ui->ContactZaddr->setText(zaddr); }); } From dd48ab87ebeed2af26a9756f3ca17e970f91a69b Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 16:58:33 +0200 Subject: [PATCH 021/253] create and add cid to Addressbook --- src/addressbook.cpp | 45 +++++++++++++++++++++++++++----------------- src/addressbook.h | 6 +++--- src/contactmodel.cpp | 2 +- src/contactmodel.h | 16 ++++++++++++++-- src/mainwindow.cpp | 4 ++-- src/mainwindow.ui | 28 +++++++++++++++++++++++---- 6 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 178cbdf..5c6a229 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -8,7 +8,7 @@ AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) { - headers << tr("Label") << tr("Address") << tr("HushChatAddress"); + headers << tr("Label") << tr("Address") << tr("HushChatAddress") << tr("cid"); this->parent = parent; loadData(); } @@ -38,10 +38,10 @@ void AddressBookModel::loadData() ); } -void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr) +void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid) { //labels.push_back(QPair(label, addr)); - AddressBook::getInstance()->addAddressLabel(label, addr, myAddr); + AddressBook::getInstance()->addAddressLabel(label, addr, myAddr, cid); updateUi(); } @@ -59,7 +59,7 @@ void AddressBookModel::removeItemAt(int row) if (row >= labels.size()) return; - AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress()); + AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress(),labels[row].getcid()); labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); @@ -70,7 +70,7 @@ ContactItem AddressBookModel::itemAt(int row) { if (row >= labels.size()) { - ContactItem item = ContactItem("", "", ""); + ContactItem item = ContactItem("", "", "", ""); return item; } @@ -100,6 +100,7 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const case 0: return labels.at(index.row()).getName(); case 1: return labels.at(index.row()).getPartnerAddress(); case 2: return labels.at(index.row()).getMyAddress(); + case 3: return labels.at(index.row()).getcid(); } } @@ -190,17 +191,24 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QMessageBox::critical( parent, QObject::tr("Success"), - message, //todo traslate this shit + message, //todo translate this QMessageBox::Ok ); // ab.addr_chat->setText(myAddr); qDebug() << "new generated myAddr" << myAddr; - AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr); + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // + AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr, cid); }); model.updateUi(); //todo fix updating gui after adding }); + /// Generate CID for Contact + + + + // AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), cid); + // Import Button QObject::connect(ab.btnImport, &QPushButton::clicked, [&] () { // Get the import file name. @@ -236,7 +244,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) continue; // Add label, address. - model.addNewLabel(items.at(1), items.at(0), ""); + model.addNewLabel(items.at(1), items.at(0), "", ""); numImported++; } @@ -247,7 +255,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ); }); - auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr, QString myAddr) { + auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr, QString myAddr, QString cid) { target->setText(label % "/" % addr % myAddr); }; @@ -263,8 +271,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString lbl = model.itemAt(index.row()).getName(); QString addr = model.itemAt(index.row()).getPartnerAddress(); QString myAddr = model.itemAt(index.row()).getMyAddress(); + QString cid = model.itemAt(index.row()).getcid(); d.accept(); - fnSetTargetLabelAddr(target, lbl, addr, myAddr); + fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid); }); // Right-Click @@ -277,13 +286,14 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString lbl = model.itemAt(index.row()).getName(); QString addr = model.itemAt(index.row()).getPartnerAddress(); QString myAddr = model.itemAt(index.row()).getMyAddress(); + QString cid = model.itemAt(index.row()).getcid(); QMenu menu(parent); if (target != nullptr) menu.addAction("Pick", [&] () { d.accept(); - fnSetTargetLabelAddr(target, lbl, addr, myAddr); + fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid); }); menu.addAction(QObject::tr("Copy address"), [&] () { @@ -302,7 +312,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto selection = ab.addresses->selectionModel(); if (selection && selection->hasSelection() && selection->selectedRows().size() > 0) { auto item = model.itemAt(selection->selectedRows().at(0).row()); - fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress()); + fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress(), item.getcid()); } }; @@ -348,7 +358,7 @@ void AddressBook::readFromStorage() //qDebug() << "0:" << stuff[i][0]; //qDebug() << "1:" << stuff[i][1]; //qDebug() << "2:" << stuff[i][2]; - ContactItem contact = ContactItem(stuff[i][2], stuff[i][1], stuff[i][0]); + ContactItem contact = ContactItem(stuff[i][3],stuff[i][2], stuff[i][1], stuff[i][0]); //qDebug() << "contact=" << contact.toQTString(); allLabels.push_back(contact); } @@ -383,6 +393,7 @@ void AddressBook::writeToStorage() c.push_back(item.getName()); c.push_back(item.getPartnerAddress()); c.push_back(item.getMyAddress()); + c.push_back(item.getcid()); contacts.push_back(c); } out << QString("v1") << contacts; @@ -405,22 +416,22 @@ QString AddressBook::writeableFile() // Add a new address/label to the database -void AddressBook::addAddressLabel(QString label, QString address, QString myAddr) +void AddressBook::addAddressLabel(QString label, QString address, QString myAddr, QString cid) { Q_ASSERT(Settings::isValidAddress(address)); // getName(), remove any existing label // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) if (allLabels[i].getName() == label) - removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress()); + removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress(), allLabels[i].getcid()); - ContactItem item = ContactItem(myAddr, address, label); + ContactItem item = ContactItem(myAddr, address, label, cid); allLabels.push_back(item); writeToStorage(); } // Remove a new address/label from the database -void AddressBook::removeAddressLabel(QString label, QString address, QString myAddr) +void AddressBook::removeAddressLabel(QString label, QString address, QString myAddr, QString cid) { // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) diff --git a/src/addressbook.h b/src/addressbook.h index ec3b6fe..6f8308b 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -12,7 +12,7 @@ public: AddressBookModel(QTableView* parent); ~AddressBookModel(); - void addNewLabel(QString label, QString address, QString myAddr); + void addNewLabel(QString label, QString address, QString myAddr, QString cid); void updateUi(); void removeItemAt(int row); //QPair itemAt(int row); @@ -43,10 +43,10 @@ public: static QString addressFromAddressLabel(const QString& lblAddr); // Add a new address/label to the database - void addAddressLabel(QString label, QString address, QString myAddr); + void addAddressLabel(QString label, QString address, QString myAddr, QString cid); // Remove a new address/label from the database - void removeAddressLabel(QString label, QString address, QString myAddr); + void removeAddressLabel(QString label, QString address, QString myAddr, QString cid); // Update a label/address void updateLabel(QString oldlabel, QString address, QString newlabel); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index fe96fce..154124b 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -10,7 +10,7 @@ void ContactModel::renderContactList(QListWidget* view) } for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - view->addItem(c.getPartnerAddress()); + view->addItem(c.getPartnerAddress()); //hide } diff --git a/src/contactmodel.h b/src/contactmodel.h index d1ce239..fcf6b5b 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -11,14 +11,16 @@ class ContactItem QString _myAddress; QString _partnerAddress; QString _name; + QString _cid; public: ContactItem(); - ContactItem(QString myAddress, QString partnerAddress, QString name) + ContactItem(QString myAddress, QString partnerAddress, QString name, QString cid) { _myAddress = myAddress; _partnerAddress = partnerAddress; _name = name; + _cid = cid; } QString getName() const @@ -36,6 +38,11 @@ class ContactItem return _partnerAddress; } + QString getcid() const + { + return _cid; + } + void setName(QString name) { _name = name; @@ -51,9 +58,14 @@ class ContactItem _partnerAddress = partnerAddress; } + void setcid(QString cid) + { + _cid = cid; + } + QString toQTString() { - return _name + "|" + _partnerAddress + "|" + _myAddress; + return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid; } }; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b703b53..cc60938 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1296,7 +1296,7 @@ void MainWindow::setupReceiveTab() { if (!curLabel.isEmpty() && label.isEmpty()) { info = "Removed Label '" % curLabel % "'"; - AddressBook::getInstance()->removeAddressLabel(curLabel, addr, ""); + AddressBook::getInstance()->removeAddressLabel(curLabel, addr, "", ""); } else if (!curLabel.isEmpty() && !label.isEmpty()) { info = "Updated Label '" % curLabel % "' to '" % label % "'"; @@ -1304,7 +1304,7 @@ void MainWindow::setupReceiveTab() { } else if (curLabel.isEmpty() && !label.isEmpty()) { info = "Added Label '" % label % "'"; - AddressBook::getInstance()->addAddressLabel(label, addr, ""); + AddressBook::getInstance()->addAddressLabel(label, addr, "", ""); } // Update labels everywhere on the UI diff --git a/src/mainwindow.ui b/src/mainwindow.ui index a2e83da..4197b0f 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -14,7 +14,7 @@ SilentDragonLite - + :/icons/res/icon.ico:/icons/res/icon.ico @@ -1502,6 +1502,28 @@ + + + + 943 + 20 + 211 + 25 + + + + + 100 + 0 + + + + Sicheren Kontakt hinzufügen + + + false + + @@ -1714,8 +1736,6 @@ minerFeeAmt sendToScrollArea - - - + From 1aa5a05589a862fdb29b4b35632808cbd0e8a6bb Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 18:20:53 +0200 Subject: [PATCH 022/253] take sendtoaddr,myaddr and cid from contact object --- src/addressbook.cpp | 18 +++++++++--------- src/chatmodel.cpp | 18 ++++++++++++------ src/contactmodel.cpp | 2 +- src/contactmodel.h | 6 +++--- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 5c6a229..ca224b4 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -59,7 +59,7 @@ void AddressBookModel::removeItemAt(int row) if (row >= labels.size()) return; - AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress(),labels[row].getcid()); + AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress(),labels[row].getCid()); labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); @@ -100,7 +100,7 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const case 0: return labels.at(index.row()).getName(); case 1: return labels.at(index.row()).getPartnerAddress(); case 2: return labels.at(index.row()).getMyAddress(); - case 3: return labels.at(index.row()).getcid(); + case 3: return labels.at(index.row()).getCid(); } } @@ -271,7 +271,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString lbl = model.itemAt(index.row()).getName(); QString addr = model.itemAt(index.row()).getPartnerAddress(); QString myAddr = model.itemAt(index.row()).getMyAddress(); - QString cid = model.itemAt(index.row()).getcid(); + QString cid = model.itemAt(index.row()).getCid(); d.accept(); fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid); }); @@ -286,7 +286,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString lbl = model.itemAt(index.row()).getName(); QString addr = model.itemAt(index.row()).getPartnerAddress(); QString myAddr = model.itemAt(index.row()).getMyAddress(); - QString cid = model.itemAt(index.row()).getcid(); + QString cid = model.itemAt(index.row()).getCid(); QMenu menu(parent); @@ -312,7 +312,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto selection = ab.addresses->selectionModel(); if (selection && selection->hasSelection() && selection->selectedRows().size() > 0) { auto item = model.itemAt(selection->selectedRows().at(0).row()); - fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress(), item.getcid()); + fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress(), item.getCid()); } }; @@ -358,7 +358,7 @@ void AddressBook::readFromStorage() //qDebug() << "0:" << stuff[i][0]; //qDebug() << "1:" << stuff[i][1]; //qDebug() << "2:" << stuff[i][2]; - ContactItem contact = ContactItem(stuff[i][3],stuff[i][2], stuff[i][1], stuff[i][0]); + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3]); //qDebug() << "contact=" << contact.toQTString(); allLabels.push_back(contact); } @@ -393,7 +393,7 @@ void AddressBook::writeToStorage() c.push_back(item.getName()); c.push_back(item.getPartnerAddress()); c.push_back(item.getMyAddress()); - c.push_back(item.getcid()); + c.push_back(item.getCid()); contacts.push_back(c); } out << QString("v1") << contacts; @@ -423,9 +423,9 @@ void AddressBook::addAddressLabel(QString label, QString address, QString myAddr // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) if (allLabels[i].getName() == label) - removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress(), allLabels[i].getcid()); + removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress(), allLabels[i].getCid()); - ContactItem item = ContactItem(myAddr, address, label, cid); + ContactItem item = ContactItem(label, address, myAddr, cid); allLabels.push_back(item); writeToStorage(); } diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 552116c..d412bc4 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -136,9 +136,9 @@ Tx MainWindow::createTxFromChatPage() { // For each addr/amt in the Chat tab { - + - // ui->ContactZaddr->setText("Zaddr"); + @@ -155,10 +155,16 @@ Tx MainWindow::createTxFromChatPage() { amt = CAmount::fromDecimalString("0"); totalAmt = totalAmt + amt; - // QString cid = QString::number( time(NULL) % std::rand() ); // low entropy for testing! - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // Needs to get a fix - QString hmemo= createHeaderMemo(cid,"Some ZADDR"); + + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + if (ui->ContactZaddr->text().trimmed() == c.getName()) { + + QString cid = c.getCid(); + QString myAddr = c.getMyAddress(); + QString addr = c.getPartnerAddress(); + + QString hmemo= createHeaderMemo(cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); // ui->memoSizeChat->setLenDisplayLabel(); @@ -168,7 +174,7 @@ Tx MainWindow::createTxFromChatPage() { tx.toAddrs.push_back( ToFields{addr, amt, memo}); qDebug() << "pushback chattx"; - } + } } tx.fee = Settings::getMinerFee(); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 154124b..0e9a6ea 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -10,7 +10,7 @@ void ContactModel::renderContactList(QListWidget* view) } for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - view->addItem(c.getPartnerAddress()); //hide + view->addItem(c.getName()); } diff --git a/src/contactmodel.h b/src/contactmodel.h index fcf6b5b..886b285 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -15,11 +15,11 @@ class ContactItem public: ContactItem(); - ContactItem(QString myAddress, QString partnerAddress, QString name, QString cid) + ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid) { + _name = name; _myAddress = myAddress; _partnerAddress = partnerAddress; - _name = name; _cid = cid; } @@ -38,7 +38,7 @@ class ContactItem return _partnerAddress; } - QString getcid() const + QString getCid() const { return _cid; } From e3e537b1a40be65929790c93be25490d4a9f5899 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 22:07:19 +0200 Subject: [PATCH 023/253] do not render Headermemos --- src/controller.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/controller.cpp b/src/controller.cpp index dd46217..a28b74c 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -880,6 +880,10 @@ void Controller::refreshTransactions() if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); + if (memo.startsWith("{")) + { + + }else{ ChatItem item = ChatItem( datetime, address, @@ -890,6 +894,7 @@ void Controller::refreshTransactions() chatModel->addMessage(item); } + } items.push_back(TransactionItemDetail{address, amount, memo}); @@ -929,6 +934,11 @@ void Controller::refreshTransactions() if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); + if (memo.startsWith("{")) + { + + }else{ + ChatItem item = ChatItem( datetime, address, @@ -936,7 +946,7 @@ void Controller::refreshTransactions() memo ); chatModel->addMessage(item); - } + }} items.push_back( From e263719206f98fd602aad68715f5baaf8da1126a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 22:16:33 +0200 Subject: [PATCH 024/253] fix gui element --- src/mainwindow.ui | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 4197b0f..59d3e78 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -14,7 +14,7 @@ SilentDragonLite - + :/icons/res/icon.ico:/icons/res/icon.ico @@ -1356,7 +1356,7 @@ 340 490 - 61 + 331 17 @@ -1466,7 +1466,7 @@ - 410 + 690 490 67 17 @@ -1736,6 +1736,8 @@ minerFeeAmt sendToScrollArea
- + + + From 45f3a80885bce88338bf47a2de5cb29d839d33ec Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 22:53:04 +0200 Subject: [PATCH 025/253] add contact request flag to headermemo - work in progress --- src/chatmodel.cpp | 180 +++++++++++++++++++++++++++++++++++++++++---- src/mainwindow.cpp | 2 +- src/mainwindow.h | 5 +- src/mainwindow.ui | 2 +- 4 files changed, 173 insertions(+), 16 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index d412bc4..53f94a2 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -83,11 +83,7 @@ void ChatModel::renderChatBox(QListWidget *view) { view->takeItem(0); } - - //QModelIndex index = parent->listContactWidget->currentIndex(); - // QString itemText = index.data(Qt::DisplayRole).toString(); - - + for(auto &c : this->chatItems) { @@ -109,7 +105,7 @@ void ChatModel::renderChatBox(QListWidget *view) } } -QString MainWindow::createHeaderMemo(QString cid, QString zaddr, int version=0, int headerNumber=1) +QString MainWindow::createHeaderMemo(QString safeContact, QString cid, QString zaddr, int version=0, int headerNumber=1) { QString header=""; @@ -121,6 +117,7 @@ QString MainWindow::createHeaderMemo(QString cid, QString zaddr, int version=0, h["v"] = version; // HushChat version h["z"] = zaddr; // zaddr to respond to h["cid"] = cid; // conversation id + h["c"] = safeContact; // Is this a safe Contact request? j.setObject(h); header = j.toJson(); @@ -135,13 +132,7 @@ Tx MainWindow::createTxFromChatPage() { CAmount totalAmt; // For each addr/amt in the Chat tab { - - - - - - QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here // Remove label if it exists addr = AddressBook::addressFromAddressLabel(addr); @@ -162,9 +153,11 @@ Tx MainWindow::createTxFromChatPage() { QString cid = c.getCid(); QString myAddr = c.getMyAddress(); + QString safeContact = "false"; QString addr = c.getPartnerAddress(); + - QString hmemo= createHeaderMemo(cid,myAddr); + QString hmemo= createHeaderMemo(safeContact,cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); // ui->memoSizeChat->setLenDisplayLabel(); @@ -291,5 +284,166 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { .arg(available.toDecimalhushString(), total.toDecimalhushString()); } + return ""; +} + +// Create a Safe Contact Request. +Tx MainWindow::createTxForSafeContactRequest() { + Tx tx; + CAmount totalAmt; + // For each addr/amt in the Chat tab + { + + QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here + // Remove label if it exists + addr = AddressBook::addressFromAddressLabel(addr); + + QString amtStr = "0"; + + // bool ok; + CAmount amt; + + + amt = CAmount::fromDecimalString("0"); + totalAmt = totalAmt + amt; + + + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + + if (ui->ContactZaddr->text().trimmed() == c.getName()) { + + // QString cid = c.getCid(); // This has to be a new cid for the contact + // QString myAddr = c.getMyAddress(); // this should be a new HushChat zaddr + // QString addr = c.getPartnerAddress(); // this address will be insert by the user + QString safeContact = "true"; + + + QString hmemo= createHeaderMemo(safeContact,cid,myAddr); + QString memo = ui->memoTxtChat->toPlainText().trimmed(); + // ui->memoSizeChat->setLenDisplayLabel(); + + + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; + qDebug()<text()))) { + // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), + // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), + // QMessageBox::Ok, this); + + // msg.exec(); + //return; + //} + + Tx tx = createTxForSafeContactRequest(); + + QString error = doSendChatTxValidations(tx); + + if (!error.isEmpty()) { + // Something went wrong, so show an error and exit + QMessageBox msg(QMessageBox::Critical, tr("Message Error"), error, + QMessageBox::Ok, this); + + msg.exec(); + + // abort the Tx + return; + qDebug() << "Tx aborted"; + } + + // Create a new Dialog to show that we are computing/sending the Tx + auto d = new QDialog(this); + auto connD = new Ui_ConnectionDialog(); + connD->setupUi(d); + QPixmap logo(":/img/res/logobig.gif"); + connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + + connD->status->setText(tr("Please wait...")); + connD->statusDetail->setText(tr("Your Safe Contact Request will be send")); + + d->show(); + + // And send the Tx + rpc->executeTransaction(tx, + [=] (QString txid) { + ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid); + + connD->status->setText(tr("Done!")); + connD->statusDetail->setText(txid); + + QTimer::singleShot(1000, [=]() { + d->accept(); + d->close(); + delete connD; + delete d; + + }); + + // Force a UI update so we get the unconfirmed Tx + rpc->refresh(true); + + }, + // Errored out + [=] (QString opid, QString errStr) { + ui->statusBar->showMessage(QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000); + + d->accept(); + d->close(); + delete connD; + delete d; + + if (!opid.isEmpty()) + errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; + + QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); + } + ); + } + + +QString MainWindow::doSendRequestTxValidations(Tx tx) { + // Check to see if we have enough verified funds to send the Tx. + + CAmount total; + for (auto toAddr : tx.toAddrs) { + if (!Settings::isValidAddress(toAddr.addr)) { + QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr); + return QString(tr("Recipient Address ")) % addr % tr(" is Invalid"); + } + + // This technically shouldn't be possible, but issue #62 seems to have discovered a bug + // somewhere, so just add a check to make sure. + if (toAddr.amount.toqint64() < 0) { + return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr)); + } + + total = total + toAddr.amount; + } + total = total + tx.fee; + + auto available = rpc->getModel()->getAvailableBalance(); + + if (available < total) { + return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") + .arg(available.toDecimalhushString(), total.toDecimalhushString()); + } + return ""; } \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cc60938..88a4d5f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -987,7 +987,7 @@ void MainWindow::setupchatTab() { // Send button QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); - + QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::safeContactRequest); ///////// Set selected Zaddr for Chat with Doubleklick diff --git a/src/mainwindow.h b/src/mainwindow.h index ad83f73..f9f781b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -48,6 +48,7 @@ public: QString doSendTxValidations(Tx tx); QString doSendChatTxValidations(Tx tx); + QString doSendRequestTxValidations(Tx tx); void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); @@ -76,7 +77,7 @@ public: Logger* logger; void doClose(); - QString createHeaderMemo(QString cid, QString zaddr, int version, int headerNumnber); + QString createHeaderMemo(QString safeContact, QString cid, QString zaddr, int version, int headerNumber); public slots: void slot_change_theme(const QString& themeName); @@ -103,6 +104,7 @@ private: bool confirmTx(Tx tx, RecurringPaymentInfo* rpi); Tx createTxFromChatPage(); + Tx createTxForSafeContactRequest(); void encryptWallet(); void removeWalletEncryption(); @@ -110,6 +112,7 @@ private: void cancelButton(); void sendButton(); void sendChatButton(); + void safeContactRequest(); void addAddressSection(); void maxAmountChecked(int checked); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 59d3e78..4c8fa7b 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1502,7 +1502,7 @@ - + 943 From bf7cb9416816fcae841512b29061447f9056b4c4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 29 Apr 2020 22:54:27 +0200 Subject: [PATCH 026/253] add contact request flag to headermemo - work in progress --- src/chatmodel.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 53f94a2..153fe97 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -315,6 +315,9 @@ Tx MainWindow::createTxForSafeContactRequest() { // QString cid = c.getCid(); // This has to be a new cid for the contact // QString myAddr = c.getMyAddress(); // this should be a new HushChat zaddr // QString addr = c.getPartnerAddress(); // this address will be insert by the user + QString cid = ""; + QString myAddr = ""; + QString addr = ""; QString safeContact = "true"; From d0b88255f24995c0fb98a508780436a387124b81 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 30 Apr 2020 00:08:50 +0200 Subject: [PATCH 027/253] do not render any header memo on the chatgui - render a incoming contact request - work in progress --- src/chatmodel.cpp | 21 ++++++++++++++++----- src/controller.cpp | 14 +++----------- src/mainwindow.ui | 13 ------------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 153fe97..9adcd56 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -88,8 +88,21 @@ void ChatModel::renderChatBox(QListWidget *view) { - // if ("" == QString(c.second.getAddress())){ ////// ToDo: render only memos from selected contact - QDateTime myDateTime; + if (c.second.getMemo().startsWith("{\n \"c\": \"true\"")){ + + // Render a incoming contact Request + + } + + if (c.second.getMemo().startsWith("{\n \"c\": \"false\"") ){ + + // we dont want to render this + + } + + if (c.second.getMemo().startsWith("{") == false){ //TOdo and is selected in Contact Widget - + + QDateTime myDateTime; myDateTime.setTime_t(c.second.getTimestamp()); //qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); @@ -98,10 +111,8 @@ void ChatModel::renderChatBox(QListWidget *view) line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; - // } - // else{ + } - // } } } diff --git a/src/controller.cpp b/src/controller.cpp index a28b74c..4a65ba9 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -880,10 +880,7 @@ void Controller::refreshTransactions() if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - if (memo.startsWith("{")) - { - }else{ ChatItem item = ChatItem( datetime, address, @@ -892,8 +889,7 @@ void Controller::refreshTransactions() true // is an outgoing message ); chatModel->addMessage(item); - - } + } @@ -934,11 +930,7 @@ void Controller::refreshTransactions() if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); - if (memo.startsWith("{")) - { - - }else{ - + ChatItem item = ChatItem( datetime, address, @@ -946,7 +938,7 @@ void Controller::refreshTransactions() memo ); chatModel->addMessage(item); - }} + } items.push_back( diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 4c8fa7b..7bb612e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1374,19 +1374,6 @@ - - - - 350 - 650 - 158 - 25 - - - - Include Reply Address - - From 8f3bc21844a2c78fc646248959bf07a90401e706 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 30 Apr 2020 20:17:08 +0200 Subject: [PATCH 028/253] render only memos from selected nickname --- src/chatmodel.cpp | 57 +++++++++++++++++++--------------------------- src/chatmodel.h | 11 +++++++-- src/controller.cpp | 4 ++-- src/mainwindow.cpp | 12 ++++++---- src/mainwindow.h | 2 +- src/mainwindow.ui | 8 +++---- 6 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 9adcd56..2b2b6a0 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -64,7 +64,7 @@ void ChatModel::showMessages() -void ChatModel::renderChatBox(QListWidget &view) +void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget &view) { /*for(auto &c : this->chatItems) { @@ -74,49 +74,36 @@ void ChatModel::renderChatBox(QListWidget &view) //todo render items to view } -void ChatModel::renderChatBox(QListWidget *view) +void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) { - - qDebug() << "called ChatModel::renderChatBox(QListWidget *view)"; - QString line = ""; + while(view->count() > 0) { view->takeItem(0); } - - for(auto &c : this->chatItems) + + QString line = ""; + + for(auto &c : this->chatItems){ - { - - if (c.second.getMemo().startsWith("{\n \"c\": \"true\"")){ - - // Render a incoming contact Request - - } - - if (c.second.getMemo().startsWith("{\n \"c\": \"false\"") ){ - - // we dont want to render this - - } - - if (c.second.getMemo().startsWith("{") == false){ //TOdo and is selected in Contact Widget - - QDateTime myDateTime; myDateTime.setTime_t(c.second.getTimestamp()); - //qDebug() << "[" << myDateTime.toString("dd.MM.yyyy hh:mm:ss ") << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); + + ////// + if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false)) { line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); - line += QString(c.second.getMemo()) + QString("\n"); + line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; - } + }else {} } + } -QString MainWindow::createHeaderMemo(QString safeContact, QString cid, QString zaddr, int version=0, int headerNumber=1) +QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) { QString header=""; @@ -128,15 +115,15 @@ QString MainWindow::createHeaderMemo(QString safeContact, QString cid, QString z h["v"] = version; // HushChat version h["z"] = zaddr; // zaddr to respond to h["cid"] = cid; // conversation id - h["c"] = safeContact; // Is this a safe Contact request? + h["t"] = type; // Memo or incoming contact request j.setObject(h); header = j.toJson(); qDebug() << "made header=" << header; - return header; } + // Create a Tx from the current state of the Chat page. Tx MainWindow::createTxFromChatPage() { Tx tx; @@ -144,9 +131,9 @@ Tx MainWindow::createTxFromChatPage() { // For each addr/amt in the Chat tab { - QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here + // QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here // Remove label if it exists - addr = AddressBook::addressFromAddressLabel(addr); + // addr = AddressBook::addressFromAddressLabel(addr); QString amtStr = "0"; @@ -160,15 +147,15 @@ Tx MainWindow::createTxFromChatPage() { for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (ui->ContactZaddr->text().trimmed() == c.getName()) { + if (ui->ContactZaddr->text().trimmed() == c.getPartnerAddress()) { QString cid = c.getCid(); QString myAddr = c.getMyAddress(); - QString safeContact = "false"; + QString type = "memo"; QString addr = c.getPartnerAddress(); - QString hmemo= createHeaderMemo(safeContact,cid,myAddr); + QString hmemo= createHeaderMemo(type,cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); // ui->memoSizeChat->setLenDisplayLabel(); @@ -229,6 +216,7 @@ void MainWindow::sendChatButton() { connD->statusDetail->setText(tr("Your Message will be send")); d->show(); + ui->memoTxtChat->clear(); // And send the Tx rpc->executeTransaction(tx, @@ -248,6 +236,7 @@ void MainWindow::sendChatButton() { // Force a UI update so we get the unconfirmed Tx rpc->refresh(true); + ui->memoTxtChat->clear(); }, // Errored out diff --git a/src/chatmodel.h b/src/chatmodel.h index 524ce61..e0a6dd0 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -5,6 +5,10 @@ #include #include #include "precompiled.h" +#include "mainwindow.h" +#include "controller.h" +#include "settings.h" +#include "camount.h" class ChatItem { @@ -103,6 +107,8 @@ class ChatModel private: std::map chatItems; QTableView* parent; + Ui::MainWindow* ui; + MainWindow* main; public: ChatModel() {}; @@ -110,9 +116,10 @@ class ChatModel ChatModel(std::vector chatItems); std::map getItems(); void setItems(std::map items); + QString zaddr(); void setItems(std::vector items); - void renderChatBox(QListWidget &view); - void renderChatBox(QListWidget *view); + void renderChatBox(Ui::MainWindow* ui, QListWidget &view); + void renderChatBox(Ui::MainWindow* ui, QListWidget *view); void showMessages(); void clear(); void addMessage(ChatItem item); diff --git a/src/controller.cpp b/src/controller.cpp index 4a65ba9..0c557ca 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -985,7 +985,7 @@ void Controller::refreshTransactions() // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); - chatModel->renderChatBox(ui->listChatMemo); + chatModel->renderChatBox(ui, ui->listChatMemo); refreshContacts( ui->listContactWidget ); @@ -994,7 +994,7 @@ void Controller::refreshTransactions() void Controller::refreshChat(QListWidget *listWidget) { - chatModel->renderChatBox(listWidget); + chatModel->renderChatBox(ui, listWidget); } void Controller::refreshContacts(QListWidget *listWidget) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 88a4d5f..ab37b27 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -994,10 +994,14 @@ void MainWindow::setupchatTab() { QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { QModelIndex index = ui->listContactWidget->currentIndex(); - QString zaddr = index.data(Qt::DisplayRole).toString(); - ui->ContactZaddr->setText(zaddr); - - }); + QString label_contact = index.data(Qt::DisplayRole).toString(); + + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + if (label_contact == p.getName()) + ui->ContactZaddr->setText(p.getPartnerAddress()); + + rpc->refresh(true); + }); } ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { diff --git a/src/mainwindow.h b/src/mainwindow.h index f9f781b..7114eda 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -77,7 +77,7 @@ public: Logger* logger; void doClose(); - QString createHeaderMemo(QString safeContact, QString cid, QString zaddr, int version, int headerNumber); + QString createHeaderMemo(QString type, QString cid, QString zaddr, int version, int headerNumber); public slots: void slot_change_theme(const QString& themeName); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 7bb612e..ed63164 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1453,7 +1453,7 @@ - 690 + 520 490 67 17 @@ -1479,10 +1479,10 @@ - 740 + 550 490 - 171 - 17 + 691 + 20 From ab1e52586000b2bc0aa54936f473973d7ccfc455 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 30 Apr 2020 21:18:37 +0200 Subject: [PATCH 029/253] render incoming and outgoing memos in a chat conversation --- src/addressbook.cpp | 2 + src/chatmodel.cpp | 104 +++++++++++++++++++++--------------------- src/chatmodel.h | 4 +- src/controller.cpp | 108 +++++++++++++++++--------------------------- src/mainwindow.cpp | 4 +- src/mainwindow.ui | 31 +++++++++---- 6 files changed, 124 insertions(+), 129 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index ca224b4..522ec60 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -194,6 +194,8 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) message, //todo translate this QMessageBox::Ok ); + parent->ui->listReceiveAddresses->insertItem(0, addr); + parent->ui->listReceiveAddresses->setCurrentIndex(0); // ab.addr_chat->setText(myAddr); qDebug() << "new generated myAddr" << myAddr; QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 2b2b6a0..f449b99 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -62,9 +62,7 @@ void ChatModel::showMessages() } } - - -void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget &view) +void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget &view) { /*for(auto &c : this->chatItems) { @@ -90,14 +88,22 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) myDateTime.setTime_t(c.second.getTimestamp()); - ////// - if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false)) { + //////Render only Memos for selected contacts. Do not render empty Memos + if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)) { line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; - }else {} + } + + if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ + line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); + line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); + line += QString(c.second.getMemo()) + QString("\n"); + view->addItem(line); + line =""; + }else{} } @@ -130,14 +136,8 @@ Tx MainWindow::createTxFromChatPage() { CAmount totalAmt; // For each addr/amt in the Chat tab { - - // QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here - // Remove label if it exists - // addr = AddressBook::addressFromAddressLabel(addr); - + QString amtStr = "0"; - - // bool ok; CAmount amt; @@ -151,17 +151,16 @@ Tx MainWindow::createTxFromChatPage() { QString cid = c.getCid(); QString myAddr = c.getMyAddress(); - QString type = "memo"; + QString type = "Memo"; QString addr = c.getPartnerAddress(); QString hmemo= createHeaderMemo(type,cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); - // ui->memoSizeChat->setLenDisplayLabel(); - - + // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; - qDebug()<text()))) { - // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), - // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), - // QMessageBox::Ok, this); + // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - // msg.exec(); - //return; - //} + // if (ui->ContactZaddr->text().trimmed() == c.getName()) { + + // auto addr = ""; + // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), + // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), + // QMessageBox::Ok, this); + + // msg.exec(); + // return; + // } Tx tx = createTxFromChatPage(); @@ -287,20 +292,13 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { return ""; } -// Create a Safe Contact Request. +// Create a Contact Request. Tx MainWindow::createTxForSafeContactRequest() { Tx tx; CAmount totalAmt; - // For each addr/amt in the Chat tab { - QString addr = ui->ContactZaddr->text().trimmed(); // We need to set the reply Address for our Contact here - // Remove label if it exists - addr = AddressBook::addressFromAddressLabel(addr); - QString amtStr = "0"; - - // bool ok; CAmount amt; @@ -318,20 +316,17 @@ Tx MainWindow::createTxForSafeContactRequest() { QString cid = ""; QString myAddr = ""; QString addr = ""; - QString safeContact = "true"; + QString type = "Request"; - QString hmemo= createHeaderMemo(safeContact,cid,myAddr); - QString memo = ui->memoTxtChat->toPlainText().trimmed(); - // ui->memoSizeChat->setLenDisplayLabel(); - - + QString hmemo= createHeaderMemo(type,cid,myAddr); + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; - qDebug()<text()))) { - // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), - // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), - // QMessageBox::Ok, this); + // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - // msg.exec(); - //return; - //} + // if (ui->ContactZaddr->text().trimmed() == c.getName()) { + + // auto addr = ""; + // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + // QMessageBox msg(QMessageBox::Critical, tr("Contact requests can only be used with z-addresses"), + // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), + // QMessageBox::Ok, this); + + // msg.exec(); + // return; + // } Tx tx = createTxForSafeContactRequest(); diff --git a/src/chatmodel.h b/src/chatmodel.h index e0a6dd0..43a0e88 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -118,8 +118,8 @@ class ChatModel void setItems(std::map items); QString zaddr(); void setItems(std::vector items); - void renderChatBox(Ui::MainWindow* ui, QListWidget &view); - void renderChatBox(Ui::MainWindow* ui, QListWidget *view); + void renderChatBox(Ui::MainWindow* ui, QListWidget &view); + void renderChatBox(Ui::MainWindow* ui, QListWidget *view); void showMessages(); void clear(); void addMessage(ChatItem item); diff --git a/src/controller.cpp b/src/controller.cpp index 0c557ca..644fdfb 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -840,48 +840,47 @@ void Controller::refreshBalances() }); } -void Controller::refreshTransactions() -{ +void Controller::refreshTransactions() { if (!zrpc->haveConnection()) return noConnection(); zrpc->fetchTransactions([=] (json reply) { QList txdata; - for (auto& it : reply.get()) - { + for (auto& it : reply.get()) { QString address; CAmount total_amount; QList items; long confirmations; - if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get()) + if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get()) { confirmations = 0; - else + } else { confirmations = model->getLatestBlock() - it["block_height"].get() + 1; + } auto txid = QString::fromStdString(it["txid"]); auto datetime = it["datetime"].get(); // First, check if there's outgoing metadata - if (!it["outgoing_metadata"].is_null()) - { - for (auto o: it["outgoing_metadata"].get()) - { - QString address; + if (!it["outgoing_metadata"].is_null()) { + + for (auto o: it["outgoing_metadata"].get()) { + + QString address; + address = QString::fromStdString(o["address"]); - + // Sent items are -ve CAmount amount = CAmount::fromqint64(-1* o["value"].get()); // Check for Memos QString memo; - if (!o["memo"].is_null()) - { + if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - - ChatItem item = ChatItem( + } + ChatItem item = ChatItem( datetime, address, QString(""), @@ -889,9 +888,6 @@ void Controller::refreshTransactions() true // is an outgoing message ); chatModel->addMessage(item); - - } - items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -901,62 +897,46 @@ void Controller::refreshTransactions() // Concat all the addresses QList addresses; - for (auto item : items) - { - if (item.amount == 0 ) - { - } - else - { - addresses.push_back(item.address); - address = addresses.join(","); - } + for (auto item : items) { + + addresses.push_back(item.address); + + address = addresses.join(","); - } + } } - txdata.push_back( - TransactionItem{"send", datetime, address, txid,confirmations, items} - ); - - } - else - { + txdata.push_back(TransactionItem{ + "send", datetime, address, txid,confirmations, items + }); + } else { // Incoming Transaction address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); model->markAddressUsed(address); + QString memo; - if (!it["memo"].is_null()) - { + if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); - - ChatItem item = ChatItem( + } + + ChatItem item = ChatItem( datetime, address, QString(""), memo ); chatModel->addMessage(item); - } - - items.push_back( - TransactionItemDetail{ - address, - CAmount::fromqint64(it["amount"].get()), - memo - } - ); + items.push_back(TransactionItemDetail{ + address, + CAmount::fromqint64(it["amount"].get()), + memo + }); TransactionItem tx{ - "Receive", - datetime, - address, - txid, - confirmations, - items + "Receive", datetime, address, txid,confirmations, items }; txdata.push_back(tx); @@ -967,29 +947,25 @@ void Controller::refreshTransactions() // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds CAmount totalPending; - for (auto txitem : txdata) - { - if (txitem.confirmations == 0) - { - for (auto item: txitem.items) - { + for (auto txitem : txdata) { + if (txitem.confirmations == 0) { + for (auto item: txitem.items) { totalPending = totalPending + item.amount; } } } - - getModel()->setTotalPending(totalPending); + getModel()->setTotalPending(totalPending); // Update UI Balance updateUIBalances(); - // Update model data, which updates the table view + // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); chatModel->renderChatBox(ui, ui->listChatMemo); refreshContacts( ui->listContactWidget ); - }); + }); } void Controller::refreshChat(QListWidget *listWidget) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ab37b27..f6bb131 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -997,10 +997,12 @@ void MainWindow::setupchatTab() { QString label_contact = index.data(Qt::DisplayRole).toString(); for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) - if (label_contact == p.getName()) + if (label_contact == p.getName()) { ui->ContactZaddr->setText(p.getPartnerAddress()); + ui->MyZaddr->setText(p.getMyAddress()); rpc->refresh(true); + } }); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index ed63164..1a0bb02 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1354,8 +1354,8 @@ - 340 - 490 + 400 + 410 331 17 @@ -1453,8 +1453,8 @@ - 520 - 490 + 340 + 460 67 17 @@ -1466,21 +1466,21 @@ - 520 + 340 490 - 67 + 161 17 - + Your HushChat zaddr: - 550 - 490 + 370 + 460 691 20 @@ -1511,6 +1511,19 @@ false + + + + 490 + 490 + 691 + 20 + + + + + + From 623e5b6d2c603692a2a4aebf760cbc13c5173ef2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 30 Apr 2020 21:45:54 +0200 Subject: [PATCH 030/253] change some gui elements --- src/chatmodel.cpp | 4 ++-- src/mainwindow.cpp | 1 + src/mainwindow.ui | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index f449b99..1c43495 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -91,7 +91,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) //////Render only Memos for selected contacts. Do not render empty Memos if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)) { line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); + line += QString("<") + QString("Outgoing") + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; @@ -99,7 +99,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString("<") + QString(c.second.getContact()) + QString("> :\n"); + line += QString("<") + QString("incoming") + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f6bb131..ce474cc 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1000,6 +1000,7 @@ void MainWindow::setupchatTab() { if (label_contact == p.getName()) { ui->ContactZaddr->setText(p.getPartnerAddress()); ui->MyZaddr->setText(p.getMyAddress()); + ui->contactNameMemo->setText(p.getName()); rpc->refresh(true); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1a0bb02..2de859e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1348,7 +1348,7 @@ - <html><head/><body><p align="center">Contact</p></body></html> + <html><head/><body><p align="center">Hushchat Contactlist</p></body></html> @@ -1390,17 +1390,17 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + - 340 + 720 50 - 861 + 481 20 - <html><head/><body><p align="center">Messages</p></body></html> + <html><head/><body><p align="center"><br/></p></body></html> @@ -1505,7 +1505,7 @@ - Sicheren Kontakt hinzufügen + Add conversation contact false From 71941224494bf0f39224b7b8361b150682d07b4f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 30 Apr 2020 22:58:35 +0200 Subject: [PATCH 031/253] change some gui elements, deactivate contact request for now --- src/chatmodel.cpp | 21 +++++++++++---------- src/controller.cpp | 42 ++++++++++++++++++++++-------------------- src/mainwindow.cpp | 2 +- src/mainwindow.ui | 10 +++++----- src/sendtab.cpp | 18 +++++++++--------- 5 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 1c43495..e95aff7 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -36,6 +36,7 @@ void ChatModel::setItems(std::vector items) for(ChatItem c : items) { this->chatItems[c.getTimestamp()] = c; + } } @@ -95,7 +96,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; - } + }else{} if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); @@ -321,7 +322,7 @@ Tx MainWindow::createTxForSafeContactRequest() { QString hmemo= createHeaderMemo(type,cid,myAddr); - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; + // tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; qDebug() << "pushback chattx"; } @@ -334,7 +335,7 @@ Tx MainWindow::createTxForSafeContactRequest() { qDebug() << "ChatTx created"; } - +//////////////////De-activated for now/////////////////// void MainWindow::safeContactRequest() { ////////////////////////////Todo: Check if its a zaddr////////// @@ -357,9 +358,9 @@ void MainWindow::safeContactRequest() { // return; // } - Tx tx = createTxForSafeContactRequest(); + /* Tx tx = createTxForSafeContactRequest(); - QString error = doSendChatTxValidations(tx); + QString error = doSendRequestTxValidations(tx); if (!error.isEmpty()) { // Something went wrong, so show an error and exit @@ -419,14 +420,14 @@ void MainWindow::safeContactRequest() { QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); } - ); - } + );*/ + } QString MainWindow::doSendRequestTxValidations(Tx tx) { // Check to see if we have enough verified funds to send the Tx. - CAmount total; + /* CAmount total; for (auto toAddr : tx.toAddrs) { if (!Settings::isValidAddress(toAddr.addr)) { QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr); @@ -450,5 +451,5 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { .arg(available.toDecimalhushString(), total.toDecimalhushString()); } - return ""; -} \ No newline at end of file + return "";*/ +} diff --git a/src/controller.cpp b/src/controller.cpp index 644fdfb..e6b6b37 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -879,37 +879,40 @@ void Controller::refreshTransactions() { QString memo; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - } - ChatItem item = ChatItem( + + ChatItem item = ChatItem( datetime, address, QString(""), - memo, - true // is an outgoing message + memo + // true // is an outgoing message ); chatModel->addMessage(item); + } + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; - } + // } - { + // { // Concat all the addresses - QList addresses; - for (auto item : items) { + // QList addresses; + // for (auto item : items) { - addresses.push_back(item.address); + // addresses.push_back(item.address); - address = addresses.join(","); + - } + // } - } + // } txdata.push_back(TransactionItem{ "send", datetime, address, txid,confirmations, items }); + } } else { // Incoming Transaction address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); @@ -919,8 +922,14 @@ void Controller::refreshTransactions() { if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); } + + TransactionItem tx{ + "Receive", datetime, address, txid,confirmations, items + }; - ChatItem item = ChatItem( + txdata.push_back(tx); + + ChatItem item = ChatItem( datetime, address, QString(""), @@ -933,13 +942,6 @@ void Controller::refreshTransactions() { CAmount::fromqint64(it["amount"].get()), memo }); - - - TransactionItem tx{ - "Receive", datetime, address, txid,confirmations, items - }; - - txdata.push_back(tx); } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ce474cc..76cd090 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -974,7 +974,7 @@ void MainWindow::setupTransactionsTab() { qApp->processEvents(); // Click the memo button - this->memoButtonClicked(1, true); + this->memoButtonClicked(1, true); }); } } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 2de859e..e5eb12e 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1460,7 +1460,7 @@ - To: + <html><head/><body><p>Send to :</p></body></html> @@ -1468,18 +1468,18 @@ 340 490 - 161 + 81 17 - Your HushChat zaddr: + <html><head/><body><p>My zaddr :</p></body></html> - 370 + 420 460 691 20 @@ -1514,7 +1514,7 @@ - 490 + 420 490 691 20 diff --git a/src/sendtab.cpp b/src/sendtab.cpp index 6d4ba38..67f6553 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -35,7 +35,7 @@ void MainWindow::setupSendTab() { }); // The first Memo button - QObject::connect(ui->MemoBtn1, &QPushButton::clicked, [=] () { + QObject::connect(ui->MemoBtn1, &QPushButton::clicked, [=] () { this->memoButtonClicked(1); }); setMemoEnabled(1, false); @@ -377,15 +377,15 @@ void MainWindow::setMemoEnabled(int number, bool enabled) { void MainWindow::memoButtonClicked(int number, bool includeReplyTo) { // Memos can only be used with zAddrs. So check that first - auto addr = ui->sendToWidgets->findChild(QString("Address") + QString::number(number)); - if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { - QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), - tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), - QMessageBox::Ok, this); + // auto addr = ui->sendToWidgets->findChild(QString("Address") + QString::number(number)); + //if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), + // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), + // QMessageBox::Ok, this); - msg.exec(); - return; - } + // msg.exec(); + // return; + // } // Get the current memo if it exists auto memoTxt = ui->sendToWidgets->findChild(QString("MemoTxt") + QString::number(number)); From 70302829b7618c8285df9f3f870e5a68ab247df2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 00:02:28 +0200 Subject: [PATCH 032/253] make Addressbook HushChat address changeable and show it earlier --- src/addressbook.cpp | 51 ++++++++++++++++++++++++++++----------------- src/addressbook.ui | 28 ++++++++++++------------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 522ec60..4725959 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -138,6 +138,24 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) // Connect the dialog's closing to updating the label address completor QObject::connect(&d, &QDialog::finished, [=] (auto) { parent->updateLabels(); }); + Controller* rpc = parent->getRPC(); + bool sapling = true; + rpc->createNewZaddr(sapling, [=] (json reply) { + QString myAddr = QString::fromStdString(reply.get()[0]); + // QString myAddr = "zs1flslqurcnummsw37mfxkhx6d7uwpevlc78cdjyqrgng7357t8f3stm9fneeqtuupfnrt7f933a9"; + QString message = QString("New Chat Address for your partner: ") + myAddr; + + parent->ui->listReceiveAddresses->insertItem(0, myAddr); + parent->ui->listReceiveAddresses->setCurrentIndex(0); + // ab.addr_chat->setText(myAddr); + qDebug() << "new generated myAddr" << myAddr; + // + ab.addr_chat->setText(myAddr); + // AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr, cid); + }); + model.updateUi(); //todo fix updating gui after adding + rpc->refresh(true); + // If there is a target then make it the addr for the "Add to" button if (target != nullptr && Settings::isValidAddress(target->text())) { @@ -148,7 +166,11 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) // Add new address button QObject::connect(ab.addNew, &QPushButton::clicked, [&] () { auto addr = ab.addr->text().trimmed(); + auto myAddr = ab.addr->text().trimmed(); QString newLabel = ab.label->text(); + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + + if (addr.isEmpty() || newLabel.isEmpty()) { @@ -183,32 +205,23 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ); return; } - Controller* rpc = parent->getRPC(); - bool sapling = true; - rpc->createNewZaddr(sapling, [=] (json reply) { - QString myAddr = QString::fromStdString(reply.get()[0]); - QString message = QString("New Chat Address for your partner: ") + myAddr; + + ////// We need a better popup here. + AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid); QMessageBox::critical( parent, - QObject::tr("Success"), - message, //todo translate this + QObject::tr("Add Successfully"), + QObject::tr("juhu").arg(newLabel), QMessageBox::Ok ); - parent->ui->listReceiveAddresses->insertItem(0, addr); - parent->ui->listReceiveAddresses->setCurrentIndex(0); - // ab.addr_chat->setText(myAddr); - qDebug() << "new generated myAddr" << myAddr; - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); // - AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr, cid); - }); - model.updateUi(); //todo fix updating gui after adding + return; + + + rpc->refresh(true); + model.updateUi(); }); - /// Generate CID for Contact - - - // AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), cid); // Import Button diff --git a/src/addressbook.ui b/src/addressbook.ui index 20104b9..1c6ed52 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -20,7 +20,17 @@ Add New Address - + + + + Address (z-Addr or t-Addr) + + + + + + + HushChat Address - give this Address only to your contact @@ -30,10 +40,10 @@ - - + + - Address (z-Addr or t-Addr) + Label @@ -47,16 +57,6 @@ - - - - Label - - - - - - From 24d3a4e9821e4fc857ce63112f0e1a50b3ce3644 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 00:18:31 +0200 Subject: [PATCH 033/253] fix typo --- src/addressbook.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 4725959..975c3e5 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -166,7 +166,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) // Add new address button QObject::connect(ab.addNew, &QPushButton::clicked, [&] () { auto addr = ab.addr->text().trimmed(); - auto myAddr = ab.addr->text().trimmed(); + auto myAddr = ab.addr_chat->text().trimmed(); QString newLabel = ab.label->text(); QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); From b9dab96b870f70c998fcee723a95ddb482b098e8 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 12:27:21 +0200 Subject: [PATCH 034/253] add txid and cid to chatmodel --- src/chatmodel.cpp | 8 ++++++-- src/chatmodel.h | 29 +++++++++++++++++++++++++++-- src/controller.cpp | 8 ++++++-- src/mainwindow.cpp | 1 + src/mainwindow.ui | 13 +++++++++++++ 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index e95aff7..eaa1b88 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -8,8 +8,11 @@ #include "ui_memodialog.h" #include "addressbook.h" #include +#include +#include - +using namespace std; +using namespace boost; ChatModel::ChatModel(std::map chatItems) { @@ -89,8 +92,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) myDateTime.setTime_t(c.second.getTimestamp()); - //////Render only Memos for selected contacts. Do not render empty Memos + //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)) { + // if (c.second.getMemo.find()) line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("Outgoing") + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); diff --git a/src/chatmodel.h b/src/chatmodel.h index 43a0e88..4e822c1 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -17,27 +17,33 @@ class ChatItem QString _address; QString _contact; QString _memo; + QString _cid; + QString _txid; bool _outgoing = false; public: ChatItem() {} - ChatItem(long timestamp, QString address, QString contact, QString memo) + ChatItem(long timestamp, QString address, QString contact, QString memo, QString cid, QString txid) { _timestamp = timestamp; _address = address; _contact = contact; _memo = memo; + _cid = cid; + _txid = txid; _outgoing = false; } - ChatItem(long timestamp, QString address, QString contact, QString memo, bool outgoing) + ChatItem(long timestamp, QString address, QString contact, QString memo, QString cid, QString txid, bool outgoing) { _timestamp = timestamp; _address = address; _contact = contact; _memo = memo; + _cid = cid; + _txid = txid; _outgoing = outgoing; } @@ -62,6 +68,16 @@ class ChatItem return _memo; } + QString getCid() + { + return _cid; + } + + QString getTxid() + { + return _cid; + } + bool isOutgoing() { return _outgoing; @@ -87,6 +103,15 @@ class ChatItem _memo = memo; } + void setCid(QString cid) + { + _cid = cid; + } + void setTxid(QString txid) + { + _txid = txid; + } + void toggleOutgo() { _outgoing = true; diff --git a/src/controller.cpp b/src/controller.cpp index e6b6b37..cf73946 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -884,7 +884,9 @@ void Controller::refreshTransactions() { datetime, address, QString(""), - memo + memo, + "", // we have to set the cid here, + txid // true // is an outgoing message ); chatModel->addMessage(item); @@ -933,7 +935,9 @@ void Controller::refreshTransactions() { datetime, address, QString(""), - memo + memo, + "", // we have to set the cid here + txid ); chatModel->addMessage(item); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 76cd090..2b252e4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1001,6 +1001,7 @@ void MainWindow::setupchatTab() { ui->ContactZaddr->setText(p.getPartnerAddress()); ui->MyZaddr->setText(p.getMyAddress()); ui->contactNameMemo->setText(p.getName()); + ui->contactCid->setText(p.getCid()); rpc->refresh(true); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index e5eb12e..913907f 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1524,6 +1524,19 @@ + + + + 870 + 90 + 331 + 20 + + + + <html><head/><body><p align="center"><br/></p></body></html> + + From 4afd49d0a7cb79eeff2c6066548a8c74efc70257 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 13:15:05 +0200 Subject: [PATCH 035/253] read the cid from headermemo into qstring --- src/controller.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index cf73946..0871d6b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -885,7 +885,7 @@ void Controller::refreshTransactions() { address, QString(""), memo, - "", // we have to set the cid here, + "", // we have to set the cid here, its included in our Addressbook for this contact txid // true // is an outgoing message ); @@ -924,21 +924,30 @@ void Controller::refreshTransactions() { if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); } - + TransactionItem tx{ "Receive", datetime, address, txid,confirmations, items }; txdata.push_back(tx); + QString cid; + if (memo.startsWith("{")) { + + cid = memo.mid(14,36); + + }else{ cid = "";} + ChatItem item = ChatItem( datetime, address, QString(""), memo, - "", // we have to set the cid here + cid, // we have to set the cid here, its included in the headermemo txid ); + qDebug()<addMessage(item); items.push_back(TransactionItemDetail{ From 4f4ec7cd317bd21114c4cf5ebc2d79c3135b029e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 13:42:25 +0200 Subject: [PATCH 036/253] fix typo --- src/chatmodel.cpp | 4 ++++ src/chatmodel.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index eaa1b88..558ea6f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -100,6 +100,10 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; + + ////////////////////////////////// Todo : Render green checkmark for contacts if cid = cid - We have to search for cid in txid/cid list + QString cid = c.second.getCid(); + }else{} if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ diff --git a/src/chatmodel.h b/src/chatmodel.h index 4e822c1..9f06d3a 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -75,7 +75,7 @@ class ChatItem QString getTxid() { - return _cid; + return _txid; } bool isOutgoing() From 899826398991fa81c51e56812dfac672dc506aa7 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 17:09:49 +0200 Subject: [PATCH 037/253] fix broken sendmemo --- src/controller.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 0871d6b..c26c2f3 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -895,26 +895,27 @@ void Controller::refreshTransactions() { items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; - // } + } - // { + { + QList addresses; + for (auto item : items) { // Concat all the addresses - - // QList addresses; - // for (auto item : items) { + if (item.amount == 0) { + + }else{ + - // addresses.push_back(item.address); + addresses.push_back(item.address); } - + } - // } - - // } + } + txdata.push_back(TransactionItem{ "send", datetime, address, txid,confirmations, items }); - } } else { // Incoming Transaction address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); @@ -925,6 +926,12 @@ void Controller::refreshTransactions() { memo = QString::fromStdString(it["memo"]); } + items.push_back(TransactionItemDetail{ + address, + CAmount::fromqint64(it["amount"].get()), + memo + }); + TransactionItem tx{ "Receive", datetime, address, txid,confirmations, items }; From 51c180af18039388332a474450fc6a9654851630 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 17:44:18 +0200 Subject: [PATCH 038/253] fix send of memos --- src/chatmodel.cpp | 10 ++++++---- src/controller.cpp | 23 +++++++++++------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 558ea6f..df894c3 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -93,7 +93,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) myDateTime.setTime_t(c.second.getTimestamp()); //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid - if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)) { + + /// + if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)) { // if (c.second.getMemo.find()) line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("Outgoing") + QString("> :\n"); @@ -102,7 +104,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) line =""; ////////////////////////////////// Todo : Render green checkmark for contacts if cid = cid - We have to search for cid in txid/cid list - QString cid = c.second.getCid(); + // QString cid = c.second.getCid(); }else{} @@ -170,7 +172,7 @@ Tx MainWindow::createTxFromChatPage() { tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; - tx.toAddrs.push_back( ToFields{addr, amt, memo}); + tx.toAddrs.push_back(ToFields{addr, amt, memo}); qDebug() << "pushback chattx"; } } @@ -249,7 +251,7 @@ void MainWindow::sendChatButton() { }); // Force a UI update so we get the unconfirmed Tx - rpc->refresh(true); + // rpc->refresh(true); ui->memoTxtChat->clear(); }, diff --git a/src/controller.cpp b/src/controller.cpp index c26c2f3..38bfada 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -926,25 +926,26 @@ void Controller::refreshTransactions() { memo = QString::fromStdString(it["memo"]); } - items.push_back(TransactionItemDetail{ + items.push_back(TransactionItemDetail{ address, CAmount::fromqint64(it["amount"].get()), memo }); - + + TransactionItem tx{ "Receive", datetime, address, txid,confirmations, items }; txdata.push_back(tx); - QString cid; - if (memo.startsWith("{")) { + QString cid = ""; + // if (memo.startsWith("{")) { - cid = memo.mid(14,36); - - }else{ cid = "";} + // cid = memo.mid(14,36); + // }else{ cid = "";} + ChatItem item = ChatItem( datetime, address, @@ -955,13 +956,9 @@ void Controller::refreshTransactions() { ); qDebug()<addMessage(item); - items.push_back(TransactionItemDetail{ - address, - CAmount::fromqint64(it["amount"].get()), - memo - }); } } @@ -986,6 +983,7 @@ void Controller::refreshTransactions() { chatModel->renderChatBox(ui, ui->listChatMemo); refreshContacts( ui->listContactWidget + ); }); } @@ -993,6 +991,7 @@ void Controller::refreshTransactions() { void Controller::refreshChat(QListWidget *listWidget) { chatModel->renderChatBox(ui, listWidget); + } void Controller::refreshContacts(QListWidget *listWidget) From 498fca3fd6cda564a45ea8abf78509cce7402c3a Mon Sep 17 00:00:00 2001 From: strider Date: Fri, 1 May 2020 18:51:09 +0200 Subject: [PATCH 039/253] update// fixed wrong savings --- src/chatmodel.cpp | 52 +++++++++++++++++++++++++++++++++++++++------- src/chatmodel.h | 17 +++++++++------ src/controller.cpp | 9 ++++---- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index df894c3..c01b84c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -14,7 +14,7 @@ using namespace std; using namespace boost; -ChatModel::ChatModel(std::map chatItems) +ChatModel::ChatModel(std::map chatItems) { this->chatItems = chatItems; } @@ -24,12 +24,26 @@ ChatModel::ChatModel(std::vector chatItems) this->setItems(chatItems); } -std::map ChatModel::getItems() +QString ChatModel::generateChatItemID(ChatItem item) +{ + QString key = QString::number(item.getTimestamp()) + QString("-"); + key += QString(QCryptographicHash::hash( + QString( + QString::number(item.getTimestamp()) + + item.getAddress() + + item.getContact() + + item.getMemo() + ).toUtf8() + ,QCryptographicHash::Md5).toHex()); + return key; +} + +std::map ChatModel::getItems() { return this->chatItems; } -void ChatModel::setItems(std::map items) +void ChatModel::setItems(std::map items) { this->chatItems = chatItems; } @@ -38,7 +52,7 @@ void ChatModel::setItems(std::vector items) { for(ChatItem c : items) { - this->chatItems[c.getTimestamp()] = c; + this->chatItems[this->generateChatItemID(c)] = c; } } @@ -50,12 +64,16 @@ void ChatModel::clear() void ChatModel::addMessage(ChatItem item) { - this->chatItems[item.getTimestamp()] = item; + QString key = this->generateChatItemID(item); + qDebug() << "inserting chatitem with id: " << key; + this->chatItems[key] = item; } -void ChatModel::addMessage(long timestamp, ChatItem item) +void ChatModel::addMessage(QString timestamp, ChatItem item) { - this->chatItems[timestamp] = item; + QString key = this->generateChatItemID(item); + timestamp = "0"; + this->chatItems[key] = item; } void ChatModel::showMessages() @@ -120,6 +138,26 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) } +void ChatModel::addCid(QString tx, QString cid) +{ + this->cidMap[tx] = cid; +} + +QString ChatModel::getCidByTx(QString tx) +{ + if(this->cidMap.count(tx) > 0) + { + return this->cidMap[tx]; + } + + return QString("0xdeadbeef"); +} + +void ChatModel::killCidCache() +{ + this->cidMap.clear(); +} + QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) { diff --git a/src/chatmodel.h b/src/chatmodel.h index 9f06d3a..fcc68bf 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -73,7 +73,7 @@ class ChatItem return _cid; } - QString getTxid() + QString getTxid() { return _txid; } @@ -130,17 +130,19 @@ class ChatItem class ChatModel { private: - std::map chatItems; + std::map chatItems; QTableView* parent; Ui::MainWindow* ui; MainWindow* main; + std::map cidMap; public: ChatModel() {}; - ChatModel(std::map chatItems); + ChatModel(std::map chatItems); ChatModel(std::vector chatItems); - std::map getItems(); - void setItems(std::map items); + QString generateChatItemID(ChatItem item); + std::map getItems(); + void setItems(std::map items); QString zaddr(); void setItems(std::vector items); void renderChatBox(Ui::MainWindow* ui, QListWidget &view); @@ -148,7 +150,10 @@ class ChatModel void showMessages(); void clear(); void addMessage(ChatItem item); - void addMessage(long timestamp, ChatItem item); + void addMessage(QString timestamp, ChatItem item); + void addCid(QString tx, QString cid); + QString getCidByTx(QString tx); + void killCidCache(); }; #endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 38bfada..5952201 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -940,11 +940,10 @@ void Controller::refreshTransactions() { txdata.push_back(tx); QString cid = ""; - // if (memo.startsWith("{")) { - - // cid = memo.mid(14,36); - - // }else{ cid = "";} + if (memo.startsWith("{")) { + cid = memo.mid(14,36); + chatModel->addCid(txid, cid); + }else{ cid = "";} ChatItem item = ChatItem( datetime, From 95638a25fd46c0c3619b95d36a6bdb8b6e353ddd Mon Sep 17 00:00:00 2001 From: Strider <404@127.0.0.1.com> Date: Fri, 1 May 2020 19:18:07 +0200 Subject: [PATCH 040/253] update// map read --- src/chatmodel.cpp | 5 +++++ src/controller.cpp | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c01b84c..c4b7678 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -145,6 +145,11 @@ void ChatModel::addCid(QString tx, QString cid) QString ChatModel::getCidByTx(QString tx) { + for(auto& pair : this->cidMap) + { + qDebug() << "TXID=" << pair.first << " CID=" << pair.second; + } + if(this->cidMap.count(tx) > 0) { return this->cidMap[tx]; diff --git a/src/controller.cpp b/src/controller.cpp index 5952201..0845a16 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -943,8 +943,13 @@ void Controller::refreshTransactions() { if (memo.startsWith("{")) { cid = memo.mid(14,36); chatModel->addCid(txid, cid); - }else{ cid = "";} - + }else{ + if(chatModel->getCidByTx(txid) != QString("0xdeadbeef")) + cid = chatModel->getCidByTx(txid); + + cid = ""; + } + ChatItem item = ChatItem( datetime, address, @@ -953,9 +958,7 @@ void Controller::refreshTransactions() { cid, // we have to set the cid here, its included in the headermemo txid ); - qDebug()<addMessage(item); } From 7faf0f0b50c89d19845b7c79501ff9373089c39c Mon Sep 17 00:00:00 2001 From: Strider <404@127.0.0.1.com> Date: Fri, 1 May 2020 19:34:23 +0200 Subject: [PATCH 041/253] fix// added else --- src/chatmodel.cpp | 4 +++- src/controller.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c4b7678..6ba7255 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -117,6 +117,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) // if (c.second.getMemo.find()) line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("Outgoing") + QString("> :\n"); + line += QString("<") + c.second.getCid() + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; @@ -129,6 +130,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("incoming") + QString("> :\n"); + line += QString("<") + c.second.getCid() + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; @@ -149,7 +151,7 @@ QString ChatModel::getCidByTx(QString tx) { qDebug() << "TXID=" << pair.first << " CID=" << pair.second; } - + if(this->cidMap.count(tx) > 0) { return this->cidMap[tx]; diff --git a/src/controller.cpp b/src/controller.cpp index 0845a16..b1e3f4f 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -947,7 +947,8 @@ void Controller::refreshTransactions() { if(chatModel->getCidByTx(txid) != QString("0xdeadbeef")) cid = chatModel->getCidByTx(txid); - cid = ""; + else + cid = ""; } ChatItem item = ChatItem( From 6ddb6855d49a1222a5f00cfafb80c6f80802787e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 19:36:38 +0200 Subject: [PATCH 042/253] merge and ui update - for debug --- src/addressbook.cpp | 4 ++-- src/addressbook.ui | 2 +- src/chatmodel.cpp | 2 ++ src/controller.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 975c3e5..be13b82 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -168,9 +168,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto addr = ab.addr->text().trimmed(); auto myAddr = ab.addr_chat->text().trimmed(); QString newLabel = ab.label->text(); - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + // QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); - + QString cid = ab.cid->text(); if (addr.isEmpty() || newLabel.isEmpty()) { diff --git a/src/addressbook.ui b/src/addressbook.ui index 1c6ed52..f2344eb 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -55,7 +55,7 @@ - + diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c4b7678..85b135a 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -117,6 +117,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) // if (c.second.getMemo.find()) line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("Outgoing") + QString("> :\n"); + line += QString("<") + c.second.getCid() + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; @@ -129,6 +130,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("incoming") + QString("> :\n"); + line += QString("<") + c.second.getCid() + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; diff --git a/src/controller.cpp b/src/controller.cpp index 0845a16..0457ccd 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -947,7 +947,7 @@ void Controller::refreshTransactions() { if(chatModel->getCidByTx(txid) != QString("0xdeadbeef")) cid = chatModel->getCidByTx(txid); - cid = ""; + //cid = ""; } ChatItem item = ChatItem( From 5ee796dc0f4842a36e45bba86c265b41cfb4179c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 19:46:38 +0200 Subject: [PATCH 043/253] set cid for outgoing memos --- src/controller.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/controller.cpp b/src/controller.cpp index b1e3f4f..cb32868 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -880,12 +880,19 @@ void Controller::refreshTransactions() { if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); + QString cid; + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + if (ui->ContactZaddr->text().trimmed() == c.getPartnerAddress()) { + + cid = c.getCid(); + }else {cid = "";} + ChatItem item = ChatItem( datetime, address, QString(""), memo, - "", // we have to set the cid here, its included in our Addressbook for this contact + cid, // we have to set the cid here, its included in our Addressbook for this contact txid // true // is an outgoing message ); From a3e762a4adca33602ad7501232db5fd032226982 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 20:19:29 +0200 Subject: [PATCH 044/253] add verified flag for Chatmessages --- src/chatmodel.cpp | 13 ++++++++----- src/controller.cpp | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 6ba7255..8a0689b 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -117,23 +117,26 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) // if (c.second.getMemo.find()) line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("Outgoing") + QString("> :\n"); - line += QString("<") + c.second.getCid() + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); line =""; + ////////////////////////////////// Todo : Render green checkmark for contacts if cid = cid - We have to search for cid in txid/cid list // QString cid = c.second.getCid(); - }else{} - + } + if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()){ + if (p.getCid() == c.second.getCid()){ + line += QString("<") + "verified" + QString("> :\n");} + } line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("incoming") + QString("> :\n"); - line += QString("<") + c.second.getCid() + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); - line =""; + line =""; }else{} } diff --git a/src/controller.cpp b/src/controller.cpp index cb32868..36ac2c8 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -882,7 +882,7 @@ void Controller::refreshTransactions() { QString cid; for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (ui->ContactZaddr->text().trimmed() == c.getPartnerAddress()) { + if ((ui->ContactZaddr->text().trimmed() == c.getPartnerAddress()) || (ui->MyZaddr->text().trimmed() == c.getMyAddress())) { cid = c.getCid(); }else {cid = "";} From f515be1aa8898b6cb16febd3a06a1241926fb8ad Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 21:40:45 +0200 Subject: [PATCH 045/253] create a cid in addressbook but make it editable for the beginning --- src/addressbook.cpp | 9 +++------ src/addressbook.ui | 25 ++++++++++++++++--------- src/chatmodel.cpp | 7 ++++--- src/mainwindow.ui | 21 +++++++++++++++++---- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index be13b82..1a2bad3 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -142,16 +142,15 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) bool sapling = true; rpc->createNewZaddr(sapling, [=] (json reply) { QString myAddr = QString::fromStdString(reply.get()[0]); - // QString myAddr = "zs1flslqurcnummsw37mfxkhx6d7uwpevlc78cdjyqrgng7357t8f3stm9fneeqtuupfnrt7f933a9"; QString message = QString("New Chat Address for your partner: ") + myAddr; + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); parent->ui->listReceiveAddresses->insertItem(0, myAddr); parent->ui->listReceiveAddresses->setCurrentIndex(0); - // ab.addr_chat->setText(myAddr); + qDebug() << "new generated myAddr" << myAddr; - // + ab.cid->setText(cid); ab.addr_chat->setText(myAddr); - // AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), myAddr, cid); }); model.updateUi(); //todo fix updating gui after adding rpc->refresh(true); @@ -168,8 +167,6 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto addr = ab.addr->text().trimmed(); auto myAddr = ab.addr_chat->text().trimmed(); QString newLabel = ab.label->text(); - // QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); - QString cid = ab.cid->text(); if (addr.isEmpty() || newLabel.isEmpty()) diff --git a/src/addressbook.ui b/src/addressbook.ui index f2344eb..c2d255d 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -27,9 +27,23 @@ + + + + Nickname + + + + + + + 40 + + + @@ -41,20 +55,13 @@ - + - Label + <html><head/><body><p>Conversation ID (editable):</p></body></html> - - - 40 - - - - diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 8a0689b..24523a1 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -129,8 +129,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ for(auto &p : AddressBook::getInstance()->getAllAddressLabels()){ - if (p.getCid() == c.second.getCid()){ - line += QString("<") + "verified" + QString("> :\n");} + if ((p.getCid() == c.second.getCid())){ + line+= QString("[") + "Verified Message" + QString("]"); ////Todo: Render a green checkmark instead of QString + } } line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("incoming") + QString("> :\n"); @@ -152,7 +153,7 @@ QString ChatModel::getCidByTx(QString tx) { for(auto& pair : this->cidMap) { - qDebug() << "TXID=" << pair.first << " CID=" << pair.second; + // qDebug() << "TXID=" << pair.first << " CID=" << pair.second; } if(this->cidMap.count(tx) > 0) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 913907f..32affce 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1393,9 +1393,9 @@ - 720 + 350 50 - 481 + 291 20 @@ -1527,8 +1527,8 @@ - 870 - 90 + 820 + 60 331 20 @@ -1537,6 +1537,19 @@ <html><head/><body><p align="center"><br/></p></body></html> + + + + 690 + 60 + 131 + 20 + + + + <html><head/><body><p align="center">Conversation ID:</p></body></html> + + From c7d0acac71c03c44d553c97c35eef4435153810a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 21:49:47 +0200 Subject: [PATCH 046/253] delete some debug outputs --- src/chatmodel.cpp | 2 +- src/controller.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 24523a1..89a7dde 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -65,7 +65,7 @@ void ChatModel::clear() void ChatModel::addMessage(ChatItem item) { QString key = this->generateChatItemID(item); - qDebug() << "inserting chatitem with id: " << key; + // qDebug() << "inserting chatitem with id: " << key; this->chatItems[key] = item; } diff --git a/src/controller.cpp b/src/controller.cpp index 36ac2c8..b0453d2 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -966,7 +966,7 @@ void Controller::refreshTransactions() { cid, // we have to set the cid here, its included in the headermemo txid ); - qDebug()<< "Message CID: " << cid; + // qDebug()<< "Message CID: " << cid; chatModel->addMessage(item); } @@ -1006,7 +1006,6 @@ void Controller::refreshChat(QListWidget *listWidget) void Controller::refreshContacts(QListWidget *listWidget) { - qDebug() << "Called Controller::refreshContacts(QListWidget *listWidget)"; contactModel->renderContactList(listWidget); } From 3b80b98c0dcd09e8a1c828c2ebaa4e905f32f153 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 23:06:50 +0200 Subject: [PATCH 047/253] prevent sending of empty memos from chatpage --- src/chatmodel.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 89a7dde..d3c78a0 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -131,6 +131,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) for(auto &p : AddressBook::getInstance()->getAllAddressLabels()){ if ((p.getCid() == c.second.getCid())){ line+= QString("[") + "Verified Message" + QString("]"); ////Todo: Render a green checkmark instead of QString + }else{ + + // line+= QString("[") + "Warning. Not verified!" + QString("]"); } } line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); @@ -234,7 +237,7 @@ Tx MainWindow::createTxFromChatPage() { } void MainWindow::sendChatButton() { - ////////////////////////////Todo: Check if its a zaddr////////// + ////////////////////////////Todo: Check if a Contact is selected////////// // Create a Tx from the values on the send tab. Note that this Tx object // might not be valid yet. @@ -242,17 +245,17 @@ void MainWindow::sendChatButton() { // Memos can only be used with zAddrs. So check that first // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - // if (ui->ContactZaddr->text().trimmed() == c.getName()) { + if (ui->ContactZaddr->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { // auto addr = ""; // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { - // QMessageBox msg(QMessageBox::Critical, tr("Memos can only be used with z-addresses"), - // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), - // QMessageBox::Ok, this); + QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), + tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), + QMessageBox::Ok, this); - // msg.exec(); - // return; - // } + msg.exec(); + return; + } Tx tx = createTxFromChatPage(); From e97a0b07c2b3aa43c55686f25885e2306e841c3c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 1 May 2020 23:40:14 +0200 Subject: [PATCH 048/253] merge in the sdl gifs from @csharpee, add check bob to render only verified messages --- src/chatmodel.cpp | 14 ++++++- src/mainwindow.ui | 99 +++++++++++++++++++++++++++-------------------- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index d3c78a0..066eb60 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -277,8 +277,18 @@ void MainWindow::sendChatButton() { auto d = new QDialog(this); auto connD = new Ui_ConnectionDialog(); connD->setupUi(d); - QPixmap logo(":/img/res/logobig.gif"); - connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif");; + QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif");; + auto theme = Settings::getInstance()->get_theme_name(); + if (theme == "dark" || theme == "midnight") { + movie2->setScaledSize(QSize(512,512)); + connD->topIcon->setMovie(movie2); + movie2->start(); + } else { + movie1->setScaledSize(QSize(512,512)); + connD->topIcon->setMovie(movie1); + movie1->start(); + } connD->status->setText(tr("Please wait...")); connD->statusDetail->setText(tr("Your Message will be send")); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 32affce..3196dff 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -18,8 +18,8 @@ :/icons/res/icon.ico:/icons/res/icon.ico - - + + 5 @@ -389,7 +389,7 @@ 0 0 1226 - 504 + 488 @@ -1332,17 +1332,17 @@ 0 - 80 + 40 341 - 561 + 551 - 6 - 40 + 0 + 0 311 20 @@ -1351,25 +1351,12 @@ <html><head/><body><p align="center">Hushchat Contactlist</p></body></html> - - - - 400 - 410 - 331 - 17 - - - - Memo - - 340 - 510 - 901 + 410 + 921 128 @@ -1377,8 +1364,8 @@ - 1180 - 460 + 1200 + 540 47 17 @@ -1393,9 +1380,9 @@ - 350 - 50 - 291 + 450 + 20 + 161 20 @@ -1410,7 +1397,7 @@ 340 - 80 + 40 921 371 @@ -1432,7 +1419,7 @@ 1130 - 650 + 590 114 25 @@ -1453,21 +1440,21 @@ - 340 - 460 - 67 + 350 + 550 + 81 17 - <html><head/><body><p>Send to :</p></body></html> + Send To : - 340 - 490 + 350 + 580 81 17 @@ -1480,7 +1467,7 @@ 420 - 460 + 550 691 20 @@ -1492,8 +1479,8 @@ - 943 - 20 + 50 + 600 211 25 @@ -1515,7 +1502,7 @@ 420 - 490 + 580 691 20 @@ -1527,8 +1514,8 @@ - 820 - 60 + 720 + 20 331 20 @@ -1540,8 +1527,8 @@ - 690 - 60 + 590 + 20 131 20 @@ -1550,6 +1537,32 @@ <html><head/><body><p align="center">Conversation ID:</p></body></html> + + + + 980 + 0 + 271 + 23 + + + + Render only authenticated messages + + + + + + 340 + 20 + 111 + 20 + + + + <html><head/><body><p align="center">Contact Name:</p></body></html> + + From 29492b73c3f8894888189834c8b57b5c067fff11 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 2 May 2020 00:06:36 +0200 Subject: [PATCH 049/253] render only memos from a valid cid if checkbox is true --- src/chatmodel.cpp | 24 +++++++++++++++++------- src/mainwindow.cpp | 1 + 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 066eb60..c6dd75d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -129,24 +129,34 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ for(auto &p : AddressBook::getInstance()->getAllAddressLabels()){ - if ((p.getCid() == c.second.getCid())){ - line+= QString("[") + "Verified Message" + QString("]"); ////Todo: Render a green checkmark instead of QString - }else{ + + if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) + { + + + }else{ // line+= QString("[") + "Warning. Not verified!" + QString("]"); - } - } + + line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); line += QString("<") + QString("incoming") + QString("> :\n"); line += QString(c.second.getMemo()) + QString("\n"); view->addItem(line); - line =""; - }else{} + line =""; + } + + + } + } + + } } + void ChatModel::addCid(QString tx, QString cid) { this->cidMap[tx] = cid; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2b252e4..f17bfc9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -39,6 +39,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); + ui->checkBox->setChecked(true); logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); // Status Bar From 0223d6def84a940a794979b4031554ccf2120f5c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 01:03:29 +0200 Subject: [PATCH 050/253] add chatbubbles to render chat --- src/chatmodel.cpp | 111 +++++++++++++++++-------------- src/chatmodel.h | 161 ++++++++++++++++++++++++++++++++++++++++++++- src/controller.cpp | 11 ++-- src/controller.h | 2 +- src/mainwindow.cpp | 95 +++++++++++++++++++++++++- src/mainwindow.h | 4 +- src/mainwindow.ui | 59 ++++++++++------- 7 files changed, 355 insertions(+), 88 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c6dd75d..7ca3090 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -10,6 +10,7 @@ #include #include #include +#include using namespace std; using namespace boost; @@ -80,11 +81,11 @@ void ChatModel::showMessages() { for(auto &c : this->chatItems) { - qDebug() << "[" << c.second.getTimestamp() << "] " << "<" << c.second.getAddress() << "> :" << c.second.getMemo(); + qDebug() << c.second.toChatLine(); } } -void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget &view) +void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView &view) { /*for(auto &c : this->chatItems) { @@ -94,66 +95,68 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget &view) //todo render items to view } -void ChatModel::renderChatBox(Ui::MainWindow* ui, QListWidget *view) +void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { - - while(view->count() > 0) + // QStandardItemModel mymodel; + // QStandardItem* Items = new QStandardItem(myString); + QStandardItemModel* myModel = new QStandardItemModel(); + for(auto &c : this->chatItems) { - view->takeItem(0); - } - - QString line = ""; - - for(auto &c : this->chatItems){ - - QDateTime myDateTime; - - myDateTime.setTime_t(c.second.getTimestamp()); - //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid /// - if ((ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)) { - // if (c.second.getMemo.find()) - line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString("<") + QString("Outgoing") + QString("> :\n"); - line += QString(c.second.getMemo()) + QString("\n"); - view->addItem(line); - line =""; - - - ////////////////////////////////// Todo : Render green checkmark for contacts if cid = cid - We have to search for cid in txid/cid list - // QString cid = c.second.getCid(); - - } - - if ((ui->MyZaddr->text().trimmed() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false)){ - for(auto &p : AddressBook::getInstance()->getAllAddressLabels()){ - - if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) - { - - - }else{ - - // line+= QString("[") + "Warning. Not verified!" + QString("]"); - - - line += QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString("<") + QString("incoming") + QString("> :\n"); - line += QString(c.second.getMemo()) + QString("\n"); - view->addItem(line); - line =""; - } - + if ( + (ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && + (c.second.getMemo().startsWith("{") == false) && + (c.second.getMemo().isEmpty() == false) + ) + { + QStandardItem* Items = new QStandardItem(c.second.toChatLine()); + Items->setData("Incoming", Qt::UserRole +1); + myModel->appendRow(Items); + qDebug()<text(); + ui->listChat->setModel(myModel); + ui->listChat->setMinimumSize(200,350); + ui->listChat->setItemDelegate(new ListViewDelegate()); + ui->listChat->show(); } + + if ( + (ui->MyZaddr->text().trimmed() == c.second.getAddress()) && + (c.second.getMemo().startsWith("{") == false) && + (c.second.getMemo().isEmpty() == false) + + ) + { + + QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); + Items1->setData("Outgoing", Qt::UserRole +1); + myModel->appendRow(Items1); + qDebug()<text(); + } + ui->listChat->setModel(myModel); + ui->listChat->setMinimumSize(200,350); + ui->listChat->setItemDelegate(new ListViewDelegate()); + ui->listChat->show(); } + + + /////////////////////////Render only when CID=CID? + + // for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + // { - } - + // if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) + // { + + + //} + // + + } @@ -247,6 +250,9 @@ Tx MainWindow::createTxFromChatPage() { } void MainWindow::sendChatButton() { + + + ////////////////////////////Todo: Check if a Contact is selected////////// // Create a Tx from the values on the send tab. Note that this Tx object @@ -420,6 +426,9 @@ Tx MainWindow::createTxForSafeContactRequest() { //////////////////De-activated for now/////////////////// void MainWindow::safeContactRequest() { + + + ////////////////////////////Todo: Check if its a zaddr////////// // Create a Tx from the values on the send tab. Note that this Tx object diff --git a/src/chatmodel.h b/src/chatmodel.h index fcc68bf..a060530 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -1,15 +1,161 @@ #ifndef CHATMODEL_H #define CHATMODEL_H #include +#include +#include +#include #include #include -#include +#include #include "precompiled.h" #include "mainwindow.h" #include "controller.h" #include "settings.h" #include "camount.h" +class ListViewDelegate : public QAbstractItemDelegate +{ + int d_radius; + int d_toppadding; + int d_bottompadding; + int d_leftpadding; + int d_rightpadding; + int d_verticalmargin; + int d_horizontalmargin; + int d_pointerwidth; + int d_pointerheight; + float d_widthfraction; + public: + inline ListViewDelegate(QObject *parent = nullptr); + + protected: + inline void paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const; + inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; +}; + +inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(15), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) +{ + +} + +inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + QTextDocument bodydoc; + QTextOption textOption(bodydoc.defaultTextOption()); + textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + bodydoc.setDefaultTextOption(textOption); + bodydoc.setDefaultFont(QFont("Roboto", 12)); + QString bodytext(index.data(Qt::DisplayRole).toString()); + bodydoc.setHtml(bodytext); + qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; + bodydoc.setTextWidth(contentswidth); + qreal bodyheight = bodydoc.size().height(); + bool outgoing = index.data(Qt::UserRole + 1).toString() == "Outgoing"; + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + // uncomment to see the area provided to paint this item + + //painter->drawRect(option.rect); + + painter->translate(option.rect.left() + d_horizontalmargin, option.rect.top() + ((index.row() == 0) ? d_verticalmargin : 0)); + + // background color for chat bubble + QColor bgcolor("fbffff"); + if (outgoing) + bgcolor = "#fffcfb"; + + // create chat bubble + QPainterPath pointie; + + // left bottom + pointie.moveTo(0, bodyheight + d_toppadding + d_bottompadding); + + // right bottom + pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - d_radius, + bodyheight + d_toppadding + d_bottompadding); + pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, + bodyheight + d_toppadding + d_bottompadding - 2 * d_radius, + 2 * d_radius, 2 * d_radius, 270, 90); + + // right top + pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding, 0 + d_radius); + pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, 0, + 2 * d_radius, 2 * d_radius, 0, 90); + + // left top + pointie.lineTo(0 + d_pointerwidth + d_radius, 0); + pointie.arcTo(0 + d_pointerwidth, 0, 2 * d_radius, 2 * d_radius, 90, 90); + + // left bottom almost (here is the pointie) + pointie.lineTo(0 + d_pointerwidth, bodyheight + d_toppadding + d_bottompadding - d_pointerheight); + pointie.closeSubpath(); + + // rotate bubble for outgoing messages + if (outgoing) + { + painter->translate(option.rect.width() - pointie.boundingRect().width() - d_horizontalmargin - d_pointerwidth, 0); + painter->translate(pointie.boundingRect().center()); + painter->rotate(180); + painter->translate(-pointie.boundingRect().center()); + } + + // now paint it! + painter->setPen(QPen(bgcolor)); + painter->drawPath(pointie); + painter->fillPath(pointie, QBrush(bgcolor)); + + // rotate back or painter is going to paint the text rotated... + if (outgoing) + { + painter->translate(pointie.boundingRect().center()); + painter->rotate(-180); + painter->translate(-pointie.boundingRect().center()); + } + + // set text color used to draw message body + QAbstractTextDocumentLayout::PaintContext ctx; + if (outgoing) + ctx.palette.setColor(QPalette::Text, QColor("black")); + else + ctx.palette.setColor(QPalette::Text, QColor("white")); + + // draw body text + painter->translate((outgoing ? 0 : d_pointerwidth) + d_leftpadding, 0); + bodydoc.documentLayout()->draw(painter, ctx); + + painter->restore(); +} + +inline QSize ListViewDelegate::sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + QTextDocument bodydoc; + QTextOption textOption(bodydoc.defaultTextOption()); + textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + bodydoc.setDefaultTextOption(textOption); + bodydoc.setDefaultFont(QFont("Roboto", 12)); + QString bodytext(index.data(Qt::DisplayRole).toString()); + bodydoc.setHtml(bodytext); + + // the width of the contents are the (a fraction of the window width) minus (margins + padding + width of the bubble's tail) + qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; + + // set this available width on the text document + bodydoc.setTextWidth(contentswidth); + + QSize size(bodydoc.idealWidth() + d_horizontalmargin + d_pointerwidth + d_leftpadding + d_rightpadding, + bodydoc.size().height() + d_bottompadding + d_toppadding + d_verticalmargin + 1); // I dont remember why +1, haha, might not be necessary + + if (index.row() == 0) // have extra margin at top of first item + size += QSize(0, d_verticalmargin); + + return size; +} + + + + + class ChatItem { private: @@ -117,6 +263,15 @@ class ChatItem _outgoing = true; } + QString toChatLine() + { + QDateTime myDateTime; + myDateTime.setTime_t(_timestamp); + QString line = QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); + line += QString(_memo) + QString("\n"); + return line; + } + ~ChatItem() { /*delete timestamp; @@ -145,8 +300,8 @@ class ChatModel void setItems(std::map items); QString zaddr(); void setItems(std::vector items); - void renderChatBox(Ui::MainWindow* ui, QListWidget &view); - void renderChatBox(Ui::MainWindow* ui, QListWidget *view); + void renderChatBox(Ui::MainWindow* ui, QListView &view); + void renderChatBox(Ui::MainWindow* ui, QListView *view); void showMessages(); void clear(); void addMessage(ChatItem item); diff --git a/src/controller.cpp b/src/controller.cpp index 2fe9b52..50db859 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -893,8 +893,8 @@ void Controller::refreshTransactions() { QString(""), memo, cid, // we have to set the cid here, its included in our Addressbook for this contact - txid - // true // is an outgoing message + txid, + true // is an outgoing message ); chatModel->addMessage(item); } @@ -964,7 +964,8 @@ void Controller::refreshTransactions() { QString(""), memo, cid, // we have to set the cid here, its included in the headermemo - txid + txid, + false ); // qDebug()<< "Message CID: " << cid; chatModel->addMessage(item); @@ -990,7 +991,7 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); - chatModel->renderChatBox(ui, ui->listChatMemo); + chatModel->renderChatBox(ui, ui->listChat); refreshContacts( ui->listContactWidget @@ -998,7 +999,7 @@ void Controller::refreshTransactions() { }); } -void Controller::refreshChat(QListWidget *listWidget) +void Controller::refreshChat(QListView *listWidget) { chatModel->renderChatBox(ui, listWidget); diff --git a/src/controller.h b/src/controller.h index 4a0835f..59cfa40 100644 --- a/src/controller.h +++ b/src/controller.h @@ -72,7 +72,7 @@ public: void refreshGBPCAP(); void refreshAUDCAP(); - void refreshChat(QListWidget *listWidget); + void refreshChat(QListView *listWidget); void refreshContacts(QListWidget *listWidget); void executeStandardUITransaction(Tx tx); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f17bfc9..254798f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -993,6 +993,92 @@ void MainWindow::setupchatTab() { ///////// Set selected Zaddr for Chat with Doubleklick QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { + + QStandardItemModel mymodel; + + // for(auto &c : this->chatItems) + //{ + //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid + + /// + // if ( + // (ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && + // (c.second.getMemo().startsWith("{") == false) && + // (c.second.getMemo().isEmpty() == false) + // ) + // { + // if (c.second.getMemo.find()) + + //view->addItem(line); + + // QStandardItem *item1 = new QStandardItem(c.second.toChatLine()); + // item1->setData("Incoming", Qt::UserRole + 1); + // model.appendRow(item1); + + QStandardItem *item1 = new QStandardItem("Kacke Hier"); + item1->setData("Incoming", Qt::UserRole +1); + mymodel.appendRow(item1); + qDebug()<text(); + + + QStandardItem *item2 = new QStandardItem("This is item one"); + item2->setData("Outgoing", Qt::UserRole +1); + mymodel.appendRow(item2); + qDebug()<text(); + + QStandardItem *item3 = new QStandardItem("This is item one"); + item3->setData("Outgoing", Qt::UserRole +1); + mymodel.appendRow(item3); + qDebug()<text(); + + // QStandardItem *item2 = new QStandardItem("Hallo"); + // item1->setData("Outgoing", Qt::UserRole + 1); + // mymodel.appendRow(item2); + // qDebug()<text(); + + ////////////////////////////////// Todo : Render green checkmark for contacts if cid = cid - We have to search for cid in txid/cid list + // QString cid = c.second.getCid(); + + // } + + // if ( + // (ui->MyZaddr->text().trimmed() == c.second.getAddress()) && + // (c.second.getMemo().startsWith("{") == false) && + // (c.second.getMemo().isEmpty() == false) + // ) + // { + + + // for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + // { + + // if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) + // { + + + //} + // else + // { + // line+= QString("[") + "Warning. Not verified!" + QString("]"); + // QStandardItem *item = new QStandardItem(c.second.toChatLine()); + //view->addItem(line); + // model.appendRow(item); + // } + +// } + + //} + + // } + + + + + ui->listChat->setModel(&mymodel); + ui->listChat->setItemDelegate(new ListViewDelegate()); + ui->listChat->show(); + //ui->listChat->update(); + QModelIndex index = ui->listContactWidget->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); @@ -1005,8 +1091,12 @@ void MainWindow::setupchatTab() { ui->contactCid->setText(p.getCid()); rpc->refresh(true); + updateChat(); } }); + + + } ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { @@ -1052,12 +1142,13 @@ void ChatMemoEdit::setSendChatButton(QPushButton* button) { void MainWindow::updateChat() { - rpc->refreshChat(ui->listChatMemo); + rpc->refreshChat(ui->listChat); + rpc->refresh(true); + } void MainWindow::updateContacts() { - qDebug() << "Called MainWindow::updateContacts()"; rpc->refreshContacts(ui->listContactWidget); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 7114eda..1110f67 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -54,6 +54,7 @@ public: bool isWebsocketListening(); void createWebsocket(QString wormholecode); void stopWebsocket(); + void balancesReady(); void payhushURI(QString uri = "", QString myAddr = ""); @@ -92,8 +93,9 @@ private: void setupBalancesTab(); void setuphushdTab(); void setupchatTab(); - void updateChat(); + void updateContacts(); + void updateChat(); void setupSettingsModal(); void setupStatusBar(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 3196dff..fb02214 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1390,31 +1390,6 @@ <html><head/><body><p align="center"><br/></p></body></html> - - - true - - - - 340 - 40 - 921 - 371 - - - - QAbstractItemView::NoEditTriggers - - - false - - - Qt::IgnoreAction - - - QAbstractItemView::NoSelection - - @@ -1563,6 +1538,40 @@ <html><head/><body><p align="center">Contact Name:</p></body></html> + + + + 340 + 40 + 921 + 371 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + QListView::Adjust + + + 0 + + + false + + + true + + From 58bee815a54909be19a6bbb14ce7b1bd179240a2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 01:25:56 +0200 Subject: [PATCH 051/253] change color in chat --- src/chatmodel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatmodel.h b/src/chatmodel.h index a060530..b4caa95 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -61,9 +61,9 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons painter->translate(option.rect.left() + d_horizontalmargin, option.rect.top() + ((index.row() == 0) ? d_verticalmargin : 0)); // background color for chat bubble - QColor bgcolor("fbffff"); + QColor bgcolor("#535353"); if (outgoing) - bgcolor = "#fffcfb"; + bgcolor = "#eeeeee"; // create chat bubble QPainterPath pointie; From 7b40755d42582e82a80bd2aa9c15bce2e0509758 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 11:35:05 +0200 Subject: [PATCH 052/253] improve some UI elements --- src/chatmodel.cpp | 73 +++++++++++++------------- src/controller.cpp | 44 ++++++++++++---- src/mainwindow.cpp | 101 ++++------------------------------- src/mainwindow.ui | 128 +++++++++------------------------------------ 4 files changed, 105 insertions(+), 241 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 7ca3090..7b656f7 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -97,21 +97,39 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView &view) void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { - // QStandardItemModel mymodel; - // QStandardItem* Items = new QStandardItem(myString); - QStandardItemModel* myModel = new QStandardItemModel(); - for(auto &c : this->chatItems) + + + QStandardItemModel* myModel = new QStandardItemModel(); + + + for (auto &c : this->chatItems) + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { + + + //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid - /// if ( - (ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && - (c.second.getMemo().startsWith("{") == false) && - (c.second.getMemo().isEmpty() == false) + (ui->contactNameMemo->text().trimmed() == c.second.getContact()) && + (c.second.getMemo().startsWith("{") == false) && + (c.second.getMemo().isEmpty() == false) && + (p.getPartnerAddress() == c.second.getAddress()) + ) - { + { + // for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) + + + // { + // if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) + + // { + + // } + + QStandardItem* Items = new QStandardItem(c.second.toChatLine()); Items->setData("Incoming", Qt::UserRole +1); myModel->appendRow(Items); @@ -120,14 +138,14 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->show(); - } - - + } + if ( - (ui->MyZaddr->text().trimmed() == c.second.getAddress()) && + (ui->contactNameMemo->text().trimmed() == c.second.getContact()) && (c.second.getMemo().startsWith("{") == false) && - (c.second.getMemo().isEmpty() == false) + (c.second.getMemo().isEmpty() == false) && + (p.getMyAddress() == c.second.getAddress()) ) { @@ -141,22 +159,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->show(); - } - - - /////////////////////////Render only when CID=CID? - - // for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) - // { - // if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) - // { - - - //} - // - - + } + } @@ -223,7 +228,7 @@ Tx MainWindow::createTxFromChatPage() { for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (ui->ContactZaddr->text().trimmed() == c.getPartnerAddress()) { + if (ui->contactNameMemo->text().trimmed() == c.getName()) { QString cid = c.getCid(); QString myAddr = c.getMyAddress(); @@ -233,6 +238,7 @@ Tx MainWindow::createTxFromChatPage() { QString hmemo= createHeaderMemo(type,cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); + // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; @@ -261,7 +267,7 @@ void MainWindow::sendChatButton() { // Memos can only be used with zAddrs. So check that first // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (ui->ContactZaddr->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { + if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { // auto addr = ""; // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { @@ -397,7 +403,7 @@ Tx MainWindow::createTxForSafeContactRequest() { for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (ui->ContactZaddr->text().trimmed() == c.getName()) { + if (ui->contactNameMemo->text().trimmed() == c.getName()) { // QString cid = c.getCid(); // This has to be a new cid for the contact // QString myAddr = c.getMyAddress(); // this should be a new HushChat zaddr @@ -426,9 +432,6 @@ Tx MainWindow::createTxForSafeContactRequest() { //////////////////De-activated for now/////////////////// void MainWindow::safeContactRequest() { - - - ////////////////////////////Todo: Check if its a zaddr////////// // Create a Tx from the values on the send tab. Note that this Tx object diff --git a/src/controller.cpp b/src/controller.cpp index 50db859..7db0ff0 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -881,24 +881,34 @@ void Controller::refreshTransactions() { memo = QString::fromStdString(o["memo"]); QString cid; + QString contact; + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if ((ui->ContactZaddr->text().trimmed() == c.getPartnerAddress()) || (ui->MyZaddr->text().trimmed() == c.getMyAddress())) { + { + if (ui->contactNameMemo->text().trimmed() == c.getName()) { cid = c.getCid(); - }else {cid = "";} + }else {cid = "";} + + if (address == c.getPartnerAddress()){ + contact = c.getName(); + }else{ contact = "";} + ChatItem item = ChatItem( datetime, address, - QString(""), + contact, memo, cid, // we have to set the cid here, its included in our Addressbook for this contact txid, true // is an outgoing message ); chatModel->addMessage(item); - } - + + } + + } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -912,7 +922,6 @@ void Controller::refreshTransactions() { }else{ - addresses.push_back(item.address); } } @@ -957,19 +966,34 @@ void Controller::refreshTransactions() { else cid = ""; } - + + QString contact; + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + // for (auto &p : this->chatItems) + { + + if (address == c.getMyAddress()){ + contact = c.getName(); + qDebug()<< "Addressbuch Addresse: " << c.getMyAddress(); + qDebug()<< "Addresse: " << address; + + }else{ contact = "ELSE";} + ChatItem item = ChatItem( datetime, address, - QString(""), + contact, memo, cid, // we have to set the cid here, its included in the headermemo txid, false ); - // qDebug()<< "Message CID: " << cid; - chatModel->addMessage(item); + // qDebug()<< "KontaktName: " << contact; + + // qDebug()<< "Addressbuch Addresse: " << c.getMyAddress(); + chatModel->addMessage(item); +} } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 254798f..0d1e984 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -39,8 +39,12 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); - ui->checkBox->setChecked(true); + // ui->checkBox->setChecked(true); logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); + ui->memoTxtChat->setAutoFillBackground(false); + // ui->memoTxtChat->setStyleSheet(QString::fromUtf8("background-color: rgb(224, 224, 224);")); + ui->memoTxtChat->setPlaceholderText("Send Message"); + ui->memoTxtChat->setTextColor(Qt::white); // Status Bar setupStatusBar(); @@ -994,109 +998,22 @@ void MainWindow::setupchatTab() { QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { - QStandardItemModel mymodel; - - // for(auto &c : this->chatItems) - //{ - //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid - - /// - // if ( - // (ui->ContactZaddr->text().trimmed() == c.second.getAddress()) && - // (c.second.getMemo().startsWith("{") == false) && - // (c.second.getMemo().isEmpty() == false) - // ) - // { - // if (c.second.getMemo.find()) - - //view->addItem(line); - - // QStandardItem *item1 = new QStandardItem(c.second.toChatLine()); - // item1->setData("Incoming", Qt::UserRole + 1); - // model.appendRow(item1); - - QStandardItem *item1 = new QStandardItem("Kacke Hier"); - item1->setData("Incoming", Qt::UserRole +1); - mymodel.appendRow(item1); - qDebug()<text(); - - - QStandardItem *item2 = new QStandardItem("This is item one"); - item2->setData("Outgoing", Qt::UserRole +1); - mymodel.appendRow(item2); - qDebug()<text(); - - QStandardItem *item3 = new QStandardItem("This is item one"); - item3->setData("Outgoing", Qt::UserRole +1); - mymodel.appendRow(item3); - qDebug()<text(); - - // QStandardItem *item2 = new QStandardItem("Hallo"); - // item1->setData("Outgoing", Qt::UserRole + 1); - // mymodel.appendRow(item2); - // qDebug()<text(); - - ////////////////////////////////// Todo : Render green checkmark for contacts if cid = cid - We have to search for cid in txid/cid list - // QString cid = c.second.getCid(); - - // } - - // if ( - // (ui->MyZaddr->text().trimmed() == c.second.getAddress()) && - // (c.second.getMemo().startsWith("{") == false) && - // (c.second.getMemo().isEmpty() == false) - // ) - // { - - - // for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) - // { - - // if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) - // { - - - //} - // else - // { - // line+= QString("[") + "Warning. Not verified!" + QString("]"); - // QStandardItem *item = new QStandardItem(c.second.toChatLine()); - //view->addItem(line); - // model.appendRow(item); - // } - -// } - - //} - - // } - - - - - ui->listChat->setModel(&mymodel); - ui->listChat->setItemDelegate(new ListViewDelegate()); - ui->listChat->show(); - //ui->listChat->update(); - QModelIndex index = ui->listContactWidget->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) if (label_contact == p.getName()) { - ui->ContactZaddr->setText(p.getPartnerAddress()); - ui->MyZaddr->setText(p.getMyAddress()); + // ui->ContactZaddr->setText(p.getPartnerAddress()); + // ui->MyZaddr->setText(p.getMyAddress()); ui->contactNameMemo->setText(p.getName()); - ui->contactCid->setText(p.getCid()); + ui->memoTxtChat->clear(); rpc->refresh(true); - updateChat(); + // updateChat(); } }); - - } ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { diff --git a/src/mainwindow.ui b/src/mainwindow.ui index fb02214..0c6d66b 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1351,21 +1351,24 @@ <html><head/><body><p align="center">Hushchat Contactlist</p></body></html> - + 340 - 410 + 460 921 - 128 + 131 + + font: 11pt "Noto Color Emoji"; + - 1200 - 540 + 1190 + 610 47 17 @@ -1393,8 +1396,8 @@ - 1130 - 590 + 710 + 610 114 25 @@ -1412,45 +1415,6 @@ false - - - - 350 - 550 - 81 - 17 - - - - Send To : - - - - - - 350 - 580 - 81 - 17 - - - - <html><head/><body><p>My zaddr :</p></body></html> - - - - - - 420 - 550 - 691 - 20 - - - - - - @@ -1473,58 +1437,6 @@ false - - - - 420 - 580 - 691 - 20 - - - - - - - - - - 720 - 20 - 331 - 20 - - - - <html><head/><body><p align="center"><br/></p></body></html> - - - - - - 590 - 20 - 131 - 20 - - - - <html><head/><body><p align="center">Conversation ID:</p></body></html> - - - - - - 980 - 0 - 271 - 23 - - - - Render only authenticated messages - - @@ -1544,7 +1456,7 @@ 340 40 921 - 371 + 421 @@ -1572,6 +1484,19 @@ true + + + + 340 + 430 + 911 + 31 + + + + Qt::Horizontal + + @@ -1743,11 +1668,6 @@ - - MemoEdit - QPlainTextEdit -
memoedit.h
-
AddressCombo QComboBox From dc4c386f3845142daf50efefdbe1aa43a2eb3aa3 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 12:10:51 +0200 Subject: [PATCH 053/253] change datetime format in chatmodel --- src/chatmodel.cpp | 35 ++++++++++++++++++----------------- src/chatmodel.h | 5 +++-- src/mainwindow.ui | 13 ------------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 7b656f7..c139c03 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -117,27 +117,22 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) (p.getPartnerAddress() == c.second.getAddress()) ) - { - - // for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) - - - // { - // if ((ui->checkBox->isChecked() == true) && (p.getCid() != c.second.getCid())) - - // { - - // } - + { QStandardItem* Items = new QStandardItem(c.second.toChatLine()); Items->setData("Incoming", Qt::UserRole +1); myModel->appendRow(Items); - qDebug()<text(); - ui->listChat->setModel(myModel); - ui->listChat->setMinimumSize(200,350); - ui->listChat->setItemDelegate(new ListViewDelegate()); - ui->listChat->show(); + + + ui->listChat->setResizeMode(QListView::Adjust); + ui->listChat->setWordWrap(true); + ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listChat->setModel(myModel); + ui->listChat->setMinimumSize(200,350); + ui->listChat->setItemDelegate(new ListViewDelegate()); + ui->listChat->show(); } @@ -155,6 +150,12 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) myModel->appendRow(Items1); qDebug()<text(); } + + ui->listChat->setResizeMode(QListView::Adjust); + ui->listChat->setWordWrap(true); + ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listChat->setModel(myModel); ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); diff --git a/src/chatmodel.h b/src/chatmodel.h index b4caa95..490f336 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -13,6 +13,7 @@ #include "settings.h" #include "camount.h" + class ListViewDelegate : public QAbstractItemDelegate { int d_radius; @@ -267,8 +268,8 @@ class ChatItem { QDateTime myDateTime; myDateTime.setTime_t(_timestamp); - QString line = QString("[") + myDateTime.toString("dd.MM.yyyy hh:mm:ss ") + QString("] "); - line += QString(_memo) + QString("\n"); + QString line = QString("[") + myDateTime.toString("d.M.yy hh:mm") + QString("] ") ; + line += QString("") + QString(_memo) + QString("\n\n"); return line; } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 0c6d66b..56b180b 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1484,19 +1484,6 @@ true - - - - 340 - 430 - 911 - 31 - - - - Qt::Horizontal - - From 765bedde8076fde7870c37286b18968137dc20c6 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 12:36:18 +0200 Subject: [PATCH 054/253] add watermark to chatlist --- src/chatmodel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c139c03..679b0c5 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -132,6 +132,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setModel(myModel); ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); + // ui->listChat->setStyleSheet("background-image: url(res/hushdark.png)"); /////Todo set an png as Watermark backgroung in listChat ui->listChat->show(); } From c8b274ecfe195a1c7d6da448e76224753de63d57 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 13:28:41 +0200 Subject: [PATCH 055/253] switch to listview for contacts --- src/chatmodel.cpp | 10 +++++----- src/contactmodel.cpp | 25 +++++++++++++++++++------ src/contactmodel.h | 2 +- src/controller.cpp | 2 +- src/controller.h | 2 +- src/mainwindow.ui | 2 +- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 679b0c5..aad9a8d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -99,7 +99,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { - QStandardItemModel* myModel = new QStandardItemModel(); + QStandardItemModel* chat = new QStandardItemModel(); for (auto &c : this->chatItems) @@ -121,7 +121,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) QStandardItem* Items = new QStandardItem(c.second.toChatLine()); Items->setData("Incoming", Qt::UserRole +1); - myModel->appendRow(Items); + chat->appendRow(Items); ui->listChat->setResizeMode(QListView::Adjust); @@ -129,7 +129,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->listChat->setModel(myModel); + ui->listChat->setModel(chat); ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); // ui->listChat->setStyleSheet("background-image: url(res/hushdark.png)"); /////Todo set an png as Watermark backgroung in listChat @@ -148,7 +148,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); Items1->setData("Outgoing", Qt::UserRole +1); - myModel->appendRow(Items1); + chat->appendRow(Items1); qDebug()<text(); } @@ -157,7 +157,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->listChat->setModel(myModel); + ui->listChat->setModel(chat); ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->show(); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 0e9a6ea..e4d32e1 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -2,15 +2,28 @@ #include "addressbook.h" #include "mainwindow.h" -void ContactModel::renderContactList(QListWidget* view) +void ContactModel::renderContactList(QListView* view) { - while(view->count() > 0) - { - view->takeItem(0); - } + QStandardItemModel* contact = new QStandardItemModel(); + //} for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - view->addItem(c.getName()); + // view->addItem(c.getName()); + + + QStandardItem* Items = new QStandardItem(c.getName()); + contact->appendRow(Items); + // view->setItemDelegate({text: contact}) + // width: view->width }) + // height: avatar.implicitHeight, + // leftPadding: avatar.implicitWidth + 32}) + + // Image { + // id: avatar + // source: "qrc:/" + modelData.replace(" ", "_") + ".png" + // } + //} + view->setModel(contact); } diff --git a/src/contactmodel.h b/src/contactmodel.h index 886b285..b97cc8a 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -74,7 +74,7 @@ class ContactModel { public: ContactModel() {} - void renderContactList(QListWidget* view); + void renderContactList(QListView* view); }; #endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 7db0ff0..577d438 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1029,7 +1029,7 @@ void Controller::refreshChat(QListView *listWidget) } -void Controller::refreshContacts(QListWidget *listWidget) +void Controller::refreshContacts(QListView *listWidget) { contactModel->renderContactList(listWidget); } diff --git a/src/controller.h b/src/controller.h index 59cfa40..bc56587 100644 --- a/src/controller.h +++ b/src/controller.h @@ -73,7 +73,7 @@ public: void refreshAUDCAP(); void refreshChat(QListView *listWidget); - void refreshContacts(QListWidget *listWidget); + void refreshContacts(QListView *listWidget); void executeStandardUITransaction(Tx tx); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 56b180b..e58e4ad 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1328,7 +1328,7 @@ HushChat - + 0 From 0e2c8503fef816cbf6afd0264bd6d0e429b4ec57 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 17:22:16 +0200 Subject: [PATCH 056/253] add new background images to chatlist --- application.qrc | 3 +++ src/chatmodel.cpp | 21 +++------------------ src/contactmodel.cpp | 24 +++++++++--------------- src/mainwindow.cpp | 15 ++++++++++++++- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/application.qrc b/application.qrc index 0507184..e4cd3d2 100644 --- a/application.qrc +++ b/application.qrc @@ -8,6 +8,9 @@ res/paymentreq.gif res/icon.ico res/mail.png + res/darkwing.png + res/sdlogo.png + res/sdlogo2.png res/hushdlogo.gif diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index aad9a8d..68b496a 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -123,17 +123,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) Items->setData("Incoming", Qt::UserRole +1); chat->appendRow(Items); - - ui->listChat->setResizeMode(QListView::Adjust); - ui->listChat->setWordWrap(true); - ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->listChat->setModel(chat); - ui->listChat->setMinimumSize(200,350); + ui->listChat->setModel(chat); ui->listChat->setItemDelegate(new ListViewDelegate()); - // ui->listChat->setStyleSheet("background-image: url(res/hushdark.png)"); /////Todo set an png as Watermark backgroung in listChat - ui->listChat->show(); + } @@ -149,18 +141,11 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); Items1->setData("Outgoing", Qt::UserRole +1); chat->appendRow(Items1); - qDebug()<text(); } - ui->listChat->setResizeMode(QListView::Adjust); - ui->listChat->setWordWrap(true); - ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listChat->setModel(chat); - ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); - ui->listChat->show(); + } diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index e4d32e1..a19fe1c 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -3,27 +3,21 @@ #include "mainwindow.h" void ContactModel::renderContactList(QListView* view) -{ +{ // QStandardItem(const QIcon & icon, const QString & text) QStandardItemModel* contact = new QStandardItemModel(); //} for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - // view->addItem(c.getName()); - - QStandardItem* Items = new QStandardItem(c.getName()); - contact->appendRow(Items); - // view->setItemDelegate({text: contact}) - // width: view->width }) - // height: avatar.implicitHeight, - // leftPadding: avatar.implicitWidth + 32}) - - // Image { - // id: avatar - // source: "qrc:/" + modelData.replace(" ", "_") + ".png" - // } - //} + //QStandardItem* Items = new QStandardItem(); + QStandardItem* Items1 = new QStandardItem(QIcon("res/darkwing.png"),c.getName()); + // contact->appendRow(Items); + contact->appendRow(Items1); view->setModel(contact); + view->setIconSize(QSize(80,100)); + view->setUniformItemSizes(true); + view->setDragDropMode(QAbstractItemView::DropOnly);; + } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0d1e984..0104f56 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -905,6 +905,17 @@ void MainWindow::setupTransactionsTab() { }); // Set up context menu on transactions tab + auto theme = Settings::getInstance()->get_theme_name(); + if (theme == "dark"){ + ui->listChat->setStyleSheet("background-image: url(res/sdlogo.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover"); + }else{ui->listChat->setStyleSheet("background-image: url(res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} + ui->listChat->setResizeMode(QListView::Adjust); + ui->listChat->setWordWrap(true); + ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listChat->setMinimumSize(200,350); + ui->listChat->show(); ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu); // Table right click QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) { @@ -1014,6 +1025,8 @@ void MainWindow::setupchatTab() { } }); + + } ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { @@ -1066,7 +1079,7 @@ void MainWindow::updateChat() void MainWindow::updateContacts() { - rpc->refreshContacts(ui->listContactWidget); + //rpc->refreshContacts(ui->listContactWidget); } void MainWindow::addNewZaddr(bool sapling) { From 5a563f169d85376b64b67ce571df284fed200520 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 17:45:44 +0200 Subject: [PATCH 057/253] set background for themes --- res/darkwing.png | Bin 0 -> 178122 bytes res/hushdark.png | Bin 0 -> 50336 bytes res/sdlogo.png | Bin 0 -> 43333 bytes res/sdlogo2.png | Bin 0 -> 59377 bytes src/mainwindow.cpp | 7 +++++-- 5 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 res/darkwing.png create mode 100644 res/hushdark.png create mode 100644 res/sdlogo.png create mode 100644 res/sdlogo2.png diff --git a/res/darkwing.png b/res/darkwing.png new file mode 100644 index 0000000000000000000000000000000000000000..6fbe04611b0b546bb3eea55fda99c68a8a7a95dc GIT binary patch literal 178122 zcmV)AK*Ya^P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy24YJ`L;(K){{a7>y{D4^000SaNLh0L01m?d01m?e$8V@)004jh zNklx!`S~ytn76*A(}15ntuc z*Z-NPzK3~si0s*6^K2;sRHM)+1*KGUKWlrx60`aF!gZ@(UrL@0d2giG3&r#8uAO-n z%AcFT^5u^G72hjdJSOvff`6zcUTe(&YlaqU84-a%(WzCW?E2@ILu2mw=rt*Oy8U%j;uzh1&8)MxC$|RK&lX)vaWmSTMqIP< zb0I$igYD~+KVBlr_bCpaC;Ys5J`-ktxRLyBQr8q7fTZiUa!g zm(n@t!zwBMkoN}sI+Xujn}W&GW-k9K{#h0qceq)|-&i!bDVc?p!fjCkOFclXblkO* zM-x#*yim)Viv0JdgIn{kl>mi!QxqLM5}?_^6|*x%Kd}HEx>#-6%cEVj-TBBQ~(z7 zIgN{q3>?7VZc6S|f9~ymPy%fRB)o+NA~c~Z%4{BEc6g}8lh z9o9k;=Y=^!)hk?k8ns6NJP3G8;I{wyNUsr(J397vdjQJ4g>Co@{@4iuOHg%{b3hkl z-%*Fc#Qhz!wxHG#Fb0T~*H1?TX%IEgS_z=fRr1V#KiL!Ghn2*-iG-9%i!*r*bm7ua z;U37ZN(>V7{|0n8b$F&$i3OehRD658%eV&X|X>Scy{(o=V`hem@qfaQ=M&xkKk+B+!?| zYpvq)d*ZkbPW+$oW|ITkq2nCSR;R2>9q@7yxa1#StW)mu%MF%RtidEmQ~8D$Sli)y zvUtDi^t=*?xOj-s^HIEx4&B)GW)-j){a$=M2?Qn!g#DVBTuWwOU~qc>*>95UEQ#x$ zt}pWMqJj&KJW#9eA%)|X+Y^JK-64zhota19KA}@7z>?+)@aE)s! z86LeRhv$s4PG|gladCZ=YxNXRJJ^-r;}TF`0Ko0r+U2H=g;uFlT^Sw5J0gIDQc;PdcaUZly2@ge>I{no}CV-k);) z;yRN$rU*LG&y4^MDV23qfGuIddc%F6lThm7_`=gll9VF{32y!8Mgrv6qvA$M$;yO#Nfbos{xbd<&(EclJM>;thk-1pXRfij4)Es%N1rs{ zIQ#Kf8R-|z;xV z1qBw7%8ahuEaiDjuX~C0H@9=?x(weVLw{G7ZB(vZ(x4f-_u^t}0)tHU>;|-&9|Ffr zIVsa&GeDQUq)f?8Qm}rp7LX!cqSVYfFjd-gQ`XVTBxI3Axy*{9^GC(&4OGAdr}|I_ zak;{@BBuSh{w#QK>kETvtbbsTk=^J15X5sc3DEPnZbbx&#LmuMXPXpFmH=T?Iu7E- z3v6qyZB2_cB1@KN18j{>mc0al*=Wb*aVS!taF+&#G|`(zr$>f)IG#<(r3zfwCm{-p;W?)MS(IVG%N6|adjW9!IzUM$31Gt* znwygBA2v6kt!}921L_ectCzV&F0kgl&8%?p$*$B4p*iM68`N`>(hFK+bys1!`!{5Q zb~-i=!(y`HE54sQUeRtdr-0C-pcnw?+Jjubps}gk?McQ8(@K6(jEa=eOzjZ(E&p6i zGb_o2p+YD=US4srpiEPB0vt~-gWC^uYn%B5EpkPl@2_#v?oHeH!yuOiuKzed(%;DK zc?}*eP;+3zNvSVC`v``JYsZtoBt@Byn2Jn%T)itHW03W6im3bKX1=Yi9EKz>)-QfM zF-wr@aIoOfT`TB^tmcvHqqYG#Wev>zgi_A)>W%?a!vx)^<= z2WOBbS)-E+mKKkFjn_Vj)=7Z88gm}rmj-c1`QndVvyb0h=sOQ%JMSk8aL2YnSc8c} zOWfU@2yFp5sZRrJ-AW%uPG$xwxF6(ZRcyR4$Qzo`rxhLB-oYftg;D2$0WAghEH|d| z4O|3eKqg^W<+wb^WdbayWdNkL+0{r}?Gm3TV4EUaNjHtvnAcSw>UbdYIOpM{hVSSL zvTq1&Maf(Z_bQ0WEPf5-j@wL9(A*DrhviXRWcAYzMakqpb6vMPc0%88#D#O^JG0{0 zl(Li2jbQAglu29zMQ+Gg1vWB0$1aug2Qx%2q;wAKOeN}xq4fZ^UkwaE5D z>Nq)?2Oy;cHZ%KJ+R-!ESX&vFTiSB5eJB=2K2u5I4mO(ERJU6Kx$N8_NC4X&E%0d2 zBzf-sdP*?p;&|=9DCAy#uW**27^y8*p(xbXX&aO2B#5y`uzn zpVmIqmOo5Phsy^LiKBwH?Vq?c9wZ54jte91e_=0kgAB z$+qT7K`?Hjzce8kJD*Wh6#`D*OX`9rL7kw@}o%KPpV+aB{x_yfQ9VpWn1^Y4GT&@ZUIOLYpZPS zck7sBX#I-kY-r@V%6|RIE`gVQnQKqdbwNnG{D57-Hj5%R5h}h%XhRQymT>=+-zynF zV~k>gb><$F+B8x1T0~lAf-Pj^z8ctBXA|idTg_U?0?I77yM9_Tl#**@i4hFW7+ND( z`v^do4{JplJ#(EDi7r53^tr<5mnAifTn=}vCR}x9sP_JmW`BUemCg{g?)225|C1!N z(zjFAX0ixyo#$a(1%w}VH-{n!xq$^G_M~>5M%U@y4T1_@absGgQ!K*5I!~k8;lny5 z5`YmI=nJ^NFreU8KRN8dDg%XehEBc*2}UM8tKP}#08YVX%% zHe4Ahse@Y<>#RIxtpS39_oW6`_fN8I<#23N=suJfQ$!xD@ehQ8O>hu47X3}NY+IjjOOG7WsIkL=6xZN`oRLx>oIe2wUswcJ}+_d zgh09`4Kc(@1+6RCc-BgtaHn-}`_ZwMp9n<|#?fCIQjIE(1?jOlcb^DsitQzy(Gku= zJWkFu)Nu)auaoDEDrf*|biVK`MWpjxRqImOZE1)pFC4n1L5Kz(9DFK8m*v9mHYSutUp4mxTJQ4`;YI5DD!06^} z<)LD$FX*9ctMf$%J)~g!_-~#9xpdWV3zSj~M%#CedM^wx5&88=8Gz%;Wk_g0{X{e& z@^M9Rz=^A1t_*IuQiK&iF3KSiL9Wn2S}XbI5H^&Da^|kqNm*^!R;+EDUMqQC5$u$h zivvMaI%fr7;_T2eRtq7(AoX~kx=cn)V052Tq7m2ex;??VE8iP|M4J$#AwzNrcdl97 zgMMfb5hIum*A<%xrQ(CxOAvxXLRsdLql}VwuVlYD0`zeqHbfXy)@`u?@zCBs`Q9H2 zZs-q57`{vTnd5vAj}p&$p2X4?<(?}BajkAqS^sKl5Amq?5v?ZO86Ay$=z4W_UW2t7 z#qCap^Uxz6Cx@7Ff~248(C>~t{%8uB${JA?!vbtmh&Wr&sQ+4VT&P3~w`5k2(Kf01 zn3jC|SZi~iptBV;MxCoe9YH*TA-RT_Z5hCH7W7~ zOBm&UOg$YA8XUr@1LSe*LjScS2x6w->rK%n6Ad+uU@ZHuEA@o7=tS;NV>BIDNPr?C z0}b)92aqyGY9-e-q8Mz;Bs7YVbv(r`|Gf&b?dK7DL6|rvt1Aw_tKGHH-mggnk*GqU zg5(&cC;vs7S}V;6CusHcq8DhRtj~=#(?K3Wpv)%D{f<&p4j)3Q9X9{2t-gA>?9l1X zvbB_@NQP%buCoaU^Abr8B?*;wrGBvG$+6^lm6E5iEM%XoZiU_S*n3N#)mK^wQL&Jt z-p@H^kp4K{xP6$a><5hT0C%;`Oo5<%%c1W}9n)uxdu*#t(#|4fF1XfA5Wma4%bnOT zfhevp-tbICtD%EciW}TZD%jeMn0B}Gq14A^ zPK%)$DRVP+9pj*9rV-wtPG9Keq8g5*NU`Qq4mFNFZ>tnVTCOIT;hJ+cowz z`hG59FkLLpo?+=JyV|Z?U_*KMVWPghS>6w+lYw@2Si+0l4M2C!VX2E+%|@G@Gq)~V zZ)nM3abMN!Bm4fl6fz~d!Ym6JS;;XM3y4xo?v&t^$ui7IAX(12sLZm}J%9DYJWSdj zPHKR>2xv7X5CMg#UjI+!$Uc?n*5ph9kpfsjcO919(%vNU0WDQ*Wu!l~I;rI=*KW9z zsE~N<1uQVi1lcB|EX|FX0mVS4ybee+KNbJD*j$=d`i#|F?b>Dt!$vC=OuSdAV#^QS z>I=k>b(_(84Fz{hzn`Xo9nKQFM%{)y=4ZJm+@DtH_H-=lM0KMY<6-GqWkko;p$svs zvaLTR|6FFz_f0O7XS0;|>P!rKl0t=7y3d1rXPBv$ZZ+ol5^YZzkzDw^8Q4j{t@JUS zQV>Zd)jjXhHZp_~aM(K#TI|vohu9AMM7{^1Nx%f*k7~hV>gAeTpD0z5awiFp8g{gB z`(<>zcCA~8he`or7+V3b9z-{oc71~+P$ZJ1z-dS)P?n^4}%gm{# zEuwA#pu@N{j{}IsNquo|_p+5jOCO#G<%y&6+T5Q?H`KzXo?-6Qh!mQzR*xHiI|&@J ziZ*x3@2AJ#%8OE}+QQ$dj9H3@G&vifC&6Dt^__lT-%gIPpehVJ9iNFPanEuS^q7$zD_}5Ef ztPj2cwARa(`?^b|^@-$Yv$(I62e~}BHVZ70#?MDi9c4gCL?SpTB>{$9YdGp0qzvQ` z&Z*&$6yuZ~E{@|ROObR)uJwIZhGPhWaclcAKyOx{$LFG5eLEf~6He zW=#h>#pm`otnJvXa{PtL1@FFvr-Qk*Grk_hk|aKaX;paQpqF!LMAV|CelY4jU!N`4 z*oP+_PI+2i{kqUqItFwip19+pb$Nx)38X1Ya%gL;{?Y&ibxfA{c-Ku%qxae_p?^`A z_iWTX^T z3V7;gx~MXE6sO%u?QWV}R%)A)V9@$6u#6rKv(lVx+?)aH5Nwl$5!Hf@Sm!PYg=zny z=9-KQ&A0q|wADIUH%P1}s7CpQf@DfT zPthJ4-DlR{IbD#b(5Xns`0?v!ns_Hji&X1dl1H43G@%X}ORRFSi$h`UC=OPO^?#gQ zCLe1*;-dF(Vf`lVmAWac6%uBy|*kg zI@ZP~m!!Rq;T9YFdvZNAn1O=|F_M;YPvOVK>&gSkc`~*;l~xdy90UR@CBfu4pK}yi z@wM~23ag#6nS^>&X(tXkao=B$jlU76QvGd8Uoz;~X+){SD zyZPfNzEB;fK?pSAeNuyEN<3*xzc=+HkFA)dI43yWj~s5uE}*jk(#~p4_ydlqa(F;= zJ?JjMI93{#_%IyaFxvoS++utVInrj89-PuJLg^Y$2|oBDjH#z~5Q1Lzc+;n4bM*1x zw&rZnw=ngCd|CK%hIo1hG^1yeGY{yKW9|w4)9?8?42J$PA&a2F=xpInXpL@BDa-IG zXjbCUGswtDHvsFK1m+Il&L={00qEED)nO3GrI7VqD=s8=rB^+~*bb!s6$bR;kPfPl zDXT3$S;#@sviFRW*aTIg<1H6-JzXgD4HN~>Qbl2%lD14P2`$$3$DX#bi@=5F+jIeH zAbptWjU*qQNv7f&klrg=2TM>tNG7@z@wq7%rDgfO1lj{^AX8G5^h-SQ>ri2>HR7PF zV(M6!Xw3J&^tDP7wBbT-%Kmh0f+QJ+tXY3WZW)F5pCYm8i&ZWc@+h+4VHT`>zqUA` zFNQI1HUL+7X2U;tS?6cSUoL62M|dpPV8{oY zb`KkM{BC;VyP}cX4oV2;FsPT7}KcP3)Z7 z!s(rDoZi{O*47M7(*RfiytK^`79k0gY$z15<>51_UWmrY+C@_(opI(tt02CjN`&!P`2Cp9rM z3WQM(u4Do$XJi6r;7t+@eneDskt4ar*oa_=#%A)w)!iR*XPedKYZz&z$VDJ7NvzTy zGX>lh$*WZfe2NnjYd3#et{iNhblSElZhGVy$gb_(51*hUCBd~O+iNlh^; z7H=#vlGA-@(e2ae>$?+$di} zONqRqt0!a#z912Wih=qzQa1*-P7fZ2$pU*y()x?*1uzxb;sK250P=b))}rf|rmz)2 zJr@q7GsUNEn}i3IUNUAtTKSu*MX~&Bt=O87YU;h zxEP|zG`ZG-DM84TXtd*k^>ZmRbZP8B51h5P0U%|q{idX4HuES z6=v4Y9tg1Qwg3mf`Gi~BvIWKQF-Cv1?gh8ihf*-OoQv?Pt%L$X&XS8pgWSR*Yl12I zqi`cFA8`acYlq;bTXX-{F+gw3^&DmdPgdE$*`j}(L9>$r)TL`swzlDffuPJMSSd>K z>w~d>$;j6cl^Df3j2TFQ0A{(}8*?e{ma{@F1~jt6V!BmYn;33ph5b3|oeOxYfApAYdNKgO?Ke;+^j$?N$3Z@-5B>EHYd zy!e%CwyoU-kf_MAs+^r`QYt)~R-#aBH)bvf;x%AiCm(E!yGD`Maz-SELLnwk1e;G> zEhF>!`gr(-tYTR~Ln9e0nFct?x`=&oX|hf^vRZ>IVkAh;2O1n$Uv{0B&B?*RvBPntu3S+vz?AJ@Two4~ z;$y^^!8E08MnoQ9U9%q@1%&g;h~PB=Wc86fL3U4tJ^ zYno<6vI-A|0gO4`oC6O2j}ny|$dBJV_f{PFmT1K!^#z41_gkDC|Bt#QPt7grC3m zCjS0szr_b1e1g6GITY5QnoSVR&@^jk)S3;*QPJ&AtU>6Y^&uWS+{2H4^d_`!@o)d_ zzrYL6Uqah56lpITAO&chq>U+MJ8v|&`IY{jNO^x>$96VN7_2kHbagf|W*oWazGrWp z*7t0f*JSIZjJ!K%&NOEUXd&@5aY?sR=x=v>xleuq=EU|uED6;Au zqd3u%N8Qi0#ar0{S5BQ2hZthPYfV;yA`k*CPfEdgAa>(9sV{rc^8W zR6i_(>cMUD8>;ZVV_?Xb!A;x}^3T=R>dB`)rwsm_G6ffdXL@^9AAKPwwF-|L{xv z_(!ket#?1g-T{Gm4QsP)D76k!Gq5HA4K$j_u%0ZLK+HzDNexsx!`|L5{^1|q#?H#)kOT9^Sk`TdAjh@>9F zBBw+WDRYKeIh;^jL{M@~kejnv)HHWkEEYaf+@;f`o?av@b37}V`CEUN)pYZ2vC-AbvhN!F~bqD ziWGb}!={vP5R&E12hn0(E71(Po8jKQef;Y6xAC_>dKJI=^;>xGXdj?0%+|I5Zoz25 zXaH_Px2seZumgo;VsP*)5HcUwE0a&1GGD5mKp8<7xTGD-4LiJ zX^DgsUlrc~{$aO+9+e8N)Gl2$jyIp+#<7H!EUbTg>pqzr*V@>sI9o8e2@JMjxXjp| zBzwC`;ovq`>F=0+$%*24h>%69*U&XveUTVmU{cnXaT0!$%zW&&&dDz-eFG?nT2_+z zq#?abYTaeQsutQ?3Hs%6q$y8@(!2-dQ#BXQOK&)QjyRPIh3l481>g&F>PymP$1WEgGn%$?k=|`#BnwmKsd!+scLYKVraz8wWF^X((ys!h`&{ zu;6em3hc1wElWU!;?7tEhKtI$QleR;x{W#;Y1oF7AUK;!r@7UdBQP7zbv#f;2&^JA z`pE~*LCV-QeOxkWX`kT89bq`Vltg!pWy*o+_*QU7t!pxBUn&+lT#UrXG`YtB%OS9a zv-hAAwPHNEqNUIFO%{pmNo|${V7{26>pHZv(0cTPC{$|yr~(ME%r6TYp&?x?4QUkP zc4M<vd*VqijJg6qdTd`yV{OU;gFKaN)u^eCJ!w zVYa3~WZTsuIjS(f+k4NXsYSB34rzlD`~#70M82kdb4HkP&{6T86pSM+aJ_wFU?MnqhBW}?6Y_4q19+HU)Yn=@BU|WB&x>=mjbY3wu2{is;y?s+;_*zg(wno3+9z|eTa-vh<2>B zM0DhsAVv-}=kMXILhRPx<8K=MNpjJ@=r4B+zLuxL;#IhZN}F+ML5#x(Xpqsbf!ors z*vYs4$2%B2T~_z$B!88iE-Gv{GZ@-qFn9l_ahq}5yK>K0FP8A%yfAuq*J-vnJpFfMHh4;wK6W`)^U%7de3al6?*>y*2u%f(m6q$4t z?t<)AsImd0&Py0{qhK=!BxzujIXLvBheYk>2>xV&Wt5Q3Du7ALa*&cgr$x6)_zFv> zs>E4GewHXz3pIaN!N8IP<|I0Vk?EOzU1bUunL_5fh^aoizXeQ{d}m)^fiu8d8tCq` zk$M`EEc4OCFj>LIP3|-9KJQWz$7ni^#a6~X`DI-0SX6>=U`Pl$%~a_A(&S^ytVvH8 zbbgWG)}8AU3wqGZp26)qxlW3}-Ud4dDG?(u5C|XXOr%zEpxUi%&2AwG3(4_PzNDoJ zr$9GJxQR4?66DrlRQO-9RXDP`q~k6c`M^UAbV*pc#cWw0(#fM8n`W z_cdG{FqT6GRzIgx|Ni7bGF9}*hIAMB|FYTQEtD7*5WA>O6CZ@D# zl(`QRlPrKF+0B7^Hkb$#r5a3oF{UJh<>yO0P<8?~EQHkSpO^Yb_5qt{SOzpwt290) zvsf`zVt^?)tw-Rt77{{aTsY9fS`2~7Jht_u*~=X0O+7yTJ&#KZpeD5}QW5wmf2P0$ z8Y6urn#+z`Tvw+G#*-K(h)u+oXLzd{@P)W9=Z7XOA3`Yyeur{YU%w$xnZaThCp^ zAD{ac)@BWWW%8bh$$vpxm!>T?VnrlM|8S~G@N27NDy0m}-%D=u6zzZibc;fx2God@ z*A<&Js4Dc2K?lBnAq;Jx*U-1dPPg;ac|11)q zrv-X@+ynGW95v9LiSJV+9})`?p`)p2_74HqO@`6$A4eQ(1k=Ua$H!7d(C#f*AiP}r z6JWsO+iU%Cel(8KuYky`dgpw>pf6cG6TCU=mAM<}Q3@X9X2Adx7}+!drmpK9SMi&L zT?vpo&0szCS7n}NjQ(_4Tgtp(}sq{pnBe(e1||I)|p+g61_a8tWGmtg-sx z4p;vx>x1|J8naXrZGfQh@hA83cRzX!w{Bj-3(uVg!L*vm7tG0ZlAgfH`o+mJqm=ZF z6&ow-r2L56?~!&?{I|E&a^MGf+G4G$k?mW@rjs4?bJtHssQUX)vdBFJhm>{%Hy^H< zvI++SA#u>09&lDL`a!#>?iXhM^0Oe0KPS1TiGMl}Lb1=F*F4K1Iqj^)80aj(jR(l` zE>r3~P2!wJMItJ(=mO*#yFCS^@-A(0&r0I#Q+ZK;`+R&1JNrP7o+mUR*lH=IgKKl@ zIZUcob|-;!?FAzus9;D@lJcF5n*;TF&RChOvoAqQj!}~$}ZAY$>el2Vb9_-*J%ajJzGPl zr!7yp@jsRHz67LZ?~Gm@qB~Xxavif5dzgwgU*hWR+8uvF$51jIEUN|71x=A@(tLj4lg0k7|^1-z_`P-N~bC5l!_w57H3mVA|b| zEqwU!5P$c#zs6tu+0XFNhfe@Hjb^q9jRu-5xFxx!(P*}V^IlT)w+=69A^>ZKB~}`T zi$lErt9S9Uue^@S7ykfT+YNNL0FgqYW>y^Js5i%~Av{yUF3dUC5K?&wGXG*k19&V3 zi30)X?t?gLmqS_>2i{|9v6#3ZmpAof%>u>GrYvlX1sWAQh1J;#^f-JVEu!L|i{?E@ z$nc`!FYy}wJSpGtbkX#ZGLYv{WocyWy={XgHt1u+b*2HJ5vmy_*LP-U=;GiQqb?sS z>QTjuaq*^L&y~}AWl^9Qm5>*mjHDii(I}PMV`AxX*zk z^`xgM+g9{vjY}*IS3(`Q5UNnJvdckt9+^2VPLg{D`D!h-GV@N}?yM9}@wD0Uq5GsC zG0E^yn{de)1TnOj~;<}15LYWhRKRb$&+I-96yDcGaLmzZU|Z6(BEmCh0aQKWdSlNApl zaujDA4e5xmAxZ!nlJikznF}7dkP@kAkXgRA@GBl#qlJTnVQd*xumUsBTr5v;E(Tg_ zEIXrLHnShmf-eA9h`vREJfdvdCK1vcWQCF`tgWG?XITjw4-P$%!gb9V)?RP!LRenp z5^#*YHv_1pd!z(92a2bB9)#*mEa`(?a%fNrgjfbxZ;0_zmD1I)N(ORAJFKL|QG6}h z(Y*Q~Wept7=Qui=Tiq1pf^MWXVfDB2Hv`!yptTOh%qgg0^bWXW8S4pX zAFR5vn`bqU8#a#BE?Yf`$o{vE0X;kIB&fhT<*!NTdyr$DwYN|!#O3x4GB|shp?#9G z-1Or!rs+cUMd@nC1J2}nj{Mzx!Ooe6c#nynIm6sGKHk+`BWK0rHWLLhI{7G2BDR_8 z0}-pPQvHRFh$dhKQtLQ6YVpfozK#F*AAg2--+c(s7Mj@xpjvkqCtTOlmIIkBU-QhI zM^<>}-3R#5kAI6RSI^_hl`Rk%nSy3O6@m_G!x&i%xdUY$KyaCSNbUzi;%aNb*2T}E zwLbIm1ul82_g%YzQ!FF{CW<|N@6=;7^||%M80T@Ne(+F&VW;05$SR06v|2E@@i23~ z0mk){n*|}xhjYmj59Ej9g6BFL&FxYr_Frjtrm#i|_Rj;=XdjoUZY0=3&ai=axxnft z!&bSgLMW2RzgF4*jZ5*68Sz3WFd~yv$lP)3h{-Lm;FJ!nQ&l#=10-2}E$3)`Wij>{ zy1XF)&85}l1P&MXj)}~vS z|Jz^Ujo;k|=nP2B09Mdso@Hh#7JE+<;Mykxn%AIIi^a0TtFOL;8#gcDkN>-G;q<9B zqsP@9IwJFVsE~N1l#yj1xDdczFWa>HXgXhxx>UU1R~r8kf3StK5yl=@0ck*!G< zIWc#Z(gd?d+uu!gsv64`?)W{S|*qkB7NPDDG!mzgQRqU<3u-|GlBWw zq)a3;17+G4n!3k9q@3o($N_)3`1Ssp5rLJ?AY^+@5{q1B_w137cvy!(R^q5q13)Jc zu}jYNgoZ#^&4r_I&!%(|5pt&=yUtPo$)xS5t1{xGaHLux;C$I)ghs5YP0N_bvOwBYsOpw|a(q;F7 zGJ`n+T=&G(`Q)?#i?Q+SF0$gpY3=&i+IW!;UcEfP)C5*RDataYV+lgp5~@^KjeY21 z-7bIO!1cKAm+Ga{VUhCYG4S4UI-ii~$Ng{;Nhb#F!E9(RDxU@g5W0>6xV3B;Gn;mM zH6|B>nzB+sm_H}(pZ4!zVs(!W6@K~pyZHb7AAf<@U;hB$b7*F3emQi*vcf6!3j(+? zkkCvZZt>}7kMZ|E`3-K~ypC^t{U%h?q2oEggoY>!atOyNSS1UD;|*69oqZ2`#K0A$Hm;5&NsC~aRkW^N)iK# zqiCfoNSL|@kbFOrT7}34!*nOl94McMaL4T=3E>Y5r-c4>o`h$!^x7r3LAAnpKzXoP zN&v<_tz}6Jr>xR&p(Bb2_Zbw8OC4JUU=?R=Mvzmf@340YDZNL+u*P#GabGv}%XQb* zC*28oP7JiU*v;!_ZS{$C9_vKGxU^P@iDajuJ?_ONf&9C!!*a2#v!Igpu67K0(n+X^ zwW;QP*mr}nH2W?r!nr?p@ua5%P?9ZQ>=u; zZgCxz^9L2CGbbLbcHDwm6yMYzWX(Gh_o&nd8qO&Fx;okZZKsT2>6jcu^(4%Ag)$!b!t2vDx%&t0QH>X z!J!-mv}}{fK{Fm;JbfyS@(+~DJeO^r+&qi0iqC3Imjs&5(tfdQWz41x-SqK;#9!EF zNTs1q>pfR94KLm4s1>tO&odCSShaZW zsh>X-vW8i_dw&l<{?Tvn>TB;~Z(jjw6HJ88ZNORK^~FgOL@uH~@ftHQZQ{YBUHt6T zH}Twa*YSft_&V0w7OWT0(AG~uln!p5&dW(0`%VcEh;RPddR!tb7;KwXVyMcoD|RE7 z?l0tqGc(|sMPMM?DhmF;uKPpEre%^Cp5n;pRScXV0)OPeMi1DkSvW=!r^$RmLpckL zvG=O*6ZhI!2$uvSM=)U+oW<&#TMUb79{9YTU!;OzE zq+Es~S5%-xMKa43RPDG;lzg>NHqkckrJ1q6ZvbxF*lB7on7d#HmMvI3aigaqg^yB; zWCRO5RFQGg9`W&rEL$)rvR=NW@6us($SqIfXVaUwcGyKXho?B~H2k{xfLI1*?Eh6} z7%I`PB!(aIL@?&Mr($?lt}NyhvA5$u29L6ksksaB7~R-0fNeY&c9Pe+$ETEHc7#L= zIzJyA`+7qA!Wdan8kG-$a!VHJwp3Pps2!w#>$`aAsHkA8zYca~sm0n{3LEJ;}6 zFI<+82Fj98ScBR`rx$ql{X6*S&wh(r&pm^i&zuHR2aTl{1i08>vcpvFerX!j%lM=$ zJQdf^NY&@}9}i-q@PWWWOJ@yYN=N2S#W-StymF!xCuAK9m}-nm zW%JkChhW5PIpRSzOt?=AMU~eK+jO^1YjnD^l8szG0C3c;$=40Z;&O6+5yjJ{8hJ0Z zs6oW)Ig}vxgxXnyMfvf<>}zt!8h{$>3+$$e)RsM+h~1Rh6=g^-hcly{OAAt8b18+0W?m5R9k%{zZm1U zAz<$Qy#diW4i1j+n>RkhTkqV)rK@MrHZu@2h;*QJI80NM4RpvorTZUwcHlHSt;t!b zxi5$~atOWbkeeU(b}SN#zz+AyxM-5T%aW-=ebj`k$FalWDI;2zOmR*yy8$)lazHf7 zpR`JNh(R*P+_~~hE`jqQARebx)*0c9_&9-UHHDO6QS@PI(1WL> zC5OnOa#Ib!8i$8RW@-~{9%$fM7|z=KWs8braV(rX0;;kEuAWHt52db%q)S#H*$pFx z!()zx{K971b(~P{DyqUq-vEW-v2-Y^uQl^D*rW)k({RCFizY4utFcQCjgmP`1+^(? zFCP;PXr3`{kZT3jHvU}wK(>BtC0C0Aq!Kz?iWh+7yyX6{Bnm~p2_o3`WC2p801=`U z?hEuj4`%akuzzrbU;XNBy!qyBEEel%nhk5Kuj@f3Uoyaz039>~V*{Uj`WQd`*&BH7 zD>v}WwH*+afhA|5bEn)C{%K2>`dFN-<5SVf`z~F90rh^hm9^iikzHtl)H@0*taP&v z!#Tm5GXuBw9H&FCRQQZp0bT-DEXLCc7MKRibY7B>0*x@7OR*CQlqqW$$zgI(0Zj?j9 zNrBwFT`W!0%gH+@0isXJP2e~SShzP;&uej}ZL2K`PY>MEq{Sh922&fL>|8)3FhTkz z2Ij$O0bQU+f@+`ao42L~ET zt()0f>inEREnwjH5Mmbs7hD<*nTa23+}1l?&O zD==$kC>$Shq9OM~p2F<*&F+NY)@f{TZk0-t_b+min8Z_fwC(9Jz-=F1m?BT;BR7YB zR{BWD`>q`XNCS(zS2dAYP!0|baCmr#%}t|UYly+Rt4wH%cr_Z4qC~@Bj(g%0Gg`hj z=tl7Z(D&gvGY}`?PYCEv2in{XwWu7p4^Ak{DgFfH);6T#%}oP?4Tb(|wOXaZ@D-oH z_I0ed+|`&{Ibj9JwM?_USAwR@ztVaaDJY*G}TAK%*K$g`4?RU)#R zsvz%DHawiEeB`U^`mm~(SM6I%ympXUFgNCp6WF`w%lEIph%krM04_rT)Pk^%d-o6U z^H+a|SHAunUVQ!>KpM<*fBcFdf;m)mV?PmH|3q+G3p~hJxuJX7N@5fdx6Nv$%>z2mXRvVDZ!V$y0X3B==I!3WS`QPEh z?IhXLyGVb)QIFg}IjM*luJnOc1K>8bDT`lwJlM?NgGM;`jMwD`w~2VDE!YBa4 zmc3x}fjDVwA8!cLTQ94&T22(|ay{aDEE`i=cnv^`D`gdBh-*LfEqzp@!OfDUR{Cag zJg|}h5#H_Tyk1i7ow=6B0l_#*K#{+B_W&0*fxO$CC6wIxR>BnNbUeaK}j* zV_SZ(b4P_fLXw7F4m4#Eg$2^kxgiWWr|`f4JVB`jh4;Pkbt@6S5;Mz65u|XDfPw;&BHUgqjI^?=nm31Q4YX?va<%YBEGh5h$lmy0!3W9iuq3s8^ z)zFHbH6bN{yzlIUXxJ3YmpWqA{kQa-h?5e69qP_9{nCT!gj1T37R$#<%xvwv97m2Y zJnY6?*4w%PJCDum>l`cSAqAcQW3gP~a6Y$H3PpA>DM+l^)AVc+T&tdX7A5cFXDi># z6gXLVDPfnWu;J6tfqDRFlbJ-8cxsmxv9c9iZ}zhjf*8I`Vu^&G;^g|AYG5#a&}1T4 z9^LGKZE#|sh;5v3cb91U69TAX+IvrjJ?rNJzme6*@fPo=SCZRPe?gdOb=&>pGT;BfR_eC-~hP zAL8cq%h)-!0gWXZ0va;WyeF@WU2Vr02W0y9Zz@skG8SFOz%~xBi0@q#<#J(Y7->|k z1f(3Zz^>0(TL8HyxlIn58EL{2ofs-}GB;(1=3*e*$IM&bP|XSX(!)9y?JUFVr{qPx z$7eNVOnMXubzkUkiPLi^l)uk;Zt1EBVc8pn)Y5PF_ zp^K8kV=(R`>fuo!SQ-=*2|e*E?T8g-oIu&$R9)9$el$00h03kHay{sj6A&_T1}|K} zt|e;~)HYl}J(2yVqB{GjV3TCR8kqs&?07ROgA!j+s(KXlTWSf`m+<9nW0M^VDD${0 z0o%M)9x}SM)=-LE9aFJM8OP)n*7%-Pk4|`z`8}vjvH=m542#5}8yqoY_7S3ZLF#4t ziqIxf$%}9RX-tGz?l5A}Ojkpt8mz6Y8L+@kcl$KWz-q6n%QkBLeG#$3xdE~@+`s<> zzxc&lcr_{&y|Yq z?Py)6_2s3qWomj*hH{PfmQuFW!)mPa?74nvUF zoRUiSj@%!|3}^Lycs13kjQLo@-F=rNj=WC%vwJ>QTe=_-LpgE7?lj}@Xl@=-Qh?T` z!AGfHlTV~FS_xRJ%8(KA&tXSsl@`;wnn5ZI;AFm`2$|DTbHiE6qtNn>oR;@LTN>7w z`ngNP92|xUp9(6L+fzj=`v@Vb-?M@Mn-E z@Ch%~Iw`GdfOSd{MbRf>ZgDhMc=OGV@!Q|Lk7ur5z}d4iDCz?H{`)N|POQw54glxO z7R!NO)}f7A^~X*;UlUNIY&@+ZW!GTs2ZiK0^waaULr5?!`52I5uyBbwP(Du8=?%5l zS(?{Iwzeg_Oc~5^C=@}7ZZ>0E<+GJ0$i*66=~3(*IWj;S_C53rf+LB!=ZcNzRPum; z-gZAf<(oN{8|JcC7dm}I3X)2FA;Lx?zT z(X<4;oa6qzJ-q&#cks<`zJPP*E}&@%%33$d;`;ZeYk&w5GI0pa;lL)Q>rL>XP1a9~ z&{V}^Bk0H}CwSZ+MVSO5jUts2H|6hN(b<4ZM9WIT=x3dURv4lQAl&%dD*H33yMs~S zMfzj$%(~a5)QWFlO{js}zBDfhno@9I)L0k5ZP<^8pT<#x#sgc>SUauB`*4wI7AqEo zpqxBCRir;6kE!=et5Tyjd_SC+;hkh|Wg>n^S@aah$Kbmx)fm#=#!Pr@Q|q5wx2AKT zCPqi~4&OxPLuh6k*suphYar4>B{uHFk!&p#f#30N_S%W=9ny;0Vw~AZ<;OlGBS>E} z;h_ec5_&%?Jv|*~=^9qgnfPoxyiAST03(BX8wc$?BDL{gZ5nr6-G4EXfbsY2)A&4; z1X@rb%2R;M%3u;eP|i8pZ)7~;eyzkQ(5M!Y*aW7r>cP2EgVfl@&KP!;3wJyNB-q<% z3g0=b1ZEL(P!B>fN8Wzhr-hclSy#3Axc=pyQte=^QHgFhh#TWjJ zP}!ZLwE6iSuCq8B^L&JVdZ`!1*E~dehPell9Xdt9qukTAxn)%CUY7d1ID4`LUo@!$>jsmQ z;;hYIi`N}{Y-4|}|1~KBx_-KrsPGJk*W)}CqL>{p$_XWYZdSn#tIm+r?{gIPAIS&s zsB6%cxPbZsF2~8rIq2tD&a|K{qIu}i&EQ2f0r)wvY-7K_c zJ67HRdck(#;(rm~V8w+8gQZ3sV_d%FxGIaN6=vB&dO~g9Se0q6#Y$XZL?Ay zI9>5di)*du(1MAzf3y}%jJ5$VS`0!}7H|#`w6H^Bs%b29qiiSzM=S|7EwrBD^E;35 z>tDZxS6;q?(>qtus7UDViI!65EwyblHmDrSxL*^xQVd8D zIo^lOz+nI0)*po{e^;TuqdL}3GR0+OLU8n!mswsWYf0t$w5iPwWlMJ6wgiyb=D2F4 zV~wMuITnkh{TT%!4!kSHtdY4m@rKC*bRSJP?SqzN(IJhyfs0xit{)+w@?VXfij!ik(qpD% zaigb_U{?CO)GnyDX~p3jfOM7!n#XhsT7y{)TRb7QX+hSO8^c1!7B$(%S**xHr0Ous zmw+urXxb(QU5-#qR=d6e&8rOjeW#69nb~v`Ac2h0R)S^9p=4VUt1?cy7hPiuyaq%q zlxluoI#lgW6zkBn2y!+1cxOMXinoYxmDyK2FUQNL|aq2oy*^MfNP6YlUCRfD- z0;hnA{P~S#Pl?@?yZ!~IniAJ3<8q@rlPF?)Q@~VO@BHUs&i2n}A9c)~=3uDKlEsY~ z-X!9z_nuCrKfSu{$W4aJn-Fm^rWdlCHgVmGt^p74yM5sYWA?$mZcy0+f7*SYVvO+o za-m=x!E}mwocMYcW{D;+r}e!k@sKTa>4ppX@_W^;U5cS<46sXR<4Vz8(kRCOm!p{Z z+6UL_~pSHmaJGL!5tP5GVC;1AWR0b=4d z0#`il2v&AJI0^*%_P4)|&COF#ZawB;b5(AkuSm7@7G$}P zxVbJWI+uh>fh6~&2?I#=5;SIeCHNkEjx+7JIj2m8;){hTzmxN6doS33YUV1qWobJm zwW@`aEcerD!lfV9Om=e0*DzOrnQoa9iJb#96ZJ8%!@F(_TIg7dBmupNspBGI%a*5k ztSyfsB>E+hqN9^^zqxe(O-u!=KN(|XaQ%aBNbajr^zT?dcqu(97U3)cCsTl%9t)=$ zjNFYme{~_Y*BZu@dcL$`;Kt7*=O;Ix(AR=-Q^y2rC*3eEEf|pmLR1uBU5qdsRSizG z_nI<<_65N%yFPPXfo27cdjQ4&Pxe#&QF4pb%*m_XG)=MylK~hbL49~u=@^T^)CFcd zqwAvzGq(sHv3Me9li>VdDY8cz{|HV!C$*n1_`{9_xht_dwkT}Ea>Hg_ zv~o(8wz6+2=MmG)8eQiS$~v&t7Tj`XZ&~(8?Nxu2V{j8N#LU@k7|+~MR6HAPFrbtM zQ*#1)>(dR;iL~nlnMEI<<>XrU;?qicg6yPZi^Ww^qz};L`%h2eXpwpSaxs8(m&!4c z&i5!gC^mJlUroGqS`X4(dIoY$YLrIAx;!-xco@ByFL8J{H~L#eAlCj>`&iucfz|`7 ztD@guubW8s!{gW9P?7MLYQ;YN(Q$el3_V(7Ig3_V~G1*sy&!7b8?lnr=l?awd4 z9iPDDc+Ep_n$yK`hZ*EER7$;*;{8&>jGSh6sYnjk${h3K0`aF=T&5i-ntXiW-r>NN0-Pz=*puJs~gUOa9^2~({b!@{yIWek&H zy|{$oC>+2`nY4;QZj_jqf9}xqEc-imo%UTN^M^Bcf~VH%!MK5-aK06kva=+zxCW~7 zg#J6D9@21pLZGa_CFH>}wP7sjG?3lR_TGut+29IQb`R()u2WZ!j$*LC1jK~6&={PH3Z4@+{aAz!%)9#;@JU(V7ZLRo}m z*(aCmz3A-Llxl)RL0-pXNV3dO1iP>=s7Da#yA%ysAJrdLA{dE+a_bG;;}Bs+#9O029e1IU@pdVQnkl>t$yJSB&V$ zDM1dvmRiln>hw4U794$sajzMqaz2LJ$ISO6fw^=1CGax7;7E#mj}e4NF|1E>nIJYX-HZdR9sW*RK)nf(duF@f|Gf2PYhV zN(ogs#_yJs>FelRrJtRK4}cIy{f;?*lh3aJx%v6yf-fDs{_(ghgdDah0Y+(|W84z* z%_cLJBZa16FgNx!x?^*|4*n5n~k|2>lHlr`1kfz!{wh>O8KdLlEXF36(^G~ z?<@D{&WHS_9j>{58}CZsr#p%uRG1)nhFo)pju+5+iLP5f>qTIHMd25x;qfugfEIvE ziQzU2cF7#;vNIp!sMC1+t@rW98}H!O%?miS)dE-|1W(8!d;I+~Ko%CB7D62AlnzC* zV5S+RSYx;G6S0ugQB<(xPbgQkdK{by5ZqYe;+L!b>*c|`90;1vqtSH?-D%I>o&?b| zxL=6VS2Y#u+0RVj2U|!T4|GpqZ%+avr2eT=?o^T+$^lOga%J4|=t1=Oc^P6Jr``uA zRS1=Se+XEHFsc66EXglY$CO&(99gJUKR*@EwS1jcR=43ohMR%>v<+7%^!Q0(0L#S^ z`+NIXb{*EydJZy7y$S)p08=Z`=K@&_QuB2DrvKy(U;15&^_nUkOI23_zZWL~rpE-g z)$>&t5Gv}AMbcVHV_RjmM=T8P9?OAa-8-))k1(yapfhBxM`=4{Cwm8!sqxwOkETKi^gMqG|$Vw0DN^kr>>TaZ`=hi)FFn!F~;px6BNv zz|=-&KAy$xopm$^ro)L?E;XJ!*~ih*9Gjank#NL;$7Bet)X6>IHIQ3lbcZ(R$(qRI z<w@0ac^*$)qsOpz zCH_5pRsp!hu%nOnMea{et4M!XP$X2LYj_-CG)^Ywspf=%CC|$#m*gTqaI6!B(1XTS zeMpD(vcdaQc7UuH2yaaz9UG{ZLG25w8s&mCIDnjhMj5_V3Ghja;!>c7+nd7NK$(~s zItOD}{VEo2{x;it7-fE}T zN*E)k=ali2b}ia|=IAD=Rlnj}ntRN+5wvPFZebi^Bc#68xBobPpS)!#QiH%n?>;6B zB+$iPfs{Bgl-u~n_frvi&hia?s6bhsC_))@g1BLBWPZK(vP!;!o0p3unSX(=;c zS4tV(q8PGiyq7Ai+_C68J0}qbI|Ob^_eB2CQ?jlF(9UE5u5#znGO%K9z}yB`U##WC-tK9E~(%XcvD1`LJUpWMNlZ@!0@U%H92XJ$c-5qZl}ar4Mh zr3MopQQQQ>fA_RNGgd9glH%tCqog!pU2&I2vWcM}kc5k7ZNVt#>odjRG4e460PBpP z^%9GvVQ*O@xFz(g&oxGK3~-?gh#~5($@pCf;FYpHfD|Am+T@Ih@7o)hd(s7CZKfP| z9OYf#%K%gO9F#~SlHYSP2EkQ=2lx7Pz%Zy<`hDE1kIO)zGjzXvar=_!!h?FA?_tM? znqAu%@I3|OwozkZ!VA|7d>!+ta_~#h`LA<=YCc*7a6y4QL?28+hJfEcN_Z${?f%d zB)YMeA%y#Y{jg{LM=}rbCLFWaG#K{q^oGsq?>&5{v1k(}p$hK2kr@~x;hJEIJnh#p ztvf9B(hrfD=Q>R-8-o8&V}mO9*}T;*2!s}o9v|S1H{QXgKX?T@J6Eh#j|CJwd=K{z z*z^O}e0_}rUP3{aI4UH7H{7!Vh*<}a8pyA$t5V5K!U4vok8z(ci86wnee^B|=C*TA z39EExV)AE5=A{eK_THg^5J@968-NQiw2seRD2$~ugfiU?t^nNhVf)q33{q#e<^uu9zS_#$ZR&${cMKhyQWu2L7)84`Fh ziA`t2`K~wC4XLztl=S@d*%Zo1j#fVG^_aEsak*}%I6OS`gJuoE>(w-Cvk-CF>vC0{ zY_C3a1+d&#b?AZD^i0EKomEAH7D>m3qlD$P%&H}^D9gpT5A6B}A4U=|=A8E3Cqo9$ zc>)S&tW8jn1+8#8MLP_Z%s!gli61W}HT1wex$HX)Z8BbK@ zrl18N5ZM^caG$*yeKgGLt z(@pQC`no4I(p&@I_SsbqkfkwwKH)BAa{Z8=vt&$uFZQLS9yY7cQQ{y==yVr3C9DcS zvVC}@CNxdH^5C0e`Gtut=7{Z#`e95*1sHS6$1vX)VF?V2)8SZjOEOJ~ZFd8hC;K?bR8d9<9LpDYe z6nt+fY);G(peG@rhzavjOIJKVF20lvOJM+BuxuevT-Z#wh+MHeB3kWUl=r)|8uBg( zBEW#6zy=pl92=OYE#=&pA_a!=fAdpfaS10em={-xfsG7>63|&dtHF9{7EKa>MK7(d zt<_OlSqMi-P(0$(0LOPvSoK7hqKCP`XP-U9Tkm{`Z+-hYY;5d+prJ;vOQ{}r`m;XW zLMmVnDzZC1)zE=m$>O;Cy#S(v=2BWKSf@vtdER$rPoV&yQ)M=-wl7TIlViI>Cd#u}spS8kg5SJIVb0f5 zqUehQE{NDBtu5xilibw`)N6X)K>7r!`9%fxs59a5*u9 zWtuxE?z}4jd(G|Aw3=g&E37myhN%-fyyEZ0Z*7t$6&~*%;hlGGf|_7AaKF3~FIqY!kQj6%%qN`N)!U5A** z(#fp4E-()=sVUgy*b^i2>@w+BQp8P^MK6a%~Dzgf6BaPQ%d55{zw7=1{)zx-3T}#`DUBTAUNKni5 zg7@itaqsyy=R;vWXMFVW9enV?XL#ZHYuMf-pZq}y$cDBANJFlNu(8n$1$6O`B4{1gbU;KFr~ zBuDK0kbkIH>ZJk_TLI`k4T5X?S5} zlj%du=(NWE!66olCDvwb$US#@77BDeuW(cQsz(l2iG^e;XzgbsXtdZpI#&WTur@K8 zb@~Glt01KWxwqUg?5X&;6>;J9M#Kt}U_rV1kO?qi^}dGb48YBt3k_$+9)6(0P&o{INyZQmDHzcj0C9D}9A~bjnpA%)8tpH`BqVma z^Io^!@7COP*}ch(I3_u>XP~$-(3d4AA{c{ciCUI0zYeH_QG5_5(n9XKZ zHfW?bthFVfbOc@zy+=8Iwama(3S*L1q!jt~GS_W2{Z2~MLvrab6dn2PR={maQYCG= zGLu{A;!>D(D0MRGSfM;;k|v?mIwbk)Oary6r4g3b-}ro*?un95RhZBhVM0RycD%k{ z3Por&fZIPIDBpx(K*9e00gjFq*xs6%1;`1g-GU)4Oa%K$Jzg88D$qGli(X@B7oh>v?yFZUI| zA0i#83nUohd=dM2mWmy&wB3IkRr(dAe@i335qfIQP&x!cDb}OCL9vVB;#xDJ4({o zdLBC#6{ue~wOwgBW@MpkN7RB->*Z_?Kmlk#v2z?E+*WWT?nPPpKGS7Vh2Sl}w9OcI? z_O#)!6fQ``cr+7y9JY4V-;awL7aFAV$YTjct4`TEiQxHU-ErLxW~;Gv z?iyX^yFBLEHJ;NfQp=>114-{)sw7x){v3JVR-X#iK&jTepK>83ogH=q=0}8s{Ubbj z_z<7nxrdKF{uJ-M{{imay^SkZ&*4x0-=8T?lBTomfwsi8+3-%Hn#O^zg9A znJ?^QMJpl~qv{qBxk1F%T7-eL#_@b(W>cb&rZ+iOHW;T9NHJJbG%ebDEf~W8Pkt`* z;S`ZzJ4oma%}|YWInY}A5T=8W{p?4?C^HusRS9(KTVCRR?xaIm;g;k&7dC_Aeud&7 z2}$uRruIYh5PDAIj?j6w%|C~fhB!356E*|eb!RFQ}eDj;n;*b95`*`uiuVQU|9n4yEPtrgX40b$AzP2vF zft0EPM7vW)VGQwR9IKKdKVb6=r~c)A?4tx=DXUz&C&#%j<#NU`Np+Eim}@|ui=k@Z zIF)b8aNe6p*%+1a-LJ|7W}x45l8!#tyaqV)&9>r^f1SR3?li-1Kn_)wbC9K6~>Z# z-XjKh(zHHqhf!2qv5b!Ni-yWUfj2y_v*&##+EL<@Kj3=wti_Q5KsxqNFsCe}B!Q`+ zUO1S>jYKP_w3#85Je$HIj~HNOK`vRx1mzcA4Fhns<}B!g@FiLE@QU8I)xS~L-&^9n z_ddm^pWesiOQ+DbQsYd%=uYp6Ntm0nM{}Uo=w_RyHOX{chs9!v`9foUw8Z1bPw?RW6WqJ^5O?oB z#JzhD@cHL=aQE{&cyRXt4)*7O0(MTH!YkkSI{xU7zJ>37@0+-C?E+>kf%U?G^WxO{ z>R>6=*jCq7FN-di{3FYMjr8_I%<)+5>5vzG$^@q%Rck=0+P+hcq)oe!eF8ql$fQ>(%T|xoUU?6i_N7_QD%AjPU-K`?ZVnYt{(CWGQJ60@_V*91AEByF#*NXEIumGL zRl4cLzML7FUMWnv=p*Lt{Eu3XM$!~TrE-sN6>(kLIwsC=3~O7eQYF*M;NF|o4TBXc z&mMUL6`~VURx!40iGR2J>zoZlj9JK>_hlU@*L8)8;%RX5;EjVBJeMb&dkd^$+md~{ z7BUE%07jIiN|R@`D3wV-dnsGopLnS`7TQ8N@Z-;cl<|alqi9W#7I77iUB_INHdDul zIn#eF&LLaB)1YQ_-IWHgF}6&O+3ld2tl57I@Ta5-Jsnnd`cGw>3jk6Lx=!QM&+g;X z&+g+JuiQf08eOtaHuHc!?b1>I{VR4HX@uVojLCZPaa8<_w_XZW@2b|85^2k#I+heT z&8@MGONUc)fbK)j?IS=@F(+APWAWFTp)io`1`*~9jibW_4i66SWcLXkJ=(?n`;Tz% z-XnbS$z6PU`#v5$I>5of5=Zj|x@CuMImdEw2*n!b&Yi(mzjg!P`QFR;=C@zLjhol7 zxw!_-b7;K;SO-^@WSDs@AWTUL?}Sp2mSxU09=K9OVAH^!!aYGsV`F}+pP|yBN#%j^ zy|v~ZqO2rOt2sDHGDT!8m(D+>`c}%^qy{^_lL)DkVP119w{c_?7X!lT@6$5j*vVm8 zE7UFwi)Dwsy?yA8!87xH&Dt-3GKfIxS$PC6k?IWlZ{pRowu67iX;UsXcFviP@EJ)F zs6+B3CrKWuKWS|^ZVY?N6>YCrh~wy6o=|-aSHW_DDkY$#6=z%(Q)QvZ^}VHnrXD-n zbCg^LqYku2lc1DFCzwPr2&R=d1x6$xWyDB@7HfJ4B@bkZnJxnIR2czIBs-U~S1Dzd zv4)KtnE}wiwM=7Ot%|NG36M(;$k-tSr)1Dl4p2z1p=kK2(q*yWHr2$*a}kDMoGD`q zrZs@pKs1B48pO=b&&4_?KALrC`Q1Hbimz3`m^bZ*`Y8Ft@Xp*>h7<#GE z=_R_ZgYLR0THIuR!*&}Iw0#aa4C*CL1AVL}$|CWW>}eAa_t( zzfzGuOhOg8!c?j<;@mOw$RV?y!5}~-t@2>swOn@CeX@tea)~wFWUC?zpvz#d)u~Nb z`XHuCby>EZ8Fyn%vjI!af=-8dV$EPF zsnL|H855Mzt5y`zjCmWV?139w3Z+30l>tRe_pTj-B=UG*ju$(r)h?32A%oitN|@(B zK}DYz5NmHKRm+u^B2M05msyl)2Y)jkU~z)Ba+z z1s~e`(&|bivWTKq%2dP|NkY*;4vS*Pc-jKwJA&q?G{?Z1nbDC($Bd2vrbd8MW5uPK z28tS=Xx4Qdmi9hhEH&nf4vV<~riX_M92^{BfA0vpyZd)uA@-ge zVt;>*`B8`Yg0WaKmK}q&d#@P?EeIN^M{1`fyUlVi!0QcwzOE=D{TnN0aaxUK`qM*QmdDBsuhpsXV;_*3kmxiW{LD2r3> zi}LOR-Yq~UFw~Lm-iC?NoyP9tT^t@B;?(xG(fKGk5s)!7&{Vr{CE!>C$wOb7)AX10 z0ZfMs?BZ`PqGE#9^rc4bapA^GzZ3=c23eF0f?Mz;`!Fh2y-5mJcD{AII8}yKxS$bT zwN>Md)``7DLBa12O|{;_+W2O>VG*rmcSQNk&Zl6d%raR( zWxatNkZl_CM>T}DY0y~UJDbh0zOjzk+6?RKn>cmqG#)-W!0p@jz*>0*IuACX9-KyNNoa6AQ!(ySKJM(;M4J?<8yC&z~25IcAxCw$=)8G zJlVsOy+b_NJH+neJv`ps!`_oa933suEg4-0EEXEw(sW5cGbm~SYC%{7Q3K6E#sC5| zF94o{^#PPx;OyB=+`4rY-~7f)c;)36@!Ye|;Oyxw%-RlGA7Z(jgRum}9E>l47^d*G z)sS8x6?DSJ9f8}-J3awK3>57d`{WZ-*733K52G-L_#>Sxqa?)SA1UL{8fNfX^4YTOmqg;pqjEu#rYjIiAXBiqIf>v=`xHwEeIm!_V zKW~U_0$v<&uQmkO&D` z&iXAaVyK6y^tk~XpGt~;mSfhMHGnSK9JKDdMIT972@z(q7NlA%J3y(K2e?|8r8;+* zaSW@lB1>4x%x-Wpl;`XPH@gM%*e}UIt`yJM21VtRA zK^#k;+`6R%s5FihK%*4e*$nN>u;jB@>zVSlRra5aDL_bBcNFudZ36pl0!)OrtsU5u zp)Z+(N`b|5&uXU~n`)#5u9)0p{~177LB}e2MvD ziTT_-TSrF=18@%yaddQq#j-=kwonB@b7MLLtiYN;n4wWElxjiLLbZkgHo9<85s}H; zYm{Y%mxmyAgq@uRH=enUm%n}sFTHdN&p-bRE?+!{jrA6+J81m`i^T#&#`X@xVt}`_ zr%~eSQ;`$P03&r0?$|pGy0G z>=;9lrn(O-jt9KCT%!&?`_UbtHfVox*SKAUxf}~}i3mqWbL{T!LaFO!FpL;VDOqYTXV*OH_^1Sa#RgRTOQF-HOu8r- zUt*B5iyg7oqe1{eGl0<;W(Uf;01$M?SaurArN+^Gf&KkM?C%|5fBz6qo*ZI#chCQM zy!!;ZPoCh(-U0Rxj&N`|$HCzOM~4d>9RbS)p<5EVE`VdtuG@ma0E}%Aw$0~LE{LOn zQVj^w>pA?9M2(AsWzW`8bukR&21_+=y=~9rom|YZ`lhqcm|HU}Tc|K=Faa%@Vk2nK zAtVwj$OH<5D(vjWIETJPz|39g{mJHoFg|Y*pu2Vw7BewytZ3`%OA2w*I z1<)7^I!(UNHNNq-OXgA}U}D0dIxsKM={dk1nie>JVH3~Zx`9_-eiq;S#&fuN^Ab+) ztYg*^bhiZSBg>y_|4%?CQZ*o!$E8VJ>bu4AV>!F8L zbzrXJIypFMxVvyXtDN7bg^Q?=3a2>`Zh37vC1$t3SSp>DF`uoSR+~*fA&cb_k00-X zNMSacq3ad_l!2q6ok1XyWJ9MPe&{vEvbZ#18yUWEGG&J&VZKZ0(pnpGNSCihZ4xpI zd>9P4s5Cz#!|Sp=TlC*_a?I_RF9TS^CKp8-r$cfaA~&_xD~DgiP6lZaBU_?{s9pbm z1;1bB5ECk#D%i(X2ViADS_`5Egce#W%;${#{W%Wz=LWPs+Qoy1yLkBUF&;d4jE4^& zN+cZu#yC$BWwU{fG~qnGmvUAQ;m(VC8SfcVc3fW3kttEv(H*` zX-e9%s%h;;c@nXIEx~k(e`g0^c?fVipg^J@UtnLA@lRmZM(#mC>lt%*%*x0)n4`A; z@lS>3yO>V5Ozhe z>r0mw&g@&8{x4-4S_ko#qHumSTN#0Wc90AoCZ%WbS?B24OowUVKqw%*kQ)%qeE5ee z++YhiIGwh;r>rD{BWn;&?nMJ)O{t=MXit=C1_x|AqnGWDpm~m_>2U7c7Oq^mjGMQv z;%hHGhZkRX23N0~!KqUX8l^#4+C5T>Ko_g^@u^}QwTZcJYG-lZEWD^NcRpN6>WG}J`{1gBK^=O0&@)o1!2`=vhDp*nyHCpJZQS?JJ4nRIyWnlS{B1oV3>jh}bx{sYZT|ZW7xfyiPOb zhn-0wdh`enAMWD*{l~a-=OOOgd5DJ(9^>(&C)nFN!2Z4&Tv;v+^WAk8Bx|xmQyZoY zYFV>JH6GxSv&r&|t&=s>fTLhxp~dr=0C{plLwZ`Nn58$dFd!>9EO@hB?g71hQYZ#U zK~by&55&Bc5iv)dDdyFRIwE;bL}gs^gDU zlLUXFI1>Yo48#t_MHdn-N;dp#lL&-hvF0n}ovqOA>I1j=Gamcb#?jfXxQ~O;gyR8| zAHG8*GUC8^TPZ-PtKdDDtq#^j9gvR$@1XS@%!eRaV0|4pe|`rqe)Sf<{hhDl#*NE3 ze|`t2cQ&!P-eA^tP;_V{ZVoKkHPOIoU3eyVR7*NaFiZkBRw?jOCmUra|ARhMdY;!F zoYh+EQ^5BSFdzRp%b#cL0QXp&QA_wF(P>Ewy{VFuairjMR|cYi_4x!yvzAYq!42;2 zmZ>5<-rd7|zQoR{O)M8jSn?tp(8@k)??Y4`;wm=zeA|czE4||;cZ|PCg(-XG#MNOC zEjXTHIPL^$`(e+};Xx{335to^sKJ3HE z0s%3w6(F9tY-Ab0FkmLb2uKb|$wC5+c}=B2nlPU)@nr814<7E~?%fCY?9;pW^wWFz z^wWE|fA_H&OxZia{=poJxdym_q8Ugvwq3dj=V)Ryk_v>zFsf`Oy~9T&4{9~5WDv5H zE|?F3I0h@+7gAR$nF57gLwYaTz5oD#07*naR8uL-p}+;C%&{;KizNd^Hgn328h>9WsP8miblp?;XKozMMOtD}j zKEiRrR)s`HM$j!6U@Wk)p>W~CDcrhs885zg6ED1Q6Stndf^+A#p;QO(0>noKR(Bdq zI*jbGD#S`F6w^a}bCFPsi1m28%v*n<+?=$B1oN1uZIQICsBxw8^ad5-&B^Rv+qNA71(gjU^+g)5mfF?ZI-NW9K z16;az4ox!y=qNhbGKMu0Yy(A$j5O1^HYt2!Ls+Xn#&I>D8aR^+HMUwmC3U*&Hz+?5 zNfhx}B~Vw=<4$RJR9imwb+fK}Pu0yy{2*&TIwkHFGJ{ouy)pNLO5_M>+lRe$A@%%Z zwicd+3EhwjPSsQ|_t{;-Bw1EVGE3%oRA6BIRde=A%6elOkZBwd3?N)~jQM!K!w^ z1v>DfTmlElze~m}UDygBGX!xCcS}%U=t{>h>^&aoIO953B(-+CzH#Q=Bc-!Ek)2D2k=VfHtvF==)c<+cC}h$?l9{;mieCQhBcMh zZ3AmFg&P>jidb#c!NDAl9`AvuMbpmEwlj2o=&Eq=!hkulJxaH{6JTGX8)k*q>Hm4I zvrExrvhqx-reMLrI-dHDncXCeL0Ad(4xQCLgKN?C-Ha8G+uOD%OzV2EYBv_e%1>gu zNaN6=MS+0`LujRTbX3Gr3~bZQHS_lrsY_{&ynhK-sBq_5+2GmQ8b<+Y0dCQ;!eXJZ zw|9Vh_wM8Nr=Q{Dk3YdjAAN#PKDmQCcOT)=qdgoQEx~A@)C^6t2GwjrwMI%nu)04E z+ER_iO8o+(A6wRW;YS1w&9`-I%wJll69h{t4k3yBQHip1%EINMU-CmSC01lTh8pv9 z3bpdK1rFzl4`x{wiL1vAF*b@OToq*1VVk-FWqDpS^vRa*-u33f=Z^3F1dEVxYv=i;ihz9>@< zqcRSd6z&;Uj$Z`F(u!(Pwz?y^rwGN1x!%-TQd5 zcZm5>hfWiK7DU@C*Nbmp3~d>EGDI!i-*=BS09wXH~G&L4feflDy*`(1Bg~!AxA)!KVOjDPa=f zhrL3}1>O@^DV2fo0C>vc_fi)i7-J)|Aac4;uY2~xScYk4Zm?Jq_76JTx%)ZZd;b%> z^UlY3|HDu4*=P6g@S!n!pD#Lq6;#uLXah~tfJs4XLT3lenYG!{QX;?9NN-Hx`+$fKPVJc}E;L*uF-blqJ?4a&r8urQ0}&I*St9rBtPZcf zOhHqfhNR!SBm2kyRr1nFWei#{w;e!?u3JFs1%M74>k8Xj>$rIFGH%?sg6E&Rfv_S+bX6UxQ># z;YapC+K+_-TSw{Bg-wQHAf<;r06j#{CO7ifvsNT4u z-O>kchX8C0qzZZ|$Uq8{NY=Q|tc>Y<(<(7h8S6b!wIa(M66z1N+Zd?MpmSnMMPkSg z3Zz;PW?*h{@BSWs_vX9!^{?N;8*jXek3PDChmQ_$v;Z`>V6*_%MNV1pyfuzs#$BQ7 z-1k(}XauYlISJN`Pd|&H3?vT5mCMA`d*i3zR<7Mn`oJXLUq@_kZcUSW=tfETn>VlG*=KLy*=L`@wQHAf z`t&B&*IOuZ;P?mx4c!?%t%)HvLt`OBhfVQ|TrWFxoQYXYai57(AvtUP2Ea;naC;2W zsPx=Uo_i@(wFx2B`vCqdwBGC z7uT+yHwi*ogDg{}RAXLOYHZ*AY+CAUowJ0W z)@SnZ#?dfA@^7A*JAt;*5IY+xSt^3tXkit{H>6*Nl0%hCxFOqpR4i?miaJY;X{E{*Imm9opmrRn|G#+uf^W^^8zkxi6& z5JMx+AScg{3n{UBTDU>6IhuBf?M;Q#JEw5v>P5Wp{4Koj!n3$`?GnzPJB`h)H7LbU z)WO6>9~yAX+BmU*!Md~0lyFsZ9WAITQA1)KPQtmP;m;E3k+QFvk;TXNfzRVSTgS6{ z$^qX{S9x^XUliPFWU;>=h>9bi&iN@mryR%cP5`-6h{LH1#aN3^@6t3L5{x4PS1n|u z<~S+5p5 zPxx5S))%Ea>SVeBnB?Y+!R^U_#=h#qea{&3i$zRpqxy=HQ>KHJl`8HMKWJO|s%N59 z$`jIsQ(5+wg#K2t*KS!+itPCxDr?4Xsm6B89b=FLG)kGcTXL$7Z09qR_T3`d3l*yWR9Nc^3(}F;%svKCW!XV# zg`?zm$9pqo?2rglNVV;3H5^>1)Qg2C;Qc{4vT@^RbIA))5=IY|7M>XX7}pkcg@?`< zkMT=AjRtLf0loi?H7%VkH~1+N(d7E461%zd)pP_=oYj+a`7rjY9T-b!bYOJQdI3cp z+J*#b4C1&X-B!1O^+Ypc|C3o_`dvWzyAF<~} zp5|rHPZS2C9cEG-_UJq@E;-)?wpZ#*OBRc%vHZ!9{KtiW7}WE_%&MPLvcd` zarrq(iVa(amOg1gqCk;VmybyF>}gU>6+Fr#zQ&%%#bSYb_wVB9@CdW*HF%3Y;-Z!# zV-Ice$=J)?m(M(O(@%}e8(V4B@17gZ(jZ^`%PCH&fyCsvy#6Y$#%h-q zsM62Mfk6^1tz&M9sF=o*8c>(T=M#JeEf{yx{p9%?@jhtmv6+OgCr=i5`#|vqZt;+^qBBnMxIRnT=ZD zZ&TToAK3sG*N9aIh@*XKB)ENQw?k$B>HC>XR_MZbC8On zwUa%h5vhaR6VhOnfCFyC?Hz(o2C|WzDR3+1|{^SmR`qS6(luJk0L_dPAp*xC#j8+JH{Dfi4Y=CA2mH3#WIsaqjF6 zE?zv1%U93i%GHawboo3kTsVU>r?+uxYXj>WYiJvo7~O6TMGL@bGp%PgDFd9G$rMwm zdm{Dc@kb2neOio`Hu^w_f`JU>J};6q>Bx5s?$#7->kupzmE&&PiGr-TfDRwh-=jnYu>w~{uGrg2!KaQjAesTx;{N?dc=fg4;BWu- zRs8DpcktlBK04ikXbVI$Xl{(==_w<^GTO9Lm-O>zLV1V zlCd=a*RZl0Ak&G_y2Ell2WyQ+5t@dvwbkIvnQdG+e+HK?pTp(LXK?Z2Xn;}QkzO7k!cqi1D^xh4C?e4g zX1m5sRt}NfX%k{-2n^QzMn?fe<^pLzBYv(vz!nX8pU~}GV||a4R_blU1h~vW92Hq~ znz#z5>?ND50X<=u<88dKrbco&EU9e^}je=%fWV49O>vhaglGWIou<}=sv z?5!KPe*F@zU%P~>S1#i0xl=fGYR!f!Xn>7WfprJ1J1BJo?to=y-;Z3#f{`%Ez=Y7e zlnE$QVDQYpC?vj}X=F9UQ)1)g-|4(Y+|??t^+;wF>h_8$uyQh=eo&I6ZH^#*(r2}* z7d#+7$u{Ac{nGz3Wz7SXzDC!SSV=J`^TCbj#wzUIQf>p4G4g9 zq!5#v5uB^oYq-{a?QWBr+cE64d(cV6dL=~)T+o7Ya*Q6#d)6bi*>dHwa^VXD3oiFn zhfn}!I65Ny=GX7zKm3RP3qODLb?hH$pxFY{I?UtI_-&bsJm5*PXk(e%RUs>{cBo7% zewJhtKJm}Rz1JX$PboM)kOCC7Xqq(;T0pA+IHAFcOu@Epbe8fwXx7kO=PjVRu0z*# z(Avm{x~>E3Wn$r^4Y>7ym;)#xwnL?ySno+weoB(9C;_%ST%?S=l(f>dtE3HaY-JUg zM_JBU=G$9y+2XyEQM8@i@R!hffn~Rkt<5!j>sw#PAOEu-;#=Q%8P~60#;H>qXd9a@ zhJ}gDT^jvt*Uh1M34qb6KxC0)L0N+IWGyb98_5}o0UCzzHs>OkLb5K8Ze06#aE_<( zS70Q^J!Mv^(F>r^o7ma+-@0bti<2E>OJA$&y3k?CXz@w{T;YjG2h4K!g<;X7mno89 zQk}e$x&#dCsPH(cb93C`K}j6c06Ag2JUn!AxmT*9d%S&H2O`2^%EfkkR;wq`ZXA7& z#DeUAYlG!tiM#h6;K|-THaBL%q@G1f+WdagG{y)!s^VP-u;8*_E1%MX7^Oo2z9RD0 zDb`SU?1M4(?@0_C)eN1d@n@XH*g`AIOvF_lSZ)l{f=H<+GQgi_uc6H?nuy#@=~!F) z7t%o7o*-w{BR^x%5hpDeicPg6eXvNpi_NU0z}T+*1we-g+gVEUk7R1{1F>RAbY3{G|| zkREFFQB=6ArbXLsplQ~?x&gEHG0f8x+OM+hBgtp+;y-XfI-qF0SL$G){dFZZ%{^F zW&{ZqC0?rLl8kjeDU&TxH=+Ov`=klSwUd;4YmMPerH-rar^7(7E`2C>Y}q>=q(7r4 z76DvfXHj6~O9_puf<_X8(Aep~&cQS)`h3N;w1*i#3Ffx%`VI}=4|TOmUd??BeGG7q zzkh^_PD*GwUDfVVSsHZR68G;v#Dn{faPG`bH2WIq<(!7oR#MsmBQ08ck_sOK%u1|d zRB?DvI9`V`TnW<(1s0E}kP`<8t)N6m0sH9Iv}MKB2ch`cN<%u{Xq>zZ!4HoSl0tz6 zQ9*&RcQfJ#5cyRv_{`PPG9>4tM8(1uq1-EO^)R>qD&Y}s9 z0mX&}ym*k2T%EZ+F3-H``|%fej6+;LN1FoMLbq+#&@^ktlbB({CxB(Q#C*OqUd_!K zh-QKLXIEr7U8sAe6u?cwd;*OE+J-{GZ#8I|om|1R%RAi}&9AfzvJ1SnT^iN~L~0Xv zWeark`&#SpJA&y63@JyBDcu!d3{8nwXo_By`y(pT{(|NS4~2Y>J_T)c1^N_BwVH?k1rw7T~EvT;&i zE$q7x4;FK&mFP*~kUtVqtY@ z4UF+V$qDD^M2re4?XQ*#=EbWn4#&MAhALMg9WSkl%VNr)=0WUrWkMA7PGYt5H;4EgDeQqSS&gm9WAlG zzJ^Av0Z`EF3OXfZKT5DV_WtHHeprRUBl7(&D00pS8cn0oN=-ZBws@pV6~(x@MIGQ3 zOh?4Z#Gu!24E{AOyKLnau)}qW#Ssn<_tDw7Is=%stpO?ppBlRs#+FOW+ImKl5CWOP zS#yU@A7X2(!E?_(gYSR;75vd3eitu&^%gca6u@&RbRea@8#SW~5(mqiJ86iNd5mE; zLnp2tqEbuOoYEbW>|i<}AI?*}qmL0at-{`>&OWu@k2J;=@?p$AIK~cYOiRAT@Q&?V zjXCZv)1kS%gJWLFzvby@3{f-JqCYI;O4MD4Kz%VWjvTV*!rEdDBi$UA|9S zDNm?B1eMCI_ht})k(F(!H8?t2;PK-pSS*&9wQI=L*^-(Ulz$>lj+j=hM+46&zV!rJ zCS%$p^>ByuXJaSmxc(P@w9Jvobi}y2&>td`$`w_JvR0vf>{UoE%#z5WfQq;}%PTO^ zzT&XC&`?#|v$&+^P|9OU+G2O@J7zSbp%k#T)}m=c27FvXaSsFg<&N~M7((-3&GDoM z5*NjWy`8OXV10c9s%eZ%iS=dH8a__k6^5)s2P3rMJI^}0Ara@PD=q%O8XX&Rc(2N` zMZZttveJmC>ycOxl{g3Q=D{UFhLmeS)8ye#3d!MlbU~#lEj|P~zXK)^fG*qqCb}}A$9;Om` z^#XA<@EmYoh)4GJXNhlg3sQnB;C}jgQXHiilyIi{)L_{yu)DjD#X z%;yJKEDkLLOITZ5$J*K^0BwDe?VB6VFqk?#*!cMbL)bw~vC$Fw2WBarx2BOv6`Z8ec$my>j|s4I+(hd5A@KgpG{`FTVU7{^h^? zA-?~;S8)BAi&$G@5FHthTMi?jfj2kTP&0$H(cC)gT&6K?X*U(00?1)zw5VtF!)t~6 zccT7rD1>NO|N0bH3n2rb0Y8mZ(>80vZpU>#8U}Qz>WimJ8B;sfl)dkJ{fN+7VaALm zoQpB{*bumP&rKjFc?9U^arcQ!rHf>W@uzL$?OPZjleY~usJOzk4uf0;Qh?Tmb<~=0 z|NbNF?H^+2^pRwzw(=&kdwkt@iqE!rC!p`d^{7OD#O2P0ocLC?ytH zwrzD`c}ASG6Dgy`+z|qkmHa50EO8G@vDM0H5*47km+o%NnDX3cur`WW zU;)q(W@?U|9m0*9H}Jzh{4Rd@hu^`?8<(-UuAtNrfF+c(V1pUR^R6v`AJpr*rFFAN z1g#k`ExWn%Wbl{_FR=vN!wx+|0IMz&SZxUUsbO3Sn(uy~y~^6a!h3ky-f^6jte)I8 zp8YKX+g=OK^7j?d7q%^xhVNPU0X{yJ}tdk)#qA1F#O<3y{wiew?K z>~zFDhkS9n*>H!ZY4GBUH}F6HKmHhd`+tsi-@gytEuqNx-?ES6eHxJq|A>Gs)i)#g z*Q28f_@qbS9BUeWqG=ket<9hs66_j#X0>fvY;J7gfC=-(0!_2DP72{UBw{@C%vJpR zfB$ds+;h+3ZY^PLeG3~Kr@+uyb_W)iTUkbB$gF-PN_J*OE8FP>xSOMCm)O~! z;koCo;}3uME&SjQzl9fGxQDC3J`7a^VN^;?0RBvzmRa z|DpXRinOon72GqxRy)R^1CRY@s{??nBLXYEPDA?EDbj|g`6XR@PAWRMx`)Rbs^}&U zfx0Y6ew=Fn72fxYI#9BhiTx@_mvrtnvJ#E_+o6&5;5 zSwQNc^?S!NdeeBd~ z_FgjAT})~Cymx<|G&a_OKm6e@{hxn}-@WxI4vvn{@eG6+G}M3L<5f=?;8w!h zoR6t{b}5bFPBu^C0y|LXin9Qs!8VS1nW0F6YVV6iDJU;ZK-T7Onigworf8fm7FaBf z05ICN^_>$UU~78=SFc{ei(h>nFTVIJe)xyq$0whBhSy*JHD3MsFYv~1e}@MTAEHq+ zY;J6!QEO0Y20~MPM8}6{QjvHVg^QV@PDhyiBtI**v9S%+5Y`Vju)qHpNAo>seFVlF z%pFR>4N_nshseB(fL}X1%W5wGI>ecCGkoo(uiyti{5HPxov-29TbFTar$wU{(0bPl zkC7c9V-0fFY?dKs?>3>aTy|J4yPQGFPUCR9v<^%u@+QwbemN#4vQcWD&UVXmC)o)L z>{^-R@hMd#bh8xCPMGkU{DBK04<)b@r>Lc`ISI68EG!THTzQ}2r%F3S)_28o9WO$z z+d8)M7#_!yi1$7&a~q$-;B8NlUcKa%--|;Ej5b#-^z!RXeSMb%540z8HmLtEn1ds( z24S((c=%`+%Z@Q?3A)o}o$Ar}QiN4Pj=WMDZpN$>ve4(tH+I^yEGdXV9v2qTG`*z! zJ~>zpKC^^09R|YS+k<~*kSc)NK6YSiyRGyZD-Gy{R%(be&7SH2VVK6rBZ|prEEYue z6}Rh1IDMtDH`CZTHNzkN@D*%sZ{jch>L2i{U%!WY_x7>WOAywqx=%qws*R^H|7&7$ z?Uzo5MhIrW%HN|(B^wo+WFR}#6%8bC2_D4yZRZy|Moa_ytfH0NIgZ1?d zfC$Uw63fonhS{MsB5ZDMVtswhI1uO#Yili@d;SJ)+`NYGeCM0^)vtbypZ)yjc=LB} zA8K-^$!>kMY?7KqloPxxxLl6;1aVaZl3Mj1`hU_)(NAK-QD?ay#<@ED7Q4!-0) zcLUo%0&gAVhd~&uJE%tE%$aRG_uTXNgMadM{NM-Q!i!(IiBmgkU_ONI4gg-70WxOO zm0=6SIDIek?=EOVM}s?dRdv=~(ZEYx5Ys>S&Una^|OR+RFx?gos<0UVIVu=JzYW>IJ>D*;C^z83F1m01FS9A znIgg%UpvIi8HZ-J+%QU#i&ag;DK=WR;Fes;g`HFD`0jVUf-~n&fsG9V2HV-1 z8QO9HRcq+w(tyat67%^2het=4AI&kJA7OrUgvDZx#bSYOX+jblSW*r&Cw-1u+loN| zHE5d|6g7i#h^A3kUtdR~jK8f?jhQ82K&b}XTiaM)-+*0;jGygNgB0QVjVri#`8>Yy zt*_&aH{QgL|L*Vc^Pl|!4<6pZ=EfOpZJtKkZUz}m4b@QJF1q4EKz-YtO-A(bv@O=x zPkDEugM$w9g@)E#U~zR;xH@17Yj4=;B?uk1Pi^AXv(Mlg-+U3bp1lD;Rq&cd#Yr5f+z{NpuzOA6WNG*2&k03O|MaPy`MONHR$3{0r16h5J?M5p;P@~91+`F zV{sY5M|$Mvi%PnQk;r`{;Z*PAAq*B+@_tX^G0#<7XF3o@k4FX?P{GJwntZ$YDb2ux z2aj;?-UD2|bQbGtGqA1HO|>4X7CcN-5u|#7Y{1F$0jP;KP zqH;>GXPR?RKCtRUWKDii0L#Y#_I<3WZx`3xBt{LQamMV)zfwv~zTxHj5=nUi`Bo_r zgK>n7jTyfBm8-aR^%B1RwHNSrfA=bW^!LBO$DiCq*Uh1t4FEHkv?`Spa8t*go<_^$ zX>O#Vk8QgLU1!p`lxncCxrv?AJ2-ppJkFj!htsD|V|#lGTU(ph+}gtW#yZw!Yfw#N zuA{Sc5k-!(=2|W~EanT$7YoeiM>yEu!|v`b9zTABhYug&(St{L^7t_h4i2zfb|3;8 z)u2%{YT%?%3bS?wQq8Dy-6#dMwiXr0dTBt>Y;6rq+X(wU^SL@Usa)-Pi)%No;=<(% z`0Cfbim!g{tN2g<=bz*K_ikf8pJV&fIc%9>K9PdVPn0; z=`&lna``-N-MogIH?QEz<+C`uvxW7UG9X!5c?5TUpU_=MhSR#MwvwlA;L(!L6akSy zI%r4&l)i-eHnqVle>RqUXj~3vvV`(F6A>)O1h>PwU#jk%Q4*=vn4%{h18y^bMLocl zs88ZOg1t?PP4f3O30)r-YF<*v8P?IC8NCT-CFa&2rRYwFV3^~(NX2-upERt?ibgTG ziOx2e{3DW%1}Ii4h=7DMK{x+AI6T6G2aiD1c;*$vK9qpH4<&oHO({zJTdnLtYY%?> z@2y~7JZ%9~V!xL$dQ{XSk76G+kEHr7SQp;Fu9C_I+Y(lF*nMCimenaFkOnv)`|mhf z6jAKxluEwDyiX?xN}j#4ztDlem^B*b&aC6ix1PhZx31#b-+l>y^*2AkFMjnF?%v%+ z*EIkfn`_uSvq-1`lf9=6a-Y6hOS=eJHbaeT>uWf7_AIVne+JiY+`z>vm$9?6gSGVy zG;IUbSg&Na4j=>;M2c53(cDUz^f+z(4V}bMv(Z#87YiI69$|lP504%`#Ql5s@!;+~ zJbd^NyN@4Ze{Tyi@dj`prI3}ETn>#f4o zXRhF1|J(l&U-`-l_?y4}5q|RHSMk}WpJRV*8>dg7L))xHX;><=PE0mJtE*hSAOgx^ zr8X!5u<|cuj0BQV3!ijT3uSDx}p5no#eVj{@iS&Bxkm*w}Z zgWD4xTu!F-2~z%4zgDa571aB!3t)mgd*%WZg83{S=T4f2cRd##W z-J|y2>2O&J-sSzU0)spDW}uO`i*zS60|Cp9@nnDBr)oG`5f7Z1p}Wp*rpinp`*_Es z(`Es(1Iqq_E0u*ntkNzT5=;m3aoE0Nv z<~Q%)?%gLiJlF?w3(yRtW&pL8*`?}Y@L%e%ng=alsHVZ$opZSU%ym5b?6bIb^%~Bd zKZo_rEuc{bWLVaZ4g83QG6nl6jqjJsrR@9oV#oy{s8(UEondWr3p?k|;>z{w05iJ9 z5{C!-c=+HUKL7Mn+`fGqpMCNv9zS}7TQm(pHH4U!aw}<4Semz=kV=sy@Z=LFJo(~0g?8R$^IBv1(qoTw_|kuB?bw_b#>U%aC~bn zZpl}&;v~t$6zw@DVa&fe9-!X)H3!wx28dmYeJEsMRmtHvFI%x+i0*dT$fti@=>@bx zgG>sUb?D0LxR_BXohRiTudqUgyD)4|^i&gJ>%P0;^R=#N^q`dc|ogXVPFO zEV~Ym9zVgs;UP9Rx4m5oOG9j%3Pd2o$PyKo3rap%1V|P2J~&fAptKqyqR7`U2TQrN zMHw&_gzJ>IXHuXzbTdd-g1#zgEU2GiW?fo@%Ez8gB9~igt1MD^duz-xZ2~D=x|8mf zXw(AFT-(OgE8oKpzW;T+^UlY3?X}(Aiy>COCze>PZ4cn z9=BJxR5pwoeJrwqjCyh-30IiXtA%h<%7~9i&9lKZ+({k^yMH#zCs;xY+s_%iv~Hgz2!Elqw(w+e+E#eX9Fhh8Wwp%1ht3|Do(#%*qpy>GzaUP@=_K znntak=kodT*T3+4<>^d4Y7wK#an)X13AYJKVxawh`_B(6U06V2fz6E;*RNf~*I#-b zFTMC2E?+*6&Gi;qFVQWJzc|l zuFF_XYkMe z#XrR#{P6qO-+zKTcRxovYrt4yckcln@7}|L520EHHH58G+qiM_CSLx=H}TDHe+OUr z>PxtA`7+kGw!liEV~wRYpwWH)i3pw6SS*k5`Q6X( z+c$oV_uqRPTU%?meCZr!Gv#j(O4k|(qMery5z5iqlm%RuG@ZMDyxl4e8u3l*;Y7)&v=x90y&gZprLZ*Zwo5aF4Ad7}SWyFX@jVVLfT+gD7K z{BLVwoDvvkX0&Nr1XLE%_jnU$DOqxpE?1WX){KV_AK|mlKF6(FSH+$xt%X!!YBKyx z8gJ)8xwz50t^=T~Z)3e`8)8Ybk637#NIh&SKP~wsmI|Gm;anBA4CQi{nJSXSOlX8g z#X(eP&^YJ8!*apKIs6a*`cJTZY6E}yXMctF-u)2!2OYMz zPNQkoBU{8NE#CZW+bCYr{@=T9fy1K%=x&b7S1#eZ-~A4L@WVgAOJDmc4iAs;%U`|* zq7ItpIGP_|Z~rkmo@2J&VsmQ^7cX7HbI(1Gn>TOa+=Yu++t@OaF#)9wh)sM3IP4rs zd@{MFE|yE|KY4_Q_ddnFJ0IcU{ZDXscptN7j^)~P%z})8#)nDNZZYYMz~E{UX1We%ZZXNa%BZa|$L#%396CXMFXv!; zWxF|}x@ifC#$pXGrHWDJ>sv8hPxc0;Ks0bqt9uGC>toBu40`vao=)0ZpOW2}??Z`% zRY8fb%pgyR>K#h4b;sG(`V>!Fv%?G=9nNw0?mZkG&atu4MjK4}P4Z0ZyE%0Q!}uGpJ4jBNGfl{t{6!xEPahIbT*K| zM8m$1Jn%5|NlJ2M_k~ z{`;TejW^!GJMVskk3aq#cke&K{{9|1-9V`pO|uR~Efh7-(KK_?6%Yko$)0FvTbe!s zk`hQpU#WG6JD-1!&p!JMi-k#tQcZ)6jST}bE?vT|kx(Xh;=+?y1=$ zmHiOi=FOJXRSc+Ei__=Mf?46+73_l~sm`)q<*!%yqVYa4GnM(CH43pX}n@x8K4C@4kU< zxrb|4&ft}AeIH-{>McBX^D@ruwAg4Dm^FvcdSRG&qIwB0gK3H~DDEWym`4U{OerKQ z4{M0JC1`8CMy{trSl#ZDC5eN`dMligX#oTIv4}Io!|V2_j%mV{=R-(6=U40nspqeB zA}WOqRY|de%pv?cjgkPadVVL%68uBfGu$ma_`&^z6l(@k2=NJp7zX35hf+#wf0y~> zjsVR>6aelNQ~gyb=qTHZ6qel*cke#H?&Cddte>^XG>Pp@;lt?(4~dfuuvP_TWxOz* zh0kYtLyt-D=zE{zWHb*~lQ}j}AQWh4acwFUZ#k2>Y9cNxWy)VP-~W^HoC*?$ylty+`gDuar_bZY&5QWn_rHb*_jmE}?a%SfyC2|pZ@!QB z-uoDL?moo9{vnQ*3W^NiCHIFK5H-d%KrHA+vnX}S(hNM8yY$T^F^{{;9N5-cWB2i6 zJbd&B+Dk^rw`M>3=r-1@Huut1BMG>6{W>mPzJiU-%`6`G>3>noQaR15B5Z7L;mrAS zxO?Xw7K=SFne;>hNEK*>jYFvhdwY9${P;1tZV9E#1U&_kHa|KRT`wo$u#Cv|&MAE7 z``^aa_7>LG*YJ}c{S=RO@8R^$1$lc=YH# zwzoI&&;HpT;ottde}k{S_!YFX#_DA|XuSaQ0-Bd-n+99k8@O=kJT6>3gUzjVT)B1y zXV0DoHLdkIhlT5eg77AQ+mUB`b8`bXZr;Fb#@K!M85%l*){L#~9bCM08K*W0wA=-C z8r%hT&htpeR1FZ0xmM@4O5 zp3J%pgIy{ojE*5ZlBs#iPDCUX373?Zw5k)yY@ngf<>U>OLSU?}cPfbOBi@F& z8Sv&s@W~bLXr+iXr(xMv|A#{eZ3{Q;@BrRIgG3r$gG9`rI}*ly(j+@p{t$wrg{8bs{>q+08sbM0FoS1Y6Z)pr(n9JGBJjHAT@4<0_m zr=NX>Cr_T>)XolePM-!Tm1(J0qLfE3XQ~XO$oSr#I&})$r*^;$93CEGxm=p5e`Nza zAcwhVAYehG(@UsE_wW8E zJpaP8P>Q`>BNStAZx^rq;um=TgAdKr1a~-nW(PNJ-N4oB*RZj<1=Se&jgcWJJ6IUB z){u#e6$N<-ZV~}a+hA*R6BjR>$EC{`Fq<{_Z?D;8*jXU!-IWnZmeN_y)|CN z)L6i1_Yp!KUJ!X-Qa?I+Ia6&J>p+)*J%}dhvqK?-XtJDva|O4R(6}PVE4+$K6s^Eo;pI zG}zxe#Qpn^uv~UnTT_Te%U6W&{)SLS>+5bBWo9Qtn-kvXvTJzmQOg!R62@uh^n^wu)lO*esUKde)K8c zefJ~0|G_7?cmE0Y4;EN-htS$+7eR6~&HP~x#*}TfI~Raeks}rLdg0<~be%~EY}*za z8yna;eHy3Fp26ueXRI_~9Zl0He zkKX?X@4o#Wo;=!z)=SF(Da+o|Fy&1I)hHYu9^lUBpJ9K04;ve^I7_}T{VW%<)EhzD zBBE(qJpYyF@&DTX_gLT9!k_)=Ut(|n5ug~ecHLfU4WKbj@7`HaW4T<|u7nGwV4otk zSS;{l?-7>EIllSLm+|lZpZ^;F}x3C;-!mt>E*BC z+KuaI8il3qpjG3?CQG5pe5}0%M!Vk5u-%@)&Z%u&yLt_u+f3J`HeT>$y3i_c4XFONgWVRt}&pT7P99+{+kph+MaOmr7E-a(1>b=`SS=j*;z^ zblSLQ!Ronvk%auABwd)IpH1286T=afoFMT~(5kG*F~RMW!t6Nj*Y*`VQ`VuB;_i+3 zvrBuUn*Tp_|M?|Jl4W;-KM^Iy-OWk32aib3v$9xsRg-C;F&G?RK=$nXm3tPL9qgi~ zXATC9s;(}YRawbtB#Fo%&Y5vjRgwLmOq3aM_sH&vI$4UoY25fz6SSdvz|&dTa4S2nM(ef27vS2pRatVAhg4Q$6w?!C$l99)80 z@q7&|VF0cuFhU4uue5mXg=gus+kAWf5eIumj7NSrey! zI;7iONq0Dr^^Gp=h9qN8Aq%S_{jQ8UWY?}=B!>DGEPz} zx!hs09EMv!sD{A)?05-ue~{|7sN z@gx4(pZ^J0w>sEX`23|wlUc`~v=|hm!)3`%QS5?g5hb*VlGe7U(4b~LO{)Nmm~=w$d{x*X>HB7A3zI%$cO9NR!MZQ0B=9VaydQDp?X004D>SMH+Igb@2?YWU`mU zG|ONhK~@H!&jHTLz-?7HM|`%5iqBT&=AlaqcfHVgxy&`v1-rh*fj@JI#6`ihJ#zwG zEau@?Ww%rXZbh^iA|xu%937o7=nq+0sb?TCLY8~pmeA38o3Qvnl$imCVj@PBt~0+_ zOa?QrV_B3oUzXub?1d_s%G_efNDLsaQ<}LDlg}j*RbXBRrYox9%+amqX}@M|*T&`~ zDj0(~(b1KaV4ek;L55^Lhr!+!9WHWjROcBvjZDC~LI+b+;DZnZ$SB3nVsoR$#`;ZO zeCY<$X~1agF&GRvJ?n9Fbi(0b^v}^L$494}oDS&q#|(yJ#uJ~3=MngdK!rt|QenH+ zk`7WjS?35SSo_3sjX2C9P787zht;(%TiaLJzPioU)>YQl*J-udSdJCFrbz6a(sd%D zR6bp3&wqEEt}g5vahqNH3d^>*e)B4;t1CQu_?U0LdCbXC52eFvmkl&6|7AtN5sw}{ z=KlR}xqkf`^+t_MtTCz1GWQgv;5L(%W&&%?)oa`QtAF(`7>|bh@)y5hFznH4cChVQ z!mewb4(RGA>YPZ*62{gBOs69}Z_Mkjzrz3Wzx;c?_q{i8T??grlK9B<$wvxFpftX( zAS&o}WXt9SL1KHBx#FU<#yC%Dl6$6QG=nc9w#;R9?JD1UYnAox79V}^HvjMsA7hIK zfBnyX$kl5NP!p6tiO4>k*o{>(ts*yMnl~L?FotxIebXo^UQnjqdsrGbC}nneWxvOAxeR5l^3x#-me9TPEwPPc?uOw36v%X6n>z>p|z;p8a6O2BrZZaq3h$poRnwqk$QGXG&6>31y-503fr%ddI;_19=L>Zwe@kh)}2^h&NtELV^Tjiy3v zsIa(x{VM` zP>$Q;&NHvjYOV75C-3u{w?DygZ2rf8@k7?v>Ie~pk-iyOmobPY^58D}6LqF*HE(NJ zWDY=-GPojVxf6$j2r9I*`PT3j1M1y^abreh}aX0Ta(-GWD2F116&>z21nkvjP47h~Z$ua5SMm7}6UI84QLD zha*PgDWkE^WU3jC6sJ88KM<^MZ1T*r&+**zFR*p>8g9Lwf?`t`ZA{ARnXwc49|_!M zdD3|JI@QUAhHnCmbZxe;Z_{kG*?F|X!*3sPc5+If6jp3ZuTvI0T_^%6ZAPO$Uw!or zJ3G54DD}h)T+~xt0(z6Gu#SDU__!;Lgq`E=|uwXZ0Dezte%yl*R6qNw* zeEQb8k`i6MzljXc&4ryvi8L_Gthn8ag4+rPSDdFvTbjWQ-+t%?Iv)G%?Cdif-l1Nv zhqgUp7Lw0TD-y9OGLx*4*MOu8+Dab~6)_mmP>hPQ<(cExHoM9)SpqQ=cr5~ItG|EF z18Evs=N8Yb_oHWg*1WZrnzK-=B?F6OxfgwUO%|WrFvGmfFm0e$o5>ch`~1sX1k<_q zB#h{ClgWtP{{^X0dK70G4@8DKayw)ar9_I*X~L2kDKxGlXf_vb!q#&DlPUE2J|BGeHNW}Yr(m^t?uD1QcKs&xdJ`cfzSfb7QIs3Y^+53 zS&70!<6}vSc;?3QJg#2d;$Qtw|AHU==q>j49`hgn0sNeFK0LiB%+WGok%>SblBXyM(y<< z@$m=0OGL$n)}eoAG;5HJ-p#j(%Hx@J1#??95nmk^gL?+nd$F;ie# zbry>S&SIrz__QtwU@yV|i;}Y@PbP^Al9MKG(hK4fa-Aqmxun8OV=e2PUv_8K&Tb~( z<*&F(l}tR3gTrG^&-$#dH^U(@GoCOPg`00_q&6?fUc{eyULs1?9DY9Ol-jId7{u$;rbeXcR;D9H_-`ZTH|>A%fmQ@6 zNI-FXtt`t5!LTh5Dx9LXZD>dd(nbiEsb?{o9CFq>W&8SdZr*u~^($LQ%f|Df=OKDV zwP~@oL?i6GgTJ%&W7^ck#>|{ZVY<>jLMyDAWc$VzYa1Olx7YdV-q#!*93!zKpsJji?jRse*-oi%l!F#{r55NDAYgbp;SZkUI@J5G(TyR75 z{HgitOo$nb;oJe=oNXmDTojV(ICd6Dfo_rIt0rUeNoPp`o=BYz80}3%yQTB3GHtf3MOrzl zI7{6uF5;|L&_X3_t`#3%BAgr#ltQ6Fg-K)>euv>IR%j*Yj|P19`6GV&_Ge7IHZQ#N z7R~k+8jGo?P=P?j#X~$jE=-VHaj*1zVDoeeX;FR97usk#1-YrSX6QGpL*VN+Y;HYs zgZ4_3ufMv_&f`5M!%4&d%f#tGAh7K^{?y~%y{~xxz4y6!>l&SIn;1G|QY~izKr_Ks zDaOMIN(G!89r4S5_ys$UpYXy9FYv=3{t5s7Km5-KDI+HL4BK)Ee2<#z&}h`d;0XbD z@7_V6_|O0OKXH0?$O|t#!)QD}0B2{X-23t#Pj;WMzIg>pItUr=$Gf|G-23uNCX*?` zl32D)yVb&R95UI`PZ{K*q1W$m?~8l%&W@?s5-AkEHxBo4t!Opc+`4{)yVq~BvD)H= z=U?XV;4|)j{fJKU85}1(AJT#3Dp}3ER(hT=$@+dHvc!X~)HdW@9mSc$BL6w^@2?vC>Wuy4qRgo-aq#)h zO7@DMIji%T9r_asp3=s@40}w$Yzg8;$hx>gxopw1Y>{9W7e#sH7K6vKM<{M!>gb_V zq>en-&ZsnH3DCyMkWThsTgI+rTmor4INDu$Lw(0K30lk z>NxpF>X7-uWaD&Uup+HyOw26KAEmh9&C3oKl!Mvw#hJA-o4ZIdK86_|uTo&SjD?4& zus}O+VX%l)!Sut`C9Sr~9QlO@Skrb^8pT-wx^mhyp|dfOVf$4UTrsqUAc(wab?SPM z+OdVOO+|oNN7hIJiP9G1vF7v79`f6_KW02_aQoTUX|=BqXgf`!5;_@nDGhoM<*ZIN z20A%nOM*|on+{PK+hm&eCwrLCNsO}=0wqEZ*tN}d>{^{xyTg-*JDeT&@Vy|6G8Psx zx~?^+N$>2GKm7iWyz=@>y!O_sfJ`E5H987H$nb^XWN}0j#E;fwGU37fZ+P#I@1j*` zNA|aW`!{_4*=O9ndzayG#J~R6|Bk=@>wnJIUq9f}Pw(Ma8lfdMw~1}L1cAqDw@s^6 zEIE1f_xk)0OosNKZiHp*EhA^6t)gQu9o} zTmTxGi<<(uGD76MHj8s(XZ0ffxr>D!X~TIYeO_lsz$yS>AuVmeU`4&4W5!J4Y0j+6 z(w*T2uG@J5xK_oKSWQvxkpFyo?n#)l2{UI4D3_ot3t;Er4ZG|x7b3rqvTfIFT&Pai z9ia^>Gs!kKn?oXL$qJp?LCHd^J$>NB%p|jA+7q*MtzzzG6#}h!RyI}dDgI1>)(E3oei{}i zA(LF@F*zshHv?Gafc4D6uCOz|P=&4wor75-eRK28TfOBSKy+?%pd!M!z%?ab7icL! zTTI4^FYZ0zcfb3T@x8=O=2kDnR|qGxi2 zVg`Sj_h{CU2e6L11?^6U=U#Y`E1Oq&^xzRs9_=t3jH0hwNMYexk|6N7|IN4j@>joM z>sII$tfS{pA&mVaGxr{X5gD4*kH=#^{NR25_HX}&w}10%u3fvvD=)poaM))$8S?Pk z`+V@hd;IC2{1nHr!ox`kEZfDlYdE$Y$+tX&P&|704PSiz5xw3qQclrKIP0AdC=a(* zXSKURr_)5p^cgxhJm8a0KjrY~2puImwcBkPjb=0zT{1W*av@QAHf6F{ff9aK&8>0m z+6~sbs~jKfu($V!lapg!*t*S+fBaXtj$-%mw>*MuA8EUM`$!udzVm6CDy!HM zkX)t@FQo@Eezy{(BoFRC;qU+c5A+6-=U;h))wSycG@`gwl9s*6HffOs?IBP||B`?T zdjMU|>iv`br3aCUaaAOH9+AAR%@L7=c}E=mV9>or`*CehWD$TP)ayViN|98yY}tv2=g zZ91!MzWL@0e*4?EdGh!x{^HNxMIb|cBR3A-wz(U9?YLZi{Zb(|1L2(j>fE0#dFx+GpU6Z9kIhe6EW zZ_@BrAr?EQik;v2;MQcLg;=oN&XRVQMwrtqc6r_zTty(w9Ps<6wx7)%I7}1dF4c8& zjvLi^&)Q`{w_SNAen&STK2`#)=?#YL9~|?{GdFP^Nf>)7vfxvfT_|B7=tyK8RW2g4 znN(eDL)#lw=qMQ-NV4QX6lhgUTUpw}Z_)P8LRdy*HqUBFNq+Gc+bh`?4>|D0xjcRI zShdXlt8~lH3~h*leypstnx&gcEpfy-Hj8)&W7foQDr;F}$5@Dco>BEyT|cc2{U;%N zyT5LQZk)-eDvYR z{QT#C&;H&XbvF!?aO-t8*H)-GRx*f0MIliAJZsKn8K-0Yc{uDSr9*dZi&q*=nzb6A zeDpStzrDv_|Fa+RlRtT#J9n>e`+AobU%1A>-af7i(u(&ql^GTlWd~leFJ+5X83EfM z@Y&hf<&W>YgXj7DYPoc$|NJGWKz;@QYAkML;&DnitGJ09|Z8o^g zzfNM!IT!RSBWp1B-Z_?zv)bY3O&{a}0U8)&2Q@iNdhhMbL6q zHz%IbhB51m@9wji>A| z^g#!q4mB?30)-#=^!t6rqcOEwjm}C3*L9!LXZxqZd8F`7q7m8;9W69SLJvpfPpMfW z*4i*^_~_{f-wzi^AZ%)Oo%>&Y%YXil|39>+_|u>K3C(t!AdbBjY3M{epmcP!&(Htv zzw!2Oe$B9ViWFfI$ML}-{gYFM!!bfyv|1fn%@&`0{23p-{}HzB(rmQCcWZQ8q{y|8 zgUD7(3M^r{`p_>#_Mm=YP6XQJ>LG^JN)PW?Z5Ely|1X(>o}G`DWBU{uW{%4 z7WKM?vUH*=&J?LpNQgOzC3F?NtCKxI$YPK7ai`{Ftq^HtXvhx~mP8nj#584X%m>I5LT)ElhR9*D!Jz4^!O)feP4v zvd2dsea!nGyw6u(?(y1d&mg6PC0zm)WcN+uYQ%$Hh3D3A`YAmp^l}@Nu7n=tal+Xl zIK9wbH}CA3ncilcGnMj(bL`>ez$ll*nImOpz1O)za@h-5ekO_8Z2UY|i1QUJ#?Od# z*v9(O6*=08ecl2;f6<}r%LTVZ5^K?7&%P+LE-n(CVb%je;CTUi`$rs|^jKYO5*{h4 zVlFx#v0DZtRY7oHc)+5{zAW5|!St2f_tdRC`yWJ02~ z#b^@n-UpxY_8&fBbNhL2-hK(oX`z&b)-u8p3L=w4u zLdqIevxO~f9(?tP|Ls5ie;E&^{PfR%%G$;TSR!E)h1OV7gAVxS-aUT*+uv|}xQ7Zn zv?c1-= ztTlM|onP>apS@4pZSc?k>ie`?E(i}P6rsaT#q2@G2Pg)%GCAC|(wv^2@!4me@%!Ju z!?)jli&6p2rr_$;t2CSKP)n+XnbJ|DaB`r=bR86WdB!jg5>qKt8Bobb70({co04l-3_;;N91JuF@bW>#rs7o4m;Z)r|;)q}pwO#Or^|fdF!s4nJ7)g z$xp7v>#)+hP?X9rLMH?Zr5tv44*2~aJ|)m~o_+px8m(146~<*FEre3^dp&mcb~rpZ zWH=mRI}RHg>s;O5rq$_$zPeIUF`ifcY=7sP+jE>aW(g-kfNN<5fyZ=s#?jsbo_zZi zrw6tXoK_36#Y11b*P-2VJQ`&k9-?8lFx)^g8cz83+sCZ5*Xgv^v86;Q z4@)Yv(gezjSW892weg!xyy=kPM4^$`j?1l^&+*K&udus&!rQ<7i1+^ZA@{$2hzbO2 zoi47WA?VSnY1X@SJk{r`kKX3-&I7JL`yy*sZ{sxDp^aRwt0s(pWbDik70f!&1fEae z`}lr95cmWt9sDwVX{EHWZ3o+Su`LJ7vLoOrQ=V991QuIccX;dj@W}_i;k|di=I+gF zyz=TzEUCi6&3Go#|Ie3aari?R=AnXsUa!Z4`w#g2@89L)k3Yqm`gGSi*p`Lod#rUg zaGaX4XU+DGE#0RR7l$PtmQs+YjZTuz4SJgnK<7Po%+HZ_MCWOWE2VGfxiPwnx&`FV zGEr_+TnTO$b?`}tyHnC<`8_W6AQmK(`=tYI=eahO*C{t6qKz4wMF#d3Wp9_oISb9K zEHqPB?!&xbRPWO|i$nr$Lw&7eI2^OLf5>?1(QZmq5GFPyjBMqmQLO6B>P1x?f7$@d z1;CNB{z@y9cz;pJq+)4ic+`H>g`1hR>bh(ucOKZy55&!WAEJC%po&$XdfL_uX-HDN z4C^%^0J(o%wOI60f} zhd+MC!^eG|ec=aeT)BzDMI#B6W;pEgXy-8xzI{M{&}U_3g}Zlev$45BtJ%VJT@)m7 zy#=etR{_GmsVpP*KS6$022alij+PLH%x(? zPR0nS=(K7`u}*K;WHOy1EWvP~`NhwF&wro%meZ3SffvwjG-hNTcR+Wv#|~ z*Fp)2b2j1N_yM1PaKz@(9#?NaM|WczY!{{CcdJmr6n{F#pN{b+Bc{_axw?tF&7knvFJ&TgS3&ESYM7 zuWsK2|A&13$?tggy|1`&V}s2NCu!3vts?urc;k_=hYz8y-a?45qtQF-^YvF>^X?x% zK}@ZP@B)qwTO{OS!C(s+BHhXfs8hOdejXQ+i)1jb+L3HOLwl&u-h3YF;9c zFA^({)V1KEAh)Ur(lhi=v&yD|skyn@=Clh+UokQ$7Zohzl21}%JD0vKSukcV1DeYg z6=j?B?CV*6Ps`qid2pEe$*Kyq?EUE|0$2;1(M0jlr{D1VKYm87b(NcUUIp1eDS_wt zJlWmhi?6<7cW;lC)ebMd_&i(N+jKe|EXxiftd+_bB>dAB9f(D5WCF}ZG(0GjkI+87 zlRX}M^$Cx@{uFO;%toiq=5~utQ&P7jQcMYxtqiG#aaP zS2kJgbg8)wgjOg$L8~(yYr;y$X06-7u_R|bpR>~eqp8Ab)@an*ctPl&tUTC%a)Kpn zYIcKq)1_u>bTGj4PHEN@n`?E}Rwa%-K}fi|QK#9oIOq>~^3{9n?|j4U=U!p^=CjmV zD@Y+ZJ3ZuR?;(@X8Ok3K1XCbDSPDymYY7@1iL@-hM(Y|X2=M(WUf|*TKAsmaop?+p zBc{VsMt#lRm`P7GNrwuc^buvZqWs{R>Gh0o8;Nt{`+WE&c@=zcOM5h=M#s!42X(ZFmv+lE+M{sA8W*mZ)32dsa*` z)wye0RRmTz zY<8iiv}9>$irU*kH6=18`!VyWlt9Wj*IcLB@lr%Agf3;|vTY<1WBG70xyV2*17J%N z&kTk#)((jXSS}|g5ZU&5PDdO21hY)>ap~BmB781VHs_xbdTdrZ73&p!Jc&prPf zolYCe3ALK36bAntQ>6Bz7;hcL*{CRZPDU;H0BQNyZ5P)P9G*-$8%_w6L({2YA=rEJgunfp9e(rc zU-8T{w|L?CXQ;W7-q{$(X`-i-2;53E5+Q8rZi{+tm6eqZx+`lqmW5UmR4@S5r%{`- z-gQ{-+B9lYY#~^wIh?w64vq$#4JM$$aa`<16Jdp{u+(AXFu|B<{{$8EXf_3#YaO~> z3)k@=m?AW|(qgS))2z4Y3@1F^-{s@CciH{+YwkYx3acC2^pBoUv--UF%2hVj+SFm>3n4{j5L0V~QUQS<;ClhS4}PHWr;4c;Fz63CJUrs~_>{xL6ON7_ zbN}AgeEUtE?&=lRHmuW2K2eBXS_aR&XZDGk! z_Au&?`RdD1WBbX+UvYADg6mjZyRymp>MCxn9=+#)$!H8(vwig{?N%!~LjuY*=X$1U zMi+8GNr@b@+ZCJRYvurxNLD8D5xwUdlqrJSauTRak9%GZ)r{Z$JODJ~H8Mm@3HlZb zwA}NuJR!^3+w-uUakou8#Vu6N(aX*v%+Bx3abCbLD9YOA>!s)6q3>RUt1CW;i1XbA z!{LP8y#tLEO`v{>K40||s2ghzlQk{@lblp1bMvHoV1=p!zON|Qp z_|sDyIbeNVve9*EHwCU7VxbX%#*!}1ibJc`=H$%d_-smlaE3PmAuXikf{^IILwN%% zF=DN2apg*v)s;GyoT8PFBtU9`3=~562qD>Q2--K+**_WZJ&sS2RdS{qktV1&OV~mGx&jGI`ug{ z?X!1q#FHln?C+m(eDa7dcE6!nZ?S!4gSBppqoYIi_m1hb+M!c}us~QLYpO#%^RPeW z%X?q*&hP%n`|p0n;bD(xKDr9E~^@~cWw8|DLYSW#sB3fwS z=h|2zE>bF9XSn(sWcE4FO%ArLSP0vvv=*7@?A2mJmI?=T)uc;TfNdHLm+SzTR?;;JM6XI)ZumFBRDg$fIC2|I-O z8fxZOi$jVs{&N{#oXK#E5SnJq!P1IJ|AenU|A^1t`wgxh@#3v5Hdh9$zp;CYp3Kaw>?+oAbs5w5}uBN+Er_)x{EgxI>SjrCvy8umq6h3y{rs>+O zuSiaNnv=60qwyq^ehCY=X4774vbx%#*%Y|0M93*xdkBKm2|;=2APl4sLSk7q?s|)r zdX1gK9#0;A#^DZhnn7LU)KD{CCnpQvql{SAx zgcR78q+YXGS?O~7_BvX>#B`$R^(XA^9CGj8eRiKb=J@!4@$isG4{vkp<_%iyMl^sI z;QNZB!xKLJ_;cR*{kwer={NMxCaknAUVL_o^=_Aj>tY%9WkQ5e&S%2`{a%mfUV4eE zSGN%|+}ABTTTGdjiVF?pl*}~flCGo9M{?_|#n?r`Y!v_#VzzI%*4kil&p*dwo~31T z6|-34%Ih3U;Uc+V{(Ox8kvR+ycVw4g3(xzRi+fn^we=#eaRIEbV6m{s09loW`Mi>c zMcLb`pKJe9IP}wlDQxuxLBPS`5r;>oY^<-wraci$Qd|U!u(vwzgKG%3m7(PkMpYw( zRdT}FU@BR!)vV|Wxthra1ynI1-x(O}F+AAZia z5BIrs_j`2LHn?~1OMdtJcM+DwTi<_+=U;f9X0w$#Sjen(5o8@Qb%BV|^TF+s)8QF* zyn?np&ytbRVKwNV@%YgrR$5J3SJpV%d%|ZQyuh|S!;6Ib2#gb7)=9I;2^C= z=ony0lnnQmQ17qM!4%&cG4TgT;nAo|R@*KsoshAuIUbgnU=v{J$kr@b^M1qv`bZ(M zYJ$3Bv)Nt6Q+~8BNG$1KO9#u+z!a^gph6~EXr0(}2^3O>VBQ!5`k{{=JWR{k2#4;Sb*A`RAWyb$yLm-9}iUR6s?Ag3>Yqxgw`kRc5NTvCd>9 z2arf%BP<82E~(cVY;D}-rpM8v!7E-!6cAe?OgGCewGZ(4UK)12bb_%`#ZXl4xBK5lLqYw!Flw20`n4s$Oh#a;Fm0cqB7B)zke0N!&(*|xCkUL9%{nQv-QSycsn}W}7 zVhByIH{{^pi07WYjj$|4Bwv{4a5|Tc*X9K(KUmXNfyjYHkP@^K$>2@e!Z1ObapScP zjmt?}bE)s6xtL}HwM8qJ%YV>xW>UAI-xVdqeE)-4p+9X^XTytKK$qt>UEdb-+YUkw{GIr+z4z$>k^Evf+)q_ zCV{IHNzLpOBE9Ix(~Cgn^IaFT#+yvoee#I2<9#-oS2=oopHJTZ1H0ee<4U)|GdHi$ zsY|5tK?RA?f1m9nc2E|w(_g!>f)pcPUp z>XwDuc4*cuIxRTu1q_B0Ces1R6Jgj!Jk*B@8CU{rJD^$DtgO~pTXktQY+O6Q5&=?A zL3vn7Q$N}tHHoAv28u@9DYe$JbaSxP_6aE7=D$eqp5m2cJa0|Ux%fG#DIQeuEh{alwp zq3G&5e__m1_8AtD9OUP2MC|vM={CfPbk(Vl?n*svJ(h^i=M7^e)_@6EOFxUw*i(s8_AIsmi(gAfa+8lb!`fxoO`Rrf z>4>oq!qmL$+{2|Sm@3okpP9BP%kCIO7B>a0g=-v@yIM+Sx7=rg+dS)Cwz*$65RMC+ zD)v=ZxEjm?v1OJy`9!%w3(olW%xT`j&rfn`i0nnkJepb%D8bQDpMHPB#>O=U!!aL! z_6-QhTi<_+J9nPJvMr|5DW|7>4v&toEQ{^!tJE8HvWayjvegDy)wxbeQUAJBkvr?) zoK*}*=~)?b_XHS49s~k}Rvhf_^60_WY^}8!o$m3~rytNee9XiT$dpY-!@fD3sx>G9 zXM+KO);#mvGhDlV72B~wwi{K!o>p5miYouq5+-+ETUcZW1N~INgxO9n3+cIhFu0s} zIgben1$1OyFG~EI$?eM~Lpck$oo}FO!Lw@#PuWGh@RyYVWMqj3iI=_~W1dPEEi31} z_wQnW&0g;2To%Pk4!{^ux;h*-rBX&Y2?83a8Y=X7$9EfzWIt8V1 z)TGHkN+}B!O!h&jsst-GASuFW<%A8Dlno>--Y%NY7L>k!W5}$`)+_sdX18Qa$%4+s zASV|?m4VhYQKz!XOWKr|yIGq4=a<0>&$L3T_kFku|Rx&)v`hh6Mz&0-XU3HCE>MP0S$iwvC0UuA7Z0%*mc-{Zm8Uojn=Vy#%* z|NI_jdk?sFrNfP_4h=^mn1H}GV2ig>jIQNg8>XkDjf)4HwO4R03f zTAsA2%W(L@-HY!6+%64pFZ+g?mr0shA{_v5cG_cqcb}Wru26Ht0(g!0Q7F*m4PY8i!Nr>VyLp!lpwxAc*lVq#t#qCn6q7m~>4vP%p zW&BxnI#sVr5_$^vS*27^m1pomdf9U@yiaF+8%(~GrKvp`Mj^JYiL2qPgIU&6&WxGN z6>L(Nt$&p?qJ^*-4u*XDV2ANoF+CYD7*2Tk>)bSC^&tAAC;#;1RdCJ8W;RPufAc(rMM+|&nFd-)#(W3H z=oeW(b~!-&?thuX1WF5pmW)Odc6RsZ51zs8HY1{;Di*OM63}QBD-&?U2Vs=!{+})Y z0Du5VL_t)G9+D67jaC_LZq^=5S5{qVB_u0BsbyJMmW9?1K@ddjgHI5s9C)7h@GdAB zDPaQhEbgKngQcyNTs6EHiJt~`WD~o}J!CJ#OVO<23!nL%tqEZy@R_Z;WtfKI(v5tI zOa6)!sV8REKQk%QP)cxo+@s%{Vq0~5UvvH1H538=@DD%Z;NXyEv&D4k(`dN7^vY|z z{K{*zT5Sycobq%c%S`D=R~@&wdRTOF=nS;eseg!aN|X)WmW`aF5G z&&hG0Mx)O5))h9_*Kr&x(uPKMg*tpkB61>-Qerh4SWM(;0_VPaWSGoh5i^F4gek7gSL(vmo~ zO}$=crO{-gy^1ZZNK>n^gg^#C!rE$67N)aNKq6*|WeDVl<1sr22W(v3;J zA$`!wC`>Q+@Xnl5B^SDS#^iDsM=?h_RR#94E(m181ulvTmIb+apcZRI%b3yRljs-= zR1BmGX3iXxxh`E4*ewzzKW}L4!h>F1hv)297CaLT)((NCE7}Lg~q@xYo z_X7?NjyXN;v9{VmXc47fRcU_8ZA7Ys>Is1-VxbpXZX3~y zxkW5$X_5%2bp$mHAZVJg7rc&R%bMu>GVd>U*e1n;>1kYA1PFw%LD+bHz~SKuXQv|q z-^Oj)4ErbC`|1!>4mSNH7IxcRl zhHbkzu1&30r`2lFY_@1Lo75Yj-ITN(r0rr^HKb)D2#1xzxQ1|%t0;m&D^1{g93AX( zu=9{f|Bz`AaBH*4)_NPq3iY{`2zBwjvmOs0>@w(2xU$h@`|4F%jRsc6OFH(uHScQx zN+A(6T?cn#1ILw|_Rlyu)^xk8)M~Y8Q;n!tp+mqc7B5!6I}YibpeS9nIff6k^3pII z5jsxP-5M+H2AVEPgRcYpAdK(zqBW&e5O(td5ABD~hLnP)ZQ(TP)La+Wb+Kdlg3(oo z3ksn%QiIUBBERw(*U5marvi>nPY8tMtslI_tvfeEJ+%tRsJ)E=VNLeD(dPiSnQm5M zBbH4@i>=GTGf}5ZWWizRd@E)aP%>Y$5CU}Rt4hyg9`nB!BI|Hueof8M&zi%HY2 zoSpSKJUrq0wJW$*kww!w-*BsV7;;*ZJZ&G$nGO|F7=Z_}5)dU|R#2e+wbD7+K#_xwrpZVt41u?p%O1>{#4S81#;GJ0VQnwaJ}R}4$^gddPondh&&+x-8C6|6 zzf_v~CaM^&3UF(_=cv6Nv;TQ;TVNIFkrYJoj zPyyqj+j+6qw$cvCl5I} z*um99u5N5_ZL1wJx5`Ia;q%iw>+|r@4&%v`?X7jTu58n2v{IdB3{163K(4XMFs<@z zN3y!Qg0v-rVVJrpxTpO!h}rbT-5yc%Za1@YDfrj0Qwu*D;j4M(l>R zl4sZ=bf~|9UydIOmK^6pe62jh(ywsv6C}$z=U3m7t|3;r=$4h{$Rk# z=`qhf_bhLI?+qHw21@%;fuoXnX<0_1Xfm?|^H{W^USG^M21(dvZTzfsJ|zt(N{65? zpPx!?Ck7te7uiSZ*k+=ZQgk6HD3ST8yuhZ z_=kI+vAwa)o3Fje+DbQ+$BZZR$0N>qC!C(0Fdp~urX!S|06s$aIJUrXEV?b5`g(&_ zW0iKNNxRjc*{IW~ySOzM*Ku$iC!9{VMCf23!=g+Wj9xtXEu_GbRx;3`l)_hv$<$*s znJ^lS7!F6Ao%QMU`}F%GhW!Dfvt!QozadZ-uG?m%dxcJSlUgeTyspy#p*R~4I62rw zd3~;I*4bKb;o4y7kl9lK42MH@_x2f2rfhC@+1k89quvN*3rZy|?R2!slx#%Dcg&zg z5YDzGolXb0RttyEPEPT>DQn$T+*&PV{LA}%m^^+~N}$Uh?n*2>N5Z68+{SIr>!fYo zcta}=!)Ax!bOJuLh=GF6e8dpU24R%4HoQzTMMC5OAw;Gt5_|X>y_IAOo(*n8u;}?7 zr>7@08x4N+qaSeN#x*QkB(D*VWM;Eg&(Ay+8~}9reqQWK<=m=8whq7S@Q2x-rJ9^L ze}_D>BGko!>0&`3k~xPA!C;UFQp)tqjV!KSRP zZHk<$OqnysMTZcpaK${=kK&r8nh2uWEh=llZ_aG!WS&E7{d9)R&ZGAzn%YYc7M`!z z+dtyyxJRemfFyiDS3W#(&_bq_VjLTllj{ZNfwYpYhGp5)CJXXa$pD$oEV7t=%l_eTDLOB*uK8h}WxNiH)o`JV&Vacxa9pz z^3S<*_cs0En2+E8Beqt&{PGLfOnLOpCkzHX#^VuznxeIj>soAYG+15Ppu5&)Wwk-O z=~Am%)ay2N*THoxY%5HavSb8eMI<+nGD`n3b?Yk9-|B>U69}Ybg+U3njTBaDK^MU~ zrBknJr8J%&;CViiiO*m#;rOJ-&XYrS_l`L0pKy9`gtzNpxh+;!uCTJQ%DA`3=xm?1 zE7)G|(5^eUBES+hQfmgoAqRU0Oomggtgo@Txk1f!2#x!r;XR>HB9=zUsMRgf&m-eo zt&HPDVhKT`R>NBDA~>aY+G9GNvcA4fv)M@7z487ca$K%Xr};$=m?iB(G5a~5C&^r< z?YP_?ZYIhZper*!5f5jHWH_++xW^?!)G^b-z>+x|zTAh^A`1_7VI)tNK358juND14 zpCIu0!S{c__uhDox@)2ElR-yBo*9)F9;PY``D9G*%2`};vDv}^d&~OKFTyCMiDkM} zB6xwkiy7yVFk8e~aFb!Wv(}!;S*!B#;v#Xs5V_&1;^z{j(u^`jco_}!EN2Xjp2=d$ z_}+@LPH$D`uZVSKfm4w`^G(vH0>~~S13WLdo>k-|Ul)W9Ec}y5GOJ?J1X@@qtvNpK zb8vXVt(#Xvy6}XgPzI4X9lA*sjZOKOCbDADY8&UA{{m?zHV}Un<96^2|`qC8ne^oM2js|h^XVs_^We+RaNP|KcfVpf9pbox_4O4tp4;Tg<{I6#72544 z^}3DYgdVJpBd{$MT0v{3Tz>9@RxeT1$I=7^jJ+viZ^{cVKF^>3#hdl`FKZ6jLN3D#y|SL%D5utxKl(wH<@ko2l7ZgL;GO!im~ zmUZdS{i5lu=Cv(=Z(ZgRlf!R_BEY?i!!9x!Lb4f+eD-#a8IKjU zwgtjUrWu9EZ>%PGEMsSLf0itSEaRAh*=#UDaWRw)nU%CqN@G`ZEqsxcHH5ZAA={*a z0Ht(dT_)qhR4PpQ+su2nkc3ZU9;CeFG>+^OB^zxBXhcq4VYnp-Lx*Q1$z}Ao(VuI| z94bTt{HtS#%?(v&80Td+d7WXZ7X`UQiA*|2v8VpOW#6PTGMjint)#_kI4PuhyHFdd z3Fxde`OCljQ`XiuxN&m}+X)ztdmJ4;#E~PmH!W`6Y;x_|9oE)6Aw%14;JQvyIBDgf zlm`R|r9&`lwv$!#%tj;0Qkc&S#y_!kT^h0k5~fxP89l?XD*;h>F3U}*rIZ1GZRV>@6#epVw58525nxGFv2%SJd}MN zl~eU4!&y3-+!d8Y$1ML@U0NhXt}^-8&=qS(lox^dd8BzE6ncTRqbr6T=dSM=fL)hY zjG2VP%{h70hHN9r@@`1z%I$>0$aT?E}{PVfi!T`3i@N>*zDJcl2Fyd&+#6vdx{7O+; z;h&ee(V6rkolP<GkVmc(f}th83K^bJ0JzfS+qqPtSVu>~T~_`XN) z^n|msQ<|+N-EJ4lwh=O7@sgoInY7fUYZC|?Ut1jZ`aFL0gu3f+b$g3WyN+XlMK~-P z`x1*x7eOJVWNmE?AuOIe+2irfKAs=YU0cOygW3I~wF ze`OLTGp@hnT1ZLbUT0Xg+>TnfUK9B9p8JR}gBmtK9DyU#xZHUxnO z%s#X=i*$IF1CDbURZ~J26^v!TQ8W8|SccUr@0#VMYV%oJo$FvNg>N&t-lD*q=VxHD z-n<66BC^GhRI1cUQZINvtGWo`aCzM65xH1pQRoE6jD3{@!aV=kvTIxQTC>hH{gfl^ zXMKGUEpIaWRq-~}rDIEP6DxFSM5mZQ;dHKy+$>5w`pgBD zmx`1!qDp55#>(1M$w-S~d|m2SE9FwrgtPzdtb@lW>O{;S2H^l>WUnN&qUJi>x_K2T z1VI2=4^dvoz=j8+!Ln&xoXi!nWHZ${R$mxhk8B5|YA`bk3`(Yq$p$tMIbvv0WK-h9 zApDXK+DE7XuI15b*|;{KeWcWkreg+!0rh%~jg3tj%|;04Bi~+uL|EZH41$1(=P~pY zLto&Q1(C*tFn{S!if3=c$41-$awtGxC7H)*ySc)k}I4=dxm zimd)}_FQKARaofCrwRlLXH$tZEKQuey!S9`y50o0iwrVV0^JIYWu8zmJAv7aBR7F* zN<>UuqXGQN&L(}q_I_EbKkuYe*bj9%TfB%T?y?N|MWcsjon4E()?(>y#ouSl1xh}v zTE-@9ZbTfM!|l3yOO8R766ui7a5Un{<6U}Z&(N&3!=ER^1f@*8X<$k)K;ygZnmjf$AmYou$_dXuv zlC~j{P{}lMcEY{tDHJ7bUoc07Oes#{@tkP0MH+@71&i}EIty-$f;X#kHUDnvB!N~4 z5d}C1pPDO?QlWJ?Amlg>>+5T{jzg_pM+*od_XZs~Cis&n{r-T{vmt}w80|=Eoi&_# zo3XDMcp7i28BBW|o(;IN(dWk1D{QW>Qm@r;5C}a*CIv&v%t&d`S?PeZ*xNtg@aTl8 zH)VVK3XMhsnX?Kr__u!|zsh{L1sR=frK3sQxk{N?o!Ea_5Q#hjrSScLsqYi`p+Bzg z`FLJ{A1H!A5hxWg_W{xZ%a&M{g|x#k9ZO1V+rhT2WN=hz9j9bO>owg|yuc^$J#JjR z#v54!maLaiY|SV1#JS#o zRp?0JXID5M*_U?XVogLzg(eCj&hlZQ?26QxGuHEc_7CDliUh(zbnB z@>lsl*J7Vd=bXFCj+;Cv&J~&2rduV*6UinS>rJzssv@HsmxjM?{MnTX!EXkzCf6v| zf@Y_j3sJ^%HYk%>%ja2NWaG?7KPI0$SD}=F>QX(?jE7EFMGsa!fcYXsBrXe8)#dp% z8iACH;BArd2N8wvS}P-GNGEf((LE8FW<=Q(aOUsE;5Nrf#(-8PQk(SaLK^YJh{~=` z=1=mPs(8Sv!XH?Rcqk+EMb(im*^(OD0!zl)NrB@!)N3v>^8KB9K4Z^g7+I2y##6?V zDWIq|+T6T*i(Ahwo)uzJ7ejgaD}olaXSw*JI)f#=c5;W$$&C zR=3no*f{&`i!iszVlxOIG4~M_iFPz@r_7fcgkSIV2kh@3^6cHKIJSsdRm$WfbM4No z^KX?Mh`BkW!-s;ZX}_{yhvH3>5m3>kZ1t?yE4v4Ia2{h95k(HivK%Q=%}<87O+c?= zUV75J>RTro;Pa)pRGNhwLukut!prPW${Y%2-Mcb31Ce7%tBQe)9h&i=ExY06+5DCGM#dAcEZWoh|$ol!KgR57zK*7n;3BCtcwl-O5H?V{ZWh8`&YpP6(`V;}K z(7K`=Q6SS{I-La0gmzv!N}G&IwQ$H#NYEC3Aeedq) zaCJ^b69R2N8YBw?91@or6j^KVq924=9OflrCMbQH453*pUdB(E#k3}SRwN5b1_2jL z%AAEYRNTU^4E+&?#4!hQE4LI~v1~E?zWU;*em1$YeyT@Ve=skWo7^o%-zT9Wa@AG;1~i zK}Itwq%23^W(xUck&a3mMrr zrEIc}+ccR$ro2=me*dEM=T}u}%P!>76f=Vb$VWjgnsIIFKj#$^rSHF_3t`URij2p% zE`TtR0iMQsV7C8YJ_KVSwi|Pk&8M-MsebY2jDW9D84pEMhbUx~?l%Rvri(?HZJr5! ztB+bSo1)g)1i#cW&iI)zc-As4OpLd(vfAP0S6<}dw-4EQvd3uH1_k56i2h*AWEv2N zfJU>y?dPuZ+zZd~+>6g~_1ZS;8|$G~)^V8z3NH}!Mq?iB?BQ#8;gwf7JUr#z=U;Gg za)c!$O2Kq6=5#P-I5;Diu5;_^CM(T4mb4<)Pb3>($j%Cy^*Y;|n*>3?!SN{*&*#Rq zE!I|ASkewtytGPnsNaDKMwGUCO_Y~SjnrBg@&pGVtPs=+i5Dow<0-@8kkiv4Cuai& zgE7;I4^bg5qsZo3tx3IJ3%!x01w!L{6Z~L=?*-VF%Sw9%%d%28jFThY`{RfF;rAcV z>eRV*;|e!#-DLaP78_gZY;LZxveLn_Wn%rNjWmhWGuDVlPb4q-zI*DYuCo4=WQUw) z48a;y&$7H~93?Wlz<)aJ^|`HKy*yi3^>fU$M;+OD3BCA-o7dJC3wG@?M2V?y&dsri zT-16Q4ypodB6CjY($vj)gxYz5>N0HY(=X1>@&0Fl-ss=1O+g!wFMY1=M-JrP=* zEegsmzEESyflRhc9bbzm@FKnliH0@t(2XS#6$_+dle%bSrb}cVapWsAAKvs3F#{RQ z_a!TG$Me=X$=c0roQr6F&I1@SYiW__MU!o)9M~yp&$TY+=0nRXImd=dlsFxjZX+@o zf{Y8wj1(lk{_`SY(S$8ue|yqzVGq(Kl>%$-hYDf z6s~1+?;H*c_Y^$M*{hd^n1{XV;g$9(+dw>;TD=Hc!kqoK!S9Pr@5 z4wI?o`#<_A-+ODF?%D?Lyz>rcr>7zN7rp=Jxd~Y<4>|YPE1+Hi%fl zq!3oLI}L6-SCN)v_uzyF_a75n-(O>~U@i36h+}qT=u3`3 z1sa8ouWhE&fYE43e>CCbtjFm|kIC4__rbBDUaPUvY16FNsW}d|V_`?ySpXHNP@W{f zx1m3naC&si+3^W0D=Vz6tX_?Q3V zU$e5>j-)v%%gBl}utAUox24WFf|54(EO&*hQ_Rx@o8?K4=Lar}3{++2B+l6qUk2pz z6hYQPV6UoUIcJJ*5!ZnHYn(?DJZo)~`Y4yBn2PE%d!enTayYOAyk7t~XVP=4-m}WN zD41uxuDp*WRiwx*&P-=qCtA@o-HTM4H?t*fyr0My_vEC%)b+L9;AU^tKWO|!;z62ltx3Qt)2t|NU@ltXGTP| z5c&0*cl1b$L|q2hnYD=+T3m7iBT{CcYe7arWHP7bAX#$oV?=|_x(0gI$dpJl!Wz>7 zLm3xckeZ*w?ia#n2&Y=(daK6wfA~Fa-@e1{lS7oRSnaIR-Q1$lS;KC$kZz6f)Z>eX zPk8^sPx#=&kGc2d0}c;+jFm(=4VrF)hEroQ9MfsH@wH8Bb)7eV@MGM1n~y&HkliPb z@h0Qw*|X`5eZG2l%JIpFn^)Jld3}p+rxmVi?MJL^yk<4cW{n%yuOcm*{k+@z?D&F%s-_s(5%y&6>ds%Jph2L?`DpN1f?M%C0+6Y*>{Lf-0 zzRk6Y6AOUwg$TC_Ygmzuq81AlNf%i`wnAq^5Eh}|%H#`Bm|{yR`({DLEZ|)T(^!BZng!}pEmlbt zDN6ESGWADK%fb1&8cEt z$;M|HWz&B-I~edY4_;VJLD_X)rG{ri0M=~tYb_Hf)5ozAOt+FfM5NyCze z>6o$i1nfH6YK9=Uv&L(0e4oxrm-pX$m-}CT#cUH+^4%pc}AW*P%WfRx6LXaEpo$<81NT>Pp1g}8M zOeCAdJ0|C?2#3SsIAtA?X@OFVMiT~u9=+a>v)+)wXv%mh5YndITA|Tw;nwQdwjIVg zN5!{@2k*3AXr~j>qF$?GTQ*+ZV>BAlJ3VF4Kcm^Mv%0oQ-L-LSo8fqX3Ibkx<5k{# z^9`EK21dlF=d5g;HRN@R_h7eUYQoW3KF&CNl4rG+CZ|Uy4lL%h^jRqa`DpTX6n@pik{o{iDPxcMLk`v@F)v*03#y-Ms^Lb`P2QnyXuDG#hS2E`&iGi6^kg0;fee+?jX67-9?^2qb}0 zcvGLzctY>2&+$p0es4$+Xl&c1QE$^-X<$2{jus)K*U<=-ZTlB&8>>&SBpgNvX*hKV z8jS{<8|!q}R&Z)Iqv?p==_%V+H~HZYzR%iPHym2iDq@LM;_aOoRw7Ch%t+aa09R1# zh!xpeQM$Qg62wKx`8o$Ii5cGORj_R-yjTJvvcOm;*G^Qt*TT?l!P|C$&vy<`m1m;o z0jP|XWZ88x$dW=#?UD`*rT1$l&_5rjU6d)8QdG(fVz4-q>75min+vWGGo*io>pgE! zaLJB${3rG@FJew;S1|*n-fqUi%l2yLuKJX1O)6fS{$R}G$NSv8zD=v)M1MI*XIDg- zSUb;1&0mDoi)6OOwk(mV`gQYD^Rt}^76m`0fL9w!P^4) z`!!I&VB z1X|K)wWv252r0s@kdRnzlWRBbu+oimxxf7l`%fMLA(JamOvfI>agXt2%6K~E#`Y#_ zD=lh5gsF^CEU*>=OG;K&Ita_*@snNl_7Bl2;M(>kt!4u$v!6SOMJNCSGunB9%_0Mm zLeM7&Kc_dHa@Ol{a?<1EWXNDJ4P_wp7M)H5*R5k)4wkUefn!oeGRrQP?12SOQxm+0 zE(hcBh^aS43g~uM+1TvTS!rT97QR2F*E^%L(&49n_EVmD_Ac7e1c8d|6LpdXCy+7G zU)otIE20a8ZbdgMk@ZNCi450z4rs~m3v(=q%E40hn`V(MrA`ASENAvv)aR4ICfDUW z-+MXj`m%z+BtjN(RxpE&mQAKx2;44d;Wg{`8F@mE7|N4M+PDUZ<3!o})P_V=%poY2 zU}?*UqGgJQf)B2NAI>*qmI1l*+Z0uxWswga+Tn^M?o$fzJjJ7(15Qo{w3=&1%T^`n zOPPU!-V)-VLkMg~&Uun9EOpN)Z04>9*W6QDH7hvr>E@iA2S+GkwW4~mrk>W=S{%ZXkTL29Bko4b%uz;*b1y?`TiF=M1%u^ zX`HFj0YMPpO-GEzLxg~Kr^)JShn1BUwYrV8G*dOolQXSANfTFx7Mt13pS*Nic! zop^`q%-L12J*((oS1%5uO(De6oUEQ9fvF;hG60>+3VO(ZT%BXn#CcxM@DnX*eG^4- zim+97aB$4yCkI^FT%+dNhUrS`i7ArAoY@ywT5|U1oHJ>fUFbU3QWXniD=%LeC&N5i zvrHIc^3DtfJzOA)cvvl)WGJ!ibkIykCg;g?dx?!nlBmPt(S~s}u_;}Mhp}SEgrYn| z7!%ON$2{I}@*cv{2p`ZTZVR)4o-P2}d?lK(1zVywoYzYi6QM-8&6rHry);7>GFkP} z@1-{4JOvln^A`i93A>u}!CiVNTF*H<%e*erPpIO8OK7|Rh9e)J8p7?MWD^yo45naF zp_IlC{7}ECd=MJPagml2x(7tSNr^O(rqOKk%Byd%wzkG6AAiVapMA{f@liO?DZ$r* zvtht^e9Y^Xoe~JeTR-|C-}{rduo^ZKe~b`;k>r@}$x26I4J8TlqQYrJFL07%V{xk( z;YC?3vD9G@4<9DOr-`O=c69D6BB~TLUP@?$Sa?q@J0mq3{f`{&r;Ui_MX`^l0%r@5 zXL&#?lcC?DL&01(1hlaO%#kY1I-_(s6PuKWCh2Js9D4a(UZ0cDzgUvlIZC{uC$2)o zzO9KBRH~0ka^~X}w^pD9!~Tdz51;VNottcKG||dW^|R+#tg@n29ov*8pe^ySEc)E# z6K%>Z$8-scFu(e`G}hL%U5YpJ1eAr>HU_WxiZpJc#%>r&rCIC==v69fgQX4M$xM8* zFwD`@DAUq_g3=&_bbv-x79bVOZ6LNErfVEt2@xXnYDKEG$QGWEva&WN2g9i^7t#{d64|TbjC}dsi zQ&fSBG~G@D7J|?bq1WqkbbQ2cG{$usJpbGkHrBUjHrhyOVG*W@b-U}VuV3L{|B&6? zeR{nCL7?e$R&X6>Mlglx>H$hCyuf4XO_+LPJb!}kPq8dPceTUX#yXvLi(1VI3p5eB zE_lI&gOfw-n$1ss`V)TeCqJUS+QAPzgiy%B1re!~NrXkcQaMK*ak1mB@OSj=hbsxA zNeZw?<2ujX#q?z@xF=8=fUxYDc$phO`CLMt94Xl+D!}ZrgIHP5-V#l1?&}({&} zCtr0=XZ9x{7N(S*IHJF71%2;S|k(Vr$duXls$I2Q%2f$sV2Dv=U9J67{WO9*s zUclboG5d!ntaV#RVF5+M7jt1%1y7u}2+eAFv;hna-dSXWBtk8i$|R(VMO%~Y?N=1+$MMGSH+nSF4K4LtjXVx3w9c2%gCBnp`*b1=|)Mm3sa zX=F70U9{HCzE-?R2@K1)JQJ9o49z5kQP2z4Cwa<42FX+mCX0C zP}m}Xz-RZwV>Erl=-LLiwl`?iolu<k|w7<{({sG=(!uIwit)?3d zAvev!AYIlvATgUf(j*pKBd=;%pi4-ia<>{>z`7qJAD7gKj4Qy{voUDtN6-KyA(O6fOydhBV8{eO3;_J{)?b2 zPUs444uwJ7l-w)Iart|M!Jp~3tKh2^l1-RlIoTn%`K+db!5v2*86Pbfh2&s@t zXMAppLwM!uCXRn5X514?o)qkr!Jzn1%SSV(MT{u-{?gTtY_ci}Q^Z9pvy{gw9(Gv| z-c(i*OOvZo+tSaQOAjUb9(S zX|b}>rq!xbuerF6gKb;kwbWj;Pbs9(c)^s@vt!(b%a4BgW8V7F4`{8n@q;N!2PK`d zY*>u>`O__2R|^n?VFA2I2O-a3<^MZ6Kg@lse0Wu#6Dkz+Yv%x)y#X9AZww=1)lk{=d^I*g|tyZeXq`Xg34>!`pdF%%Z2FK-C| zC}B7?d0~DzwJr;jktABte5ILbAEFI#_;h~dClVKr1*X8A=Oq{BODQFDpFciEWzt^D zTE~gPqpb&NTU7t1D=giX2ewsH?PZhb z=1^%`Xh?)~nRh*dO4iEwr zlA_8S^csyOeEaATPj>fM>27fQ&MmrY-H64K*p|RXV+lnt8Pi!=wH%+Ag}S2j0TU0qFLY|B!E5?N2=h%%l| zIX&%he0;`aGR3xPtaUf2HySvO6%J+@a}ipFzYlZ}Ni@Pg^E{vFG{CLfG<}yq=}bo} zUUz8{9#~d`TFs@|sMBiIXg1xDEzf{al@6drr-`-pd)Ho4Ct}`u zpZAVz^U=-nNTy~q9YzqOex%88OC=B}@KM<}m44*o1VER6S;{#l>`4v$XQKRjW3 zYaN+@Y)yHP!~6vuAExs%jvz@j?=DnD#ZeGG+4u_R8w3TaAC)c&436uflrO&`jxs<-p zVA#39ZFw^*8LSks)FM}$sUU2rNXx~N4Ngy{{O)%j^51{{4!{58F$a?xotsxPU6-W$ zl3-uKhGVw3uCUf!#jzwZ>P|^1sMTGrY+u1~ZH^8P+1oq7 z_ch&a7sqi*_Xtadrq|=im|nlf$>|xx;Rq>hwytc`>2$E|8kS{Y*&->>&Fd0de5WGteLZxR-#HK18&OqoW48!+5hQmHi&Ed5-Ugdk= z{~jydmGJ9P8e>`DMWHkm>6}64kzWWj=uGzoL!MQz=n`V)Yh<30QZQh25*HC}CbmyA zB4tV4W2#uox3mM*+~{GMkby!M zyXUhI#v<4EQXM#!U~CHjSLc98)r+dc?LUN(Qi_7ds!=8uAJj6NA7OxFMb0N%B>C$) z!A_}uN$OA*aC$c2;iDa%dFCdarbOiCb_G?yc@{e@Dl|V8Z4RxYD9!X|NrTlaTB=3) z=cblN8nKZ}<%7ozrznJNq>EJ-LKD(d5pv*FWLbHk6CI%0_DC4pQdYc51Cbp-6DuQyhEM0B+#L=gVG8Mn|ixLqq738%VZL8a5mv| zbinS}glpG)u3uTFU3WlC(fC+GuWUXF8#rf!Engb_gP)-(rUI6f8*HicsiYO za(YU?*T?q*9Jj&MtLroybzIlMvSjkCgdq~jIQ*2^?n;?ft*`{hh$@MGVo7lmcHInL zr|316;k~Ir1Yu!K=uV*!NLw-(jyO6xqPw=r4}S6^UVHr&R@PVW2{H~-5|J5diLC?8 zVoB@8*)=oaDeJJ3iHtJ}cC*W+iopjW-EOjb?+mYJQA`QVJRj#_%94}|b1%=l@IoN- zl1RDCnN?|%S=OB_Nq@_C!7givY92FusVGilyUXX50nB2sv-1nZu4z^0I@7IqTG!x` ze%X|Q!7OH1I<<@nCrw2HMDkk6s#b1#QB2ckk#>bjzu(Z1BvGkRlq(vEU_6=f;NfGQ z?C#ULdj(61gb~&{PUJ~Zvbaz+sxx+GX>(I&d{eV+Vq+L3v3D(LE1yG5US{TB0KPhZ zJ&hwr%${;K8B223XUjj}Iv2K}Gk$tPZ(h0Op#09qQop~we8 zgp!$179bc72h{5pwR(+})m0qVP1@!NorX{tx5N(uG|+6fsW+RU-aN8648fmBrsg%F z{Gh$EO1rzpR11clj(l!yremAI-k77|0oOO%Y_C|f9EpQMps^iEXSGeU-C#7FaMtT{ zczDQQFrZeeVOcgp2t3cD-|sUXPiQonY^<(QZ`5&Y3oD5XR=K8>&UC~QV=+^|N08a~ zD*IlVf~$fs3=YFp9kIAlhaT8MGM!F2JM42d=yUz%4gTUU|D2azd69a<1reZP@8gKd z7kZYVmo6Dp)ia;VjA1_6(3iqtud@^K)zkc?fx5=~(Q_JgI>)%B!&6Ja3=^~$2nu6} zcqSXY97B0g<~D=P$#!qdpIenQdKtj9%=YsluQgNeYx>n1pG}vIDPpYp?ev0#Y&qA#-M z<(2I$MmlD7b*b%@sCZBoZAj!=!5QUBu9qNmIpB`|ij{N)axMbV+KWAPg`r!GugOC9 z#K?-zPRdfqkq?b1(kNf8wBb-Nw|TJ8hFitjF5X(r51Nsh*6S>25woIG7cfe?+-caX zgeu1=M9v2y`fnQ*I1GAIKKbY?e)0G3@w>Ob;^a)wY;IF)tP&t0&=qM zwrMq+3{Qvj`$Mj+wOL(R#c^Cz;Ae`Fe4i-r!>`v|7t69jU3&SG7IC8jr`Dj;-N3H5 z2*w`TsbSUIw65R5ZFJZ@+Tr-&DZLGwo9j*1TMm{~ScC&umJqa8TGShL&Q1rMoSbmh zJB{|x@Oi7(>s-ISNu$w7)|!kHAgjyyl>3Y);Dw$sWLeQ=5?Ohcc@89uVXWVm4hrZE zhU_06ptR=YS6}6)fBt9OzHJC)^~c*=J^6PSDEPgnB~rg=p=kXbv*B~RBhr~enE??Dwl{ndn+zsfa+pJy3O3vQG8`(UE}ln{odXXKRgmy+Q1$n=Zj39Tx;)0#|~U zMV`0J9wAC=q>#AHHg0PbJ(%K48@skbZS^YcwJl_GmDBxi`EvgW$EQPXt+%+=t+Q6Q zuq;3aND*K=7TvWKnym(&H$`iO6aw28ICkVrpjA3RDr9Ache-cg%G-$L?~pgS0!juRJtGNOW6m>0SmDJIuqy+ zewPfOCHq)v^gcVC=^O|9%t9G6;6@kN+nEgV0_V=GElOlMM@329qCYd81x&?BQk3hS zmy`QlPAOisJy*RK^KA=bCL@(;=2Gp%qDxjRbRA|rBWb~R`ON*(C_eJ9XIEFF@qBQ| zgsC7P2ts3Q&-0j!CwShJ>12ZM`xza)*#eFS4#G-XlrVV;%a*iS4VujcuIu7hPB@5R zNi55zR&%i|+t{3gv>Mc*kK@7N2~VEvb8TxKTiR&thl2`AC5M-hGCNxU9))^k5;?@; zbbr|cdET3~jOXAy3zecCX~q+pOxace9i7#qnG8)OBasbyFhOe3TX6oh$PddU_9r4M zahY}f;v!B|@aSd9Mzc0$UE=s~(T8+CVATbdxM)j9l63Tcr(fp1Ocee-@%QiW_S>IwdJN6Rbvi58v7J?*hSJf%7z!OnxW-bF+%TXNAZ?pQqrqSx z3H$(+fI>*WsR#~38>|%MR;$ysu^S5NtyP+Mj?tvEDl;h-jJio~K;v#Hf=&^kK&RRYdq#$HO949Hdu^IfLTc`EBR z28Sa}G9vWi?e~YA4F^ca;`x_eM?u?CjoC2PrZo3)xO1G!~P!bQDllh+U;BcT%|L$3J}Jyt!G+@UnaiIkiQBf6taMh8lRjr>XY4%LVWr_xtJ!lmWu-!ZOD;&eIH#T3 zTDgrjwN@8lJqcwJ^$x;q5lEK+7twTRS`Bo)%k=0mkM?RJ7qkXu(^GOAN=?&UU}ms z);Cvi>o!Vw5ZSe5b*GwHB;ZAvI#J+m-thbfl zpJ#&F1^0cuAhAA&;Q~$e_6Pj> zH}COxfA?!X`uH1q{QymaR%eSwYZGa=(b`30rH__~Y^M_4ZZ@Vje`#uti_=}>WcMMT ze{qjS&F1c%TiBKr-cMoZ3XT0wMRr-KCvO?^l7d@}z;f!?ZUapi2W;0`NVkC!Em9+B^)_prHkM;2g`Ihz>1bX;#|{Ri8WmlLG+k)f zh|*Vy%Z2c45f%XgU%_}9&>xLBJvn92>$ASG#-IM#4|((ZZ*c3*RcbAZKu_`YBpP&5 zi>z9hr9aJ&4J_ywpbO>fjNLk6_;qP}deK(yq8{c&(n2iyxGs(E=0&K_0=C8ArrEDu z08JGING244koXYf^l(ojiOW1Mw4T|mnRl(S=b+A>d3ydm%U~2y{xkAvpO*k1n3MDK z)QORK&xoxxOeRx&&tp2BGMP-6PNs~1yuO@8dUT%Jl|(H8b?3x1pCQ8?RJaRl@;2pCaqS3dJPVb20VInz@1yS zub@cKHdEidu6PR;yu}XI_qk1GP0yRR3AS&u+yB(OMgRa;c z%{pBtBgC@@vUIX<=AywfU|E>!E+Tt$WlCiBvoFH1%}NS84~t&f zP0Z|d6{(OqayE(gF(ERM+WF(?yhKrz^iZGUzLtf9JS8}IAvUz^mo$o&vW~4N`C1{O zdP$j%ULttJJ~%vPJQ^_`k3%hOkZNvK1h!(2)>N-36W_wv;wz4B1R2>k3FgND=f18Z z@oVOG=#23+Iy6!rjZZl_8Q?lLjk-&#>EMqy_~?^wc;?yXdFJj_{OJG{j6es81x>0K zO@UFVM{nLwG|68VrPZdcVs*_3KEu8y53Exr*;oW3X2``1<~IL5W$hqc_<0%JTH%0E zwP*|P;lffqoy5ADdfW`ll>pOXrmV?O}kpGZt+35w6-(p#dFxZ)trNNxu70dT} z7i!^^*fwR}b0Owk7YE8J&55$Q`(?pxx-KXbl6ns9p8^$OBrVD0MhPSc8>MZgQ_bUt zJN)7ozvut@Z@=N*y*)f-VOwp4-NLq7)M{NEX9aW}rLDr?YYfv=?1OArcNOi|!pY%4 zTe!_tT7l;1V3*(h;e7_9A<-5{qnhY~FgAYd3B&8lIy49-YlDwYG~^6O{4*A0gD-HDtD`wbs#m zv6u-yL@rHp-mHYKlJ}JMCUwa=zc^bv4*;5LINryTCreZ~u*?C)m*Aan`KezbUyu|f zW9DbBI~bQuh!E&-3{2eV>H&h_%x+$wOJ!Alne^re70XYFb4?e63IK0)B8 z5tPwh6-orcO<0-(0$Sv%>iGNea)k3-CYifrI(l7=6e`0c`o6-Oju`X@oVgamL7yi( zhm5D1zy9k#UjX`Nw}zPn!rqo{NiCng0%WX>ki8Qg+SDL#nG zKv{{-xQx9uJ#8Vo-W(A>8`HQUg>h* zm%8iVx)#!sSi-_~Y@{XAR<99pod7)@4jacrh#v$fr3jS54+6YE;|BuY7btCkbg-N{ z_0?_G?{3gpU1z1+WwpBoLh{l3zhyMq!wWn-H3==;2ry%pmjZs}OSH(s>IHE^^dE|% zC#*0?j52TSMLXo@m7QgiF>_tV%(c)Zg))^c3Puh@#wKi$Vc_rXSBdu2j9$htt5AB$ zo?>~Gqo3kuEsJSi2;`ZaL@7$|vq?gjQo$;6WwDNIIh(soXHPG=)=ejp>X`b}E7+cl z{pbTrW5PAuNPRy@+m<3s#7P0HPE%eI(VSd>wVelW^Aqr?+d^my6oK!k1*}ClJfalz zdLG9o`<(pE&-nD-1Ag+Suk({1zrl^GT^eo;%LcR`diNS}r6F-4a*V1nn2llt<9X9e zvRYchI!g*{+lI&{&9bZv>!g$}XUB2@7E7CJ8*OxinBx$jOLvEbHKbw|IEz}v(Sfea z4JH1(k!4-fC#CQVnyj?RxRf|0%%1!ex#@Bivb3ob`s?#;h!@jZSEP=Wg4YWcG$Q4C zgkdolOCJj9Wg=ou&COh=*DoAEvXD58MvBkA_?n;n{P+CwSMTuX;T}^DgmgeS=%`y{ z2@BhDaqK!$)`%^{iY>FymsSdi6cz|8S6HXN6rsQ=cG3{i#cr*#A|=Pidwlf8H|*>j z@XYO7+`f60&9yEy$H7;MsqYbJ1yW`_V`gzEQc9Z5Ce3D(Nialdjff1^W7ZiRw)+FE z@r8ww7H-|;cyz#ny+`~|-Q@PO*SY=t4SqQI5xcu5>^$COZ)b-mPoA*5f5gG@kil@w z$z+Ne4I+me4cbCl4njyg6-h5534#c&NrX~jIX14_q}FKD>aMZU-C(u5 zNvqSP(ORL_Y$7Zh5k(dEdS{#thSY6It>J)FDCMEGAAa^Cug+3ioH4PHGnJS8SWgVEJZD`r`vt^V| zUiQI#WmNGd^HK05x=fheg#t;@6^kEe1qzS1CU4vq#K|L#LRzxOr2{oNn=vp;>4 zpZ>|4JbU*Bwyg;K38)|fxhi39Gm9>l&m8K`bR}SkS;Mdh$X54Mfa3f{5>{W*NDrAE zF<3URKd-XRYU+#+Gb=*X)ZbOIjC#&Y$|8dt+BigY=>w?HQOcGm%%KZ2+Bx_BOJg2O zSX?v3#k|OR?#iv8nsnZ}NEam&GeM@l(DO8#xX)yOUTh9Sm@H4~Y+>fv7g~(w(1}R* z7p*O{vN`Kd_~Uz@@L&Gszw_=N?{RuI3W2K(V|dYa(z=(@!nR$c<%Hjl$lQA!d1ng| zdU*@N&>A7kqFm&1*#rEf%OVrTLpE3FIxd6$DMyC~9KHJy_rJN%Gk0%sb$g4Wvon0H z(Nc!2pU8?!W}Wd;T3A+W^d5p+g$^YZ#D#%I>i`dhEhJh9Y}cXQY#<$*Y2bm@*iDyf zcdoO2^9I@v7>!2sh6Bz9eFnoZ!@-2%a7w>7;p}X}!TuQ!zkR~){xRdgN4hqy>tfex zVMK8>gj{oLxV0LN?cg{Lj_cq$Zusw7okp`wy}5#0YvZ^LEUN}lmnl#hMSxHW+Yw6w{Z{6v^Qh=UCi(m)HA(* zF}#{e?8UTTX)_ryD^Y27J2aC!Z)(((s*Dsq|6XSd=9Lt(sn>lZZxS{_Is{XA{AizF z{`wvM>wo)Kf>kLUEUShTPBa6M`^?%XMRdHcNuzK#^oz;b zkWtWqj#W%Z!T~L-?$B`?G#YIN#|P}49B}yV2Q->>yvcx0vySE1N!MbL*<~RFjuV2) zOtZjb9!cN3)*T4M=~=TA5~-lbNTy!g_ybXHmfdWz6~IOrB-z!le@VIx-sM04ar{99GV z+?^wAG6@8Z3%e?fYXWk0X&Xxze|Z^DAq?$<$_*fw5j8po4APj}Dl|VIl;vk7^nx~3 zOMSj7;HDt1!9KJ zO)<%<2x5!CMCTTIm=L!Jg^*dOmCVMRg|74Wt=bRRY`f(jkW7gc7x8*#Vns3_63Q&| z=IDl%Q%R7g9NJvnyhq7aqO zXiE|R1214__mD5|-RIGxeO$NA_U-3rch(SY6QrGCD8qe4CjE*~A{M@u7Y`&0fsoOC zB9wn<0hRzE6yTx#F~_F|9PT}0*gxdO=dbbVD|czsZG@PHv&Kd_s%NmNivSEW45n;M zEU%t9Z{If+>15gZ*vmPb?x$3%WezCMo#m(i#q+#%O=(=_oYDE=;`5vPUzUYsl`BKW zyWGGLvwU=y0a`OPspkOb=XsrZ;ThGP-C`oBE)IhjX>i4#v#dMEA_dC4PV~$*V6013 zaUJF`xK*haWLXU%jXyItAiePBO@>M@zTrihHPQfgDYKj(8j#VSTS+jc=lMK(e8l15 zZ+Y*%Px$^@ukkPb`p@|B4`0J^T(laaf{F1S^vnfTwh2k4P$IRWl2T?`o>I!pW*cuZ z*^Q?N?247M`Te@+n@6@qTxh}Pz)SjbW`msgwM`kuLW?$@^3UC6J;yez^bm+U3VN|7 zK)DT^&e(Wiw0cCOIW#v3iJSr4b8Q`A+9(xcPV)xXRguO5!)rGWb}I(yOy(++&}Pa~ zv?5FHlqH^>BiLjKiG$XHR9zXeeV#9QvU9+%e*H)O_HX~5d-t9&^#YW((b#Aex(R56 zAtTXIrzspRv+OzuyFfc9HBhF-7s?Yvh9xzhdzB!f5Uj~`HxxSYWKqIGxD70)#%gDk z*4i2eQejzkr1LEf-Bw*EDKza?lkM#-9_}479FJ(V0s%8ZAwJx{HV|^a*o&U8w zc_1&;Qm$fJFN49I1(ueP5#+yDe8&US^RCZ%ub0VaD+rxjW)NehQJbL^~zWVwRPj(LZH~;D{SzBGfQz3)|yHtZ)AFg-NvnAuKFuRXhdx;Uwl=x(%pGpsxx?m_Eo${f!j>vs7HeSc^VOR4vYaNF_`TkvAfB7z(YfT(E#TH)JQK)467dvGZ2U4?TUyA};vw&RO_GlKPOyz5( zUe#oDnTuVMvQQyKL2|eRc$w91U+!M$x!s=gvWfo~pmrYMtpeZqGZK@466LQGzlPEp znX_3f-hWj|)-6{kEe`0HL34|E2+vAK%?F7HN~3zs*t;~`K>$L^WSTYsxq7*VPU=E{ zAr{a5{7YYtg4C;5BBf?J)x7_~Hyj-Nuk_A({MBFnklQ!caV!_DJOlxzjh8HG4P|vq z#lxTqAeszo75lxo?bmF%ht3T-nSeX*C0GV_Oa?fes|ZS3Ba1+{Y|(U)2Vz#6zYN5Q z62tFoR(!PC$5twl&vWS9pt5OIy7)P&pVDGnZu}oAgVsgPn>c^i&1Z1uogw7~M%fw= zDWf@8Dlz;1n8P2T{hN%ARvU!NXcX|#$6xR_|NDRA?YBSX=y-zG4qDi##0f#9-J_iC zQRs-^B87{X-gE_;2(>zxC?UDp3^0nF0x7APEu#h#85TA~Pd1V~)79PiA&@KiJ?l`f%@!%m7<~ zb&;77as9fR9XsdS-~RUZ5jsb#2?mcL#rqUdo3#}+1G&j;#?iq6I+?H)III(_WVU9> zJSEPS5@wSl z?mf88-P<2>dVG(|djbFaAAOe3zxD!8Kee6S7gZp%NU!R8?qTnA1Hj#>KNqP2TwPvelqpWyidHT3slE0R z)q_~6gXT&LtlU6)P;>F;n_q7!4?_`)G1-HZ`k0$H_xa!cw?E{@`|tA`|N2+?#h?E) zJKG`Z=Qx{X%GV!|MGLEMV5{qQ`eg<^2K*vRfRgsQ%Jf-TH3{fqQ>*H5>#STk?s;_4jMDF1>m>S-_DdkT+iOl}J!A3!6MD(uLAhqQbZrps*mo zl)C0t8-+&~d*6M1Hcu8?i<@7nX_EDRR*eDB%ATOLR6ZncZF|9(0Aq$6oy2_iyRY*H zfB0p-``tGgPm^r$NiAM&o?zC+spqzax%SrD5S!aubrm{N@hL9ujS-VGxMw&_i$bVc zI9GQxDI6Lob+nuO$_C9W@ysKd;7IdGbHS^}iDK1rdV0+G_>eI5*rCHZgHKatvpJK~ z6Xx?NBA%`7EuMV(X+HI-Pw~PFFLLS9C5*KsB&4c%-;l&KKy7nPnc6IdRwP-1#gfiW zxO?XYAKrMK)8l(wy}Hdm`;|}gxzE1H^G{!5Gyu^V_&G*=KH%HGuA0yB#V~Ts4&{_IqX=Ak*O3UiGY_l*%+S=pd%9oA{U97#VZqAj%J1gRH z*8=o~O{6TX1a(P4)Rm83U%w3?qO`7E>QmArMT}r=Hu&XL5D7pcj*k=m=377H_kQoo zeE$b;lO&)L;??3Y_;Q%3NAs`bGJ^o?LX362Ly+~ApV`S-k=~>rMS6<_&2MxyZ7rW6 zT1Z`TJzTbi{Q4j|uj|7wU~4pF5}$%ku;PIfQSjmkM3FQmnVn)KB@BgB=ZvQ*Njzh6 zdW;dz)6YJ|GtWH5Q_nofl_##Uy}gUI0V9;eU+d8!mGUS+!G8V!IEJ79JG*MRG9AzI9$73KkEAO225D1LTn{I zwhF*D2=DaQ?gFZ7Ft)Adu^d*@-d3+vJB{o8w3YjFcd*X--o)pP?OnyLt_DH60R?b2 zVB5tWuL}5S5{jCWCF`66T|;TI1_Rm`k-G`&yy-pe1-EMyN1J#o7k|&y0goXFY#!=R zx16xnVy(qFn_0t%$>JW3$*p8e3jj3NRT3wRPbZ8|rf33I9EM!O<`*bE_A#kuZMh;h zo(f}DPQOc~Iw{YtIHU%{F?bp!*7hulD)iU30gUGdw4kKtKax8fBYw3=Z!bs zV>Zu16f#e1TahzMH_KfPSQ?CRSmO|}x!0;R1O-~b#o2RajlnDUB+Yee)qO*&PgN%{ zsd4Q^2t)pTM)H5x-19&xE^%ufRKwwr?d@$2PA1?}j89OpU^1PZ#goQk=96R8&xpNe zI+>BoV*+Qn_QYjA^XZp(=~FLo>GCc?7@#&Q`Z8d925Y)TQDY?wqlx2$hYufe zdjAFox9;FL=3o7*U*y04m%qTZYXPGnI6Fhr1k|G}yvJ)KMjvar?4WG?J?(IJZR9d6 zhP9-F1d(Mpw<8&G2~awp#a@-k?snGc^|)r?gisdDRmXu1-_&Z|<;8;ARRC!@p``uA zIL*8nsib?IpPB6HKr9>DS`82jS)F#?Nr=@ZXS(!-E!DaJ zi|$4%q;8GDyXG(FoI}-PjKKw&VRtl$2!m`uB1@bxncYknl;+;nT8z!oXv|V;qP%@2 zf~GK=&Nw}uFdNVDF&J+!SPTaB;MHgBk57r?dA8{rA@y0DaFQk@X-wkN%)1k6?P6+G zR1S_+G8kQ`EXs?Rv2rE|5UVH&?|*Q@fB2oRaWbCqfB3h*&TB6}OJK5rja)TZxk0+L z1+)NyZH-f{g(}iYqgk8s!PHpI>T6XCmjx5wwK$vf|3Y!5%e0J@Y0UZ|uC>=*vtfRw z7D{1V)IYS>ZpURy!Ze&Eq!nH0D=rD%OQu2h>l_Z10TwA(Ju=_ch9=rK;svQnA&O0o ziic*UN~^gZNVi3w^qsU_nWB9Xh4skj79vo)ll}Xg9Nr@xpP~cD z-rf#ZFF(gqPd>?uFFwyxPh2GmUA{Yd(qa$NV)EMOP7u<0-Zsgxhrc(~pf`u+THWQsiKyayb5G5ktU8=z zX5xZi)nc$XYe>?VIEgcW>l0?PDbx9s#K$CQg4dK(Jw9)XW&<4_pECtohrjh$&~kIl z-mLe64TPi9Isf5z|B|1+^&bDv|HuE0U;M(W3`2$7fV>V0wP#pME3I~Iw{}=Q8Qk`| zZL`MNYb+)w%j77Lm2rU0N|B1=rmA*699`9O%c4X29U|J!3A((E$2uZ+>0xjCiVdl; zKU8d|7Qb(7_`j=2Jo zq{6TlZV$R_vsjj5CktL|ovq9mg9$C(XD$QAIK&Kj|APno-tYefU;gvI zB=dxO_aE}^JMZ!KTkr7j{yx?^MuRQ3c18>(Vm`ain{VFXop)@D8r zxa|h`wBB2316hmlt;}`w?4RdhEk$H0u3pCp;%qGM`i%QozNb}OKH}%7>I!iYjt%b8 z<;$7(XAyWHS!>ZWSh2DVEm~nOwNevP0}BiPzoIQYy|Q^z=+lg4SL!BxTG zaOwzfNSZm>hSs4rI~vk(i#RO+Z;ICp%*H-t9?zL4GvZ{PF}*(f^7yhEs8*kg3b#l% zvK09_UK3vb=`H?W|L@=C-~HQP=hyz}m$^d!$w)PrE%9!LT z=*4GU4e#roxm}v&sy&Hx0pCKeUR18R)0L4115)v;T^hu_v{%yGv#kGT-nK+~%)u)R zau?WL{a!LK=_CXV`S7EM{Pu7E34ipbf5pRt8DhhQOM;j+HOE^00Dvu{cN<)HF%MgL z}_umg>K=Csnx?gU)!eY zE32)MvTFOjP=saQYw)ROI-PU0f57cqw|MvZ``rHM4#`~E-r8d{7~zb?;SddRZkPT2 zd%X45hkX9?&oFq>VZ=6Ctrb@WX)>qU(O_uoYt{J&uf0XzTARp{R%wUHni2IUj=%W+kwf-&f}&o21}Yki)XXT9!j+Za;uI_%LbdP1=mHk zqpne5!@gHGTYb?Q5|V;ARqqwDA^} z#qai?zPZwlUj1NxvMYcUqAiCi%uZ8$?7=7Cl>iH59+jq=-jff8IAg&UEUlJ~eg)eb zCo!{RPVD0h@TT)j){tgw?;?1>peB3teHlBG54d>CWE%6mAH2_W{Kp*ZKjeS>*Z+bi zuI<(=#G0(_0{nMdXVoVH+Y_iwuu%n zM?~QOD>kzRQ;Vtv2BdMw2k+nG&aHi}U3nsNtT4VFMACn^Ru=yy$Zgoe6a$uz+WNG3 z|JC8+E*V-cSZg^W)aN12%P96U%L^%uuKbL$68P4>@;~>@zqbZ!*g0w6W8Podi}oc; zHbB3~s_q|4!R<0R!C65r9Uy&e7F9ZYzAO8@Ug$cPUTHyX=A@-(Zm9eV*+%s|)b^Rx z>Qwf;k5%1{;_P!-o3snK`sM^r$KPqtLM_186i20%c7Y()5N&1B1fRLaU}A&uU=>77 z4U*LCm(*a(0kr)61ra{*rBor&Os_jn=1k{PX7d@d`HUn<@}UsHdq_=|k>qQ%PiFO_ ze$G$dy2atamzhjv{7?VGf6FT`Jp&q(r1MVuuWB2vnH<)xikIiAOU)6Xs}0qhbl1ku z?U=Ofnf7GGH0(O9r|yTpISDMie{b2TP=_zw$wk${0qH#G)-XnI9SBnDs2AX`OClgG zAYE#CTO)YgM*0gJydqYvuN7Gglq{KWk$Ppa*f8<|x?&(xi($KRwyVlfFGQ0nOR&0JPJR8Kk5e5OzJo5~L!H`rv z!_kQCtsRELAyE|OtZs_=1`)3&=tZSA^9&kk1uD$4=xx`4Y1l$z%EwYRs4 zZZcn6U6KH4VFV~AK1%QLv)_oOUuu`Obko78zVl`sc5ofgzs~oq-7L+6M?2U&?O+SF_Mk1=UW?;V zE3AmIN;tG=;P5kGCisabNfMme1!ZX#wq&*1V38P+<-Q{rafq>a0=xBYUSZH($W5H z0MrU|*saq&n?9#GODEC+xI2Rs`WX4eqk7oqH41MhF4mDlD&_1LVpg za+kuYP+I*4Y22@3%Wx`$7$&nB$M+wSim-F}GA;-*f7o27s!}+xEQXa9?g)O-y%GgY zF;W0r(~=pj^UD~+rM*jB+S|*sqfM=w;(b!tTPt9@anG%@3n9{h%C&3P zu+~<-XQ8Vzk^$$F<0Ed}yu+JszQu<(K4d;k8AjWT23rIs$kWs;28R`kXmRa}&+D)< z>$GOK=D6is zmQ<6;gc|#}kOo#+$tFmswC7t3pVFSE^Y|)W(+buZoVDN;@ro&Z(<|Sr4XtD`%!T9! ziYZg$vtutyUvnlPvJst}Xpv#5RE!j+>3xJqWg-v%Y^&);UASA6!$+Le4wEglqEdVrMopmJY<+C8YU>qhDm z%&K(_XY2Y`2KYN_#^s8kB`wg}HPQ~2sN(R@T6^W^Fr_|OD}H=h0zSX!$cRNG1cqF{ zeuw}4Kl}+_`HSzde=tL=Lrvy$tEB{_cl%!Q+48~GoGFaLZK7}sX9t;8Smkx33p`YD zh!k=VAxUD=IL!vcq7bnr*BjRl`f`pywQRMiWbCKG zdw%lc*LnEhfWU-okM@Yd5upjO#^tUzF8?y+dXZeFP&m6J$(S^q@XRxNJpIfSoYSoE z@9gTB^6*_m(ykAHWbFsze7Xeb+$T*bm09*xyU7;-Zkx<)>w1XvFS7hA+mowbxfHM( zaD()QZAjxxYYrTr<@0p|=g#sLE`Z?aWJsmYnoU-=$!ovg^BQOM0~WfYdu#8l`XxPU zqf2t2-NmI+#CJF72&t!gR=fDcnX^pj+6R>V5=lpSE*a@OFPgFz``io9{?>vys9PmT zHNi!?JEJYjhfaV?ubyV{8=32Y5y?FkvjZl{hsi2UV5;E`RiII4L-S2X$t}VRR%{7) z1LufbNEAebE+n)8PE1zedh$rj{IxVoREkq&JWlxV!@C?jywCRbh^tqw5JgeGa7<~P zVvMO>PiX<8;uNc}no>X9YSZ`SeP}+6jqho=Iy4#aESM{&j${Cm1>sEyf!fJhW zlL4;TgK3++mFh;(7$}np0Iq%p)vEt+)sio>-VzCk=Z3f6xy^t2-7oWJU->o<_hY;S zh>7rGb0*&`MI5pO+%9$jgS8P+utgYd;cQg0xb-Id0?2EL=oVnZ7=yD8D}v5r;`s~# zf*^BoDX(+!>=d0R$%^O9r#lC|D4I;M$&BZ(UE%VjOPM|5g7{c!6Sm9%ef9Gzo!84* z%hvW5##(NC@Bw%4-eGrlm(gfcvP?-5bN}8w-hA^-KK$?lj*pK?Vow+h7>3(e2{SM& z4oi^70h_E-Rsp8ud*I?wPnge7*xhx!^r@#9ZCUa>yE-+9WVU^^FkD)|srPH+e)k4D zOeH3@-y%uMgtukjb~Pz*F#vZpV5|@*s{lD&c%U0}wTlwnn60h;-33v!w1-oXc*vOm zWN+(!*=MESQ9xSfb{A=Mc7WU8wm0;7>32OVeE@f(;-lkU=$d-qzGqigU3+6H+VbUZ z+CKl{v%i&h!7|pKrR8GF2F(;13^3MrnhZXDNw2)8L31% z)WG3FR#PVxrN=bB>+|;v-*m<4YDb|{WzSkgr&MsZR`l-L_TntTeg;@o17*9zN}?7*0oH_XD0`^Mnb}HL=Qg3Kp8_rw*hT-qxEZq?&> zlg^!1*3;6>ym7G#0g2BYSGKpeaY4Yl*WYC_8FTgO6^t<)92|1v#tm-Xyh#*AeC9Ks z;mIeS;^^?0**GS&Lo5M?OjBGC1k$=IT_`eTK0gMT@Z1YmdE(kO*510aJxWA*K9%y5OodjR0|gAj%%*| zy(YM=x#U!UR3FRD(qdqpLQWc?0q13m7sbC+9B^bAP&2ZU)jf+mV;z9o=K!&)h*|}3 z*RnRN?NRmDSmguU)Bw|?r8ZsHwEDh%|A~?V+-l2wNu}0&m^xV9PJr7);Z5*a>MDxG zZV@MVt0X>V9?wXU%u3AUwm@QN#T|-twK=7Og|2@}5qVvvK~&;>ZLm`WfL znlZXb3itOophyJmsxK1E)8I^{z2M5 zEFjGTpj6suD+0MW(7Ce07FzO-7C5FFJW&VbUFIlCcdKc!UK}DJ^ThD_>+kd1zx^kC z;~U@S=)_}PgqSF6-b+70&q=~0o-UCYeOjt@PI>X^Yh1Z}xfKVzGKj7p*>4Q! zq;mKhYl-8GskPR!wYA03(II#4-a%D)?zv}q{<-J5a`_70D|c?*;pAwHvjePzwbV)J zd2>=L$THvXB$+UqA93x8Enaxx3SlUCO)95=mXei>OEsy|$J}=Krq&9AE|A+ODk`1CwH~0RgUT|prH4sfht2Lh zPmI(GpLNd1i<2m90O)Irxohrb^Rsd|?L!m? z5=5UUau~TtD0>{7j~%`d~4g^ z^bBJ51{vD=S#76>icF!e8tMVj%}sPM5F|C@`5Fl99Qf+Ko|}HyBG$OcNK1nTU$*M& zKAOunxAp|EmT61N*631cLUp4pbg{Y4aYcqkFB4yVglg-l5!;-_<2t4@c=Mf)_`^T` zDu4aW*Et<4&J9StB^$rY7&{d~E`XO?>_{Hf6xD=GS5(R7stm?RVLsdnmnu9mv+uFM z&^T-~;542yeeeLhu>17WgrgzeXg-2!NPx5$@{$UO&NZ^u*vcWG7v$ZunS7_pxF>PU z!NCElN)QC>@9z@?0Z%;fB$qE=W@|XiW(bTW3`2r2$Xps!vH%`!R0+8xtX449uC50$ z7(3+TbfkG_xAYS_{ufGv$DGRzxYOwsi_ulUg&)z-|w#sw1$sTLfzgpX2 zJ6)EM7nS6;`dXhc{#fX=^;!m2SGhbq%7Fx4wg3Qt07*naRD!N~?X`Iy`T%Z|-Rxdj z%dI{(F>hYkeiFr#mhUMXhD5;t>&Hy@r^G(S*#L`Mj$??%K|I5Go*L?cZ&!L(k;@bxL7jV4k zGWM?K)_zfErqaL^EeSx|t`E@A z^>*JA)oxptOmn-uFj-90Hm^_NsvxKutcyT~+`4&(uYK*?{N-Q%nEk^U#sz@Q3 zmN&o1nKfBLn$Ai66t5vhJcU(N79dev3sZRy8E8|f6mEs390p?*=OUclLS|FO`$r_H zvh&1MhI`xKEQ$B{LW7%G0%Si?Q%GV&eN9JyF^lXh5AbC3@SbdTuf1n_B}=_Db`gbMor)BLbpz(}kPmJ=;O5N( zo`2yg#^#`~W;myn&O(3j+AREI1hCo`;f42)?Fm7MjU(AscA#tfU139}e$af5(iFkli* z8O>*$Oeai}8FO`{UbuDZkpJ|1-{kc4fdBRX`fvHnXP(FV%oEcX)5AJ;$JK5Eh&w^v zvLTkf1hkbc23_mnTEAr>OD4gWhdA`NeHP48-&(Hcx1VL|q~jp$knV`qa<$6zuzs-9 z$3koOjcs1b>YsNB@QV$gdQi${mRuQV&eOicA!fkC{TYA#&F}LUU;PfZ?;ay21OifB zSkRpDR9o@RlURCAb@Q~ST#`7;c z&kHZUn8gS~L%T@c)v$zNgoweXDL4;WnSIE?P?ors57~)X_!`S%Uo|$wxosZYzt1~w z-{OnE_!8SY7EO~}LQ;6A<|DdmSPs^Grt@HubAViJfQr>Jr*41kmHQvGwaXQ7TkYo1 zU=W+1O&ToyGN9XKKUo6~s&ZzLT#G7K%Ym$`ib1kz9t?sQkk6=vQpLLD(q}pRE2enxF<(tbU-Q4!P)jHq1v2X4f z8SM4k{<F4^pBNgfquMM;U%?0j+~$6zla@d=aJ7*ZuLAx>P@ zKHKQ>NC(GjN{>AXqp`fTl<7hZ);Iz?U=St@!zripDdYJmlf)6HhVjV>fBL6C;Qsyl z{9pdh|B_$*)n8^b9JJoUdHI}jkg00{Z46v!fxYr@&_!ELb$#ox*2d_w4YVo;Xkxu; z9Hx;vyX%|mf>ivJ8&+2}Fou?%!!@8Q-Qc$maB6e?pAoePWYe7O9^iVfSshr*2O!VH zey(oHG_FB51e6Kivw=&IkXyHo`NKc{3V-lNU*p4DCm1`(*iuYBICPP~whK@s#L0x| zOi0oxss>HTeOa^jkm(Ea_iQZIxO^DY<^zve0c%Z^01rX%z70~5v6)64ff2UCjEy~= zOxge7L&gUW*|~OwXzvnsFu+!e)Fgp#bWU0=n`G>TW)|ypzdY6IJYV6%YG=5eG-$uHVNH)CH$){GTT2fL4v5MO<42XzN64H5$ z_-{Fk&2UF^NY^rjFCo1HS#Y zA9DBB@9=}~UFSD{^S|TOPrpDASPFagd*>_43Hhkx{S{{3%%ncH_y!Gwsh zSv)Ouh5I8TEHx$db0$*{a#~5%HH)H}s;<2f3?YSotHam;XNClJizpZ|2)77afI$ew zU?W51EGN?wP7jZ`H#s3XIwab=%+~fc;ULTkG4C;Hig?W}b{Egu$D^x_Q9c z@7&>2FI^%G14NVZeHaxuw?46_mAye=L*Mt*C)o47%xeX#Y_it%+#oa+IY0JCCfdtI5tI#LI>+2&Cd%%A0{tozrhG^ltjElyOi*`jG|F;agtY!f!3b2@VabuNU4?)HVqhKf z_=NYaPkH#@?>Rjc{@uU(?|JRD=NSw_j98L51(JLyCPhdKdaq=_mL-~18Qk@BK7}iR z<}6&@+q9)0sxkzXO1eI8q@B7gRxu;_j*_mm`AN;+7p+vbvcCO}NIi*9yNZQ{gII0N zRKps|_rHn)ZA9(1ohi(cfcCEISpSTsniyod>bH7yZhMe)g$}pzsAySs8t}r=@hN}$ zU;dJR{~!L8+xJefL5N6*SJTR+c%&VA$uyvuX1`g~O1-!(92Iiln3AngBQ2CQ2R0@tE<$2b>%pGv3)|_tG9)qb&>`6MIBcNK>kLu_~Y! z(Y{%eLy`&zNa7f;zLX`D?b*uVX+*FllO!DMKV*OZKJ)nmaRDBW$=Oy@L^J!8RAW>j zRkKJl>zHg*EH>ET`1pu7-uQ@L{*{+_@`)jsg=+%-yq88wse)Xzww}5^z9wlXndD`l zb@jtuYKf~}A3YL<<=0>}AlO7_sXei{(mE5g#=HufP3159v&GM=Xngba*pw60LE6H~ zP*=>-7oV%8qit$ho9~Od+fS_IW(>QZvA`FEru4ZN^nxQ?Mi z>2&MqmJ>FU_%{9J&a#noCFxv5m0fMyR2NQmCi(17oZv$YUt!3Z>MnS}OG~)31A;*&gjvgNK=YRTLjt{5&&;QH6 z;Y(loIR>H4TgwIDOp6+_^&V@k3O&=et60RkNw=vT2ELhDE_C?pHIlljY;2Y7*kJMX zRm<5z*3wEWJ2Zsmu#+~N4!Vg*X$2-!o}@~F)sD8UJz&twMt7!?t$NmFLtB?+zuk&~ zE)LzsXV+$1PF8?)t^48TuW!U~ay;R${`znEy+8OfZr?jbY=BCb$pe~bEg z;n&<~q?d0+7hMvqu7`}RG{)krWjGu$8f_DX!^|Z`O?j=12!U8|5yn}fBw-RKOdlR{ z_u!D>V90O~GM|hIN13;7Q}*-7CArcrveZM8ro{7@G))(gzDbA06<-wH>TU5qzz{Jj?!3o1Cvc z`#sFCkgdTEM<@Fn9Y5fk-*}TG9xy&N{NgXX%C)N_N}*|aL(_J= z>UkDn3*@yuSd1(zy1E}gS|E2l#&%r>MH>SNg*}V!Pde+#J}G36i_KnZgB0aZOu@!h z{VS_$O=S54+v!fAEwI@fGAq+|8bwL9Rb0p?`ut*>wq)9Bm*osvgT-hKOc$~ciU5>) zXQd1l$icrD16ao68L$8JO}_l)zv7*D?qCChm;kQ^Uvn{St~g!sY@N>+w->fZvq;rO z(VGpIITtY+?y$ABM-+?@aj4ox(Q6S^Ty9ZlZ9rs{*d!*PL7XBk_p>`J*>-O zPxZW^?B}>7f@JbzRc7-!^ZC4XC8S!|8NAnKQUE&skg0`KfVw>2DGEn{RgGhVemD{S2ShGa|&#P_hg z(!eZ>Kkpv&Tc==H{*W)fC*3nT&2Wb`BF9#|#(K-LAB&Wqqycg}3yBSw{~X}1)~I&A zYpo~_c(nd!g}qAouw+s|%vOfaXX%{jWQ_M7=iG*y!a1W7OZ9H1RW-&EL|Y8Q0i(ed z+v8o1P7e6qx8C9YokKqQSO18A^KbqsPd~Fu5IW-6llTNKS8bS+E14fh( z@Ik=HMkHa(bau+&{4}%H%CE0i#cNk*=n-)OJ;OKi`J6b8v-d;hK~el&YYc~nhy36N zKj7A_+r0Ma&oFcmcW*u*ouw_0Y|(7^OjXO+-ew1^y-PX*x5aE`dH4Dq9y~Z^duum; z&$@Job(L@FVuHQR)=3Xx(mG#Obi(RjpsCNL9f8`xx-R=%o9^u;pw_%pmvzBwH(6DB z_*RPXJ{+?WgvsXMw(s-T3z)UJ_KpGOKG3{=F|kyqTS{0OXGzY8EoORX=(d-=cE3(~ z6%((jJ$9A4l(=sVF)Zr%hOW(z)A1P1YTxdE~!x zOBs_7f*B>i;=N;%PMJ{>Oj8&wue%tP3+iVD6iX_!4j^4GF;~`m4%*QnI0aRkyBa{j}Fu-Kk;K zp;jI=trl4a(A0WWTdP`4JzeKxBiOoz{Z`fli?9{d^=ERbvJ;bEFQ3~x6`r?Rb;-+< zrNAN*FqsNJ`q6cM=XbxtU;p)+j3+7B2(LlL-0E7N_~W51S=a5uU`@mz+F@(!5`$

m>kX0Zx{I>E_Ciu0D&bHGtY>aajLM-K4@Y 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

_}rKaK|L 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�GNDnFDwkz})QY~Y&|1)zigH@emWJiDpsWiO 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 literal 0 HcmV?d00001 diff --git a/res/hirsch.png b/res/hirsch.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b8dbdf2675ad367bd0a2f33a33023ec3e0eacd GIT binary patch literal 142903 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�?tT=;td>Wl@urAqE}}*)>EvTJ)Mc8`Iu>3rMGNWNb7h z=~?-Qd4(WwaCkb$cur2bul~9oJeh|WtSza&N&T^C-s-b=X(4N&>^JQtcXTiATBIBP z=T?}35}|EFV}|%a&CQ-~E7E+zaCE+ITL3a9^7V@E7M!`%k=lTw84S|4`cy*_ot?c} z&)k^NfvUu0yq3~Z`{OwNe$6wy3&7spvz=d^+Vo_gcjia}Mh{L_ z9B04%ZtBw#G8sp3vLs0S&L<5mXFmSOF~&wGp_iB|wF1jLxj%s;p%bYR-WTXT14=+v zyFRou5{cU2f^hmKSOz~be}j1D(H4f%rn)9^-npA%hn6M#XB?ku)`;~DAOXbrNAtfP zqwBhE?t_4v0F4O!D<#`M1R(ERQV<4$DCk9W8Bdh62Y2$ZJ={9oFyeIrvu4V}eja|rIO zENAxUTzJ1#;QWrG!y{}eLc@FN4%waN7uk#40BaK^!ti7t&^CsT@(a$B$W*AE$B3v* z%uj|%2vj3cC$=?^LiZ)$?adML9hzF{-~jJK8}{p%mtD{IF%{!HNA;m;35)0@GD%vr z*xn!jeaQcy0SZCQIF7F}u_Lia9|Ev<_BaT`Fc|F&2cW0O)RX5*ISA-QJoL#b46tM% z3!;ctN&WB7_Hv34B{;^Iy+n2M&F|O*yN*Z7kx8{^m6vF;U0_U3uNGF#e^ffzkU9Hz zvP7*y2;N7+&b*$XkSy*OoKwLfnPbdcql~TsH8kN~vwkWSWL2&!dU|I7inAq1h_l6# zhtb&+`8b9!TR87N3E^0~r6V6-RvW39yOZFtR|XLQ_tS7rmKn z5tS_(sZ}<-qwVYhB`ph_t0T~Uok^&7W`v5pct7*!$_1SWWokw|LxrMM)iQ_n)AgdVkG6_|GCkPfi-XXS=W48V%4+G^{2u9B_p#;p% zbBe|$<43jbvjkZd>vo9HoD)8Uo{ZVJm1vBMc5i{Dz?W>37gWdw<$T*su`1U)TmjTt z=3Eg+ekL3?rSh(_1!35*@rGgEDT1|n84YKP_R51|)e4gdMOF^0{n6FKcT!|L^!xq( zQr*96XTYe4kx;g;Fipx2p40JX4DMWlZv$b1!x1LjN>FBNg7olWn9z1lq zE{vR^VV>w>i@wy7;I7Bx@nn&9-mh%`0&sUPxedcG6h*uL9eE30RdWX?cn}IBvli7P z24V@aNQ!^*&oRRLzQ3;Pde@Ka&{yk0n1By}v?k`1=0d=g_8}oAig7~5fKKw;qoEyd$*Bz*@;%OF(-9EYN{KY>4fj9i zEMp>IY)hjv{bU)*nt6W8t$WhMHkhcPOxs)^A16{td6cTQc75om%{W>MxM zIL4%QGQLlJGT}n|~tp;ZedwZ@Vnwqmr zZC&pC#=&0HaI_nP?f)+Dp4Uo}kRoL!8ZFs72Fa}5Itf{=)B0W9jo$4Ue)FASTu*|8 z_HKgjdRO<9zGa1OwDZ)2n6S2O;@okx)GftGaoDnH)+Z#KMKs`bqdi79XT>RW$$y9u z%L(nB&b0ZRJ6y>Xk&@Fn2j>@za)q_eU-j913&7pIr8E!(Q5arUR-NtXqxuIwJv4)e zFN%R-CZtI^-F2^1)qhG6zAenl{eFMM>ov7i7bM1?P@@oR=n6|j1vQC4ShHKZr?_={ ze6}g9YUh-#2f#~g6DbkO*F^wh7Rqde$L0c85uSpW2MIF1&AGQp?%62ZZ+K<_o<~4o zKy%;EG24}gpk3QC(uw@L0^po=PTxVsIYpcWPRJ$1y1z5hhsVeJ7V-g_iD9EBK&a=Z z&ziBH=DKzt<&XdKYmHIwox*@WboWKBF-E?%VD5_z&eHQ_#tl=3gW5=HK|{!c%m_Te2yd%J2cw`6~Tz z@`;+})+r1`blI9j*D0MvmS2Tg*MQ~>oaq&OQ_hoO0@_(%*mjxOT;irx_HY9^Tr#I| z3>?upt=UB1$X&{@t}_8=x*+*sLw<{{Uj<<9j#3Z?VjzHe2EBqFyr<~B>c7e$uMEoy zB8YyqwAPm0Ws^)MlfN*8$qmFKSl9KiEX&@rs|()M1GP9d8vVGL&g$i6@B__G@XaW2 z-J5&U;M@41+xG%Qmj=POkEqi+qhnoQOR-r%EmX}L73F#!0}^y;^P$||r4=@QP>Y<3 zC>d*Q2F3NaWb8G~m0bTM7dfNvw*hw)_2xV2kZOF4_2=C9WgYQSyYwYqhLJX7!xq-(n=gU54N*wOD zr}2v+0UX(|& zP9*$nks^g8kOS=dY=5@zUjShs*z!vIzMnS@sV#<`aIliBM8G@ZF|KtpT>mC%7>`ZFu*c4nM3hQxNp3@M(GfWS0oot1>ff_(;%W{_t zW8#<{JMuQ-0V!?gY2woSxG`EA&SI+~0H3_n8R})h&u&Fc1~cpN3iKH)S8e7#dDH7Q zjV0mtIWgX4AKr0}b7GvjG0&;-IB&;FAZ@4yda5WrFpSH6d_T_51D{t7-`Df!d4i;j z##soi%Sq2oxrB~Ux&}4IisX|E%bMY?+7F<~e(wXrzDw?p<2ZGW4#XiAe$BHA%=NA9 zd|l(K9N_J}>o}(Yj!+&5=JFY zjE;5rxz5vkjB@I@s0(En@(J*`$wJ3Oe`Snp+jia~$x?q6BK;MBxjR}x7>I!=`u~3| z_u;^>tPi51f*{z^Y?~&T>?HXMM;I)QAfsp++v!YkF{a2ZN*HcKcQ;My;h9yo={=k5 zD8LN(mOyNZ@!SKGXWw+~B2t^hu0zSUqXWg_qy&`!sLO^uWz-Kl=@KoB44N6DI(z}L0 z((#&fkXxXBb6g$co%GJy$L@=5nZ096J~45E96N9t5lIFJSXj=$232&l<9mL3jv@m} zUz6ErD?o!CYuy4BcDJ=RuB>3FV59YOn7{Zu1Yqu7QxFDXAON3e?|&_O1D)b0L)agM z3Mz;wRnu;o$7DA73rCo-H5tY!8bOuLqS>dSZa3R6MOhhISx|3IZ-)j7=&Xv9RRicf zFe2d2V5YHYN8K<&k1^`k9rjOQ(3{EIjkkNk1ZV=erR5^CCe*G+vtBtC84}o8lx*Op zbLecYppBD{_Jy1!HJj zQ4g3_<2~2v-C``q<$lg}?3%tnP(y`wf;)Xkz_Zr+AU*C+H94gN=Yv2KxIJ?8cqspu z_xZk>w9GT#xpEEL_B3$?Qh|x8bJCsdPT1L4s~DtNCjp8Xo}kkv!OWJAg5}7m6qVnC zXmpn$h=8?bgEgXW)^XZrhB%Xeh~B*H(NEg1Jp~}{ZciHqf*=f&5}ab(w@Y#r$-jix zSI92rgC5v+Z%9`SZP+v6nskx!jTbfIk#hw4Bx5oZ?|j;g>dOL zlhLqk0)mAZ$zt_ht!IGX7A6Mru-;Hqk91X(rbG6>HT!~ zk+zmL=%zD3Z1Z)E(G)JP?A2cmjJ)~j{{s40gg~q#I4R>5V@U~V?Eg8oDf5>2de(7d zCxqtK*tORvA|fG|X>ezxaI~*`E@nnZtK5vdt`gF}+h4%edKQV>|1foKhaaH2GP?VK@O(bsS^BH;oxcSj z?%r+_2x2G<*Fb~RM<$Y+k&F@p1|Bepw4yADPg9NAzrDqB8B9655;)99icBpHGsSmK<%OC{KoER z*KuA~;MvP(yq*M1`>KfIJfiCyN^Sl7{eG<1RF(Gaj{YkI@#97jH&0icL zKs2dwSfc9hnH&wLBDhHwFcFM=*SbwiJEuumrhv|Yh|)R5c2Z}CU^XfDUWM%_lm_8s zFv6*b)0yWaq;RerckdwYUNFp3_LCtJ2hN~ouh&qP=bmN8@IH&yhf$IV%!X=<#&s<8 zW~Fv^soB>vd0x&?1pwX@!;p7i8p$;`q`-w{6>@dUQpp^vW#aU3S^bZ12*$CWoh7mVgVHB!(aU7Ey!D zQHUynIv8IQK0d){Ig(sEcvCWrWm#@d!+RI>2vQn000Sh0&pqaM{vQG>xEFj;29*qO z3aY;wISzJ>4X$UmNov;0w=iA-R>K&5j6fW`Ay|cXcL3kE6?>O`u)P&k8f?<6wX^5T zdHcS<1TxljJ+fz_3cnf;0hqgk+=QVR2%xYm2gxo+$Q5$0Tq&nRgZj|O0_j&=$zJ4IkNh|I=nM5xZ6deqMZUdX-n;8v& zz2M{)SYMwply&NAI1FbO2=B@@Hev(=8<4g^qAT~+*Cpx&W9Z??!H}~7719?qq}(!z zW{Szf+6Yzj@j9NL7FkoTq`OBi%GQHgP)!;D`O3R-I4s6&a=h3Wvl!dk*X`+XGeops zF?5N}b9`Brr+_fFAXKe`LVJ5FVdx~^BmF+{i=%UGEs z#&I7ZTxDJa`UBC@A(I1iR~OMGQrWwzG8|?EE@>S`zN-)Y^rIbeHg&cXYddE%%oCZ( zF?QE~*c&M%fCEhmpPEy6y}^RjK*Ba+W~Qeo^nulXyH;avdc?l!eyAO^zl z{SS~^nVcwv@`gTPYTBkhO51=jHY8bpth6&4NqEM8>w=?yV{*@)!~5h$Cp< zIdXErcdAcnFuwr-it#~{R(lX;lX~eGj>eccdDUaKD7o>GwM+L{m8u}Tv<)beBV1>= zDHhbP8-w&7a588t*A>EO47ZotU4pN~R4dM&O)NxJLi+EVP>#DXg{Y(IO7bl&qX~J= zx%@=&{H_lsgZ!0&)6u-^Oek<1$G>ra&(NS}$GMquRhGesp!l&9 zi_nNze)?l!a&9NLc4Jkdt7+)|XesvQoE`#3HbPnqdcSQMBS;zr&iQS-s*bPM>zy5G zuA<6+vli*A0L0x(Zi7G&1W+G{4QnpIC0KGGuEfQX)JV@NA#5dCBn!(jj0Z8luI}p3 zznMnAkoQL)k`ilo`ZVtN2CvhBUES(wLfZO3LI`!v^{T=Sd>1dZT+w0Me-*IjkKiq8t z$IR!pZ9|{|+W|#_yz!BoRwC@e3FdH*c9_1R8K$2ABr&FWkMu);D#e7;0~B9rh5Q8o zTLPl9yfoL_sUv@@33d#$eFvPj^UN!rkqJ2CEX7*ZWyWQI%nDaiq#T6_^DYExcP@2P{c1rj*zwsRVLr$nxv}T_Jsi8ods&c8atSB^v?$x{PYx1yM zsHp?&sU*O)`Ek|?D?jFzSjFJ+3ZHY0+-}CKNwI?`Auh?D^%pJzh^S49-|}A}$_}wI;%;HDSoi1CxrNu3W%-dnV({eo@g$>2BV;Q| zS)*9tr(D19dlS$ZgT43LTu=`nc_i$11l`Y?QR#@d4@I|$Fa@JG)+wz#z;ws z61q0PCe&xRf4_^!RJq{%C-)a+I}Ag+I8=>!uXLJ+8qMB{5)%zdI6R6FALhEQZ7=0n z86#scVbbcYA#W##j=(I8MxYhmXeBRyyzCfdC8u~Ba5Zy9%W+&}1#r&HgWdGamx*cCRN013?%? z3r&0JMoZBe)Ehi71f%E=1wn9)*~!l1o9EvZVM7_$b=`l2`~Sjk4z??@xkIFqs7=CLn&Gt}A+&r^1#eET`33ZAHjT~?SLflWH%#6v3AH5m{V*seVVGQe`Ug!d% zoX?QrwO1LmYM#V%xPC)mp~947$gi~-LS3uRm+NIqVyRVHh^6n|J^KVIw^ssQ(pO5( zj6A4;5bk#|I(oR7WZ%a$qnba&pI)rVnnGx=a-dxAau0sLd2WuQKrFBs%Rn z9E70m%`-!mvTfYnCwE06tygD({U-VyB|FWl2<5u2x6bWKKE`{6L0AJ5tc(gll%2fSMhLV6_U(K)+_kggORx^BBIJ(KU& zqHIiaWe9)q_!oe;b4x)Oh@mJhs=r-VH`z6GDb-UratJE=W1%2E>U5?|lAD{Gzea?| zah%i)ipiVrYmP`GWxl9I&~3rg#Wc*IA9t+$E$ZW)ob(u z+s(d$-?Q#ZjC>}Dn@@0lOxo)mmu1>^Ogam092&58u4a7IUoF{Z!qBCQ%X~F=P$CoW zl?kgM)bO+RWw#pHD>=n~5KUR|tTt#_wOtd-AvBgoaMJJ`O2bl>-<(PmQ< zh9$~_cwt{UHq+S<+C#%m&Wqo3e?YHQ!eQ=QSMJ@KL&ipgR7Y#paef=2>6FY?Uhlex zRHUJY5nZYBpIC{Gul+tbnG>Qx=2`fRwO-ftf+KNEgr!+4=EBIV*R4^n*gj6pwr%DG zZx7>kwy&g`q8K_+3_D410%Kzkc`b|84iG#;ZrnPRj7@l*?v z+ui;8_3M8%gmfq-H#jnfW~C1Gcq{ZQ1$R`v7oMr-DC|-eX}#DQUOqDfum0XEq2o@R z!Z`{M3xiZ<%!NNP^E85uF3X(KU#Tb8w8Qj7BA^%9wtYLzxxC zkFB+SniG5nk$xviX>?J^GR7CfXJ0=^GDHwu6OBnx9E_rEm}aDp@m?`*+qOOSeZP%h zOA**K`41KBb^~Xu8FM1`>$>iFa5o12jAY8JG$JahVH!mitd8YZ<1UfMy`TtI=k+Yt z`xa4HnZK=qnTXsv6Xi}5%uWz06Bg_}6WpdP2$;reb+@UIu&B8g@j-+U^nEDx02i@B zo*6=t&oWA}D9A0uk}%1-&RND~|2*zPywB&%^{e1f;PO4^>2hOlXZyQAmIdkWy4Q}} zuUA2E&jMm>fL?3ut&Cv3@jq$1gAyW%hCRJUdEY1>wVrH(pkw46j^p^4rfCB~7@})2 z@8Jb_%c|TB$Q+yOav!Wtlp0yXydRZk2~&WE3RR|PrMD)#*L>>i;dMRN^-8-<6o^J< zCAIBFY6MNiwH{%bLGQ}Gv{Iy*!r%axXVTx)vp3y>(vzUK3qAv{6xd+_y8NUV!LqD) z_-a6f@|SzGjmRCr(jmbr3Wc{Q*wK)-Nxy?OZ35O~w5QFcW*eT3yt-zhOgn5-VgMr@ z1>Q)-C{%-62d48M-Cx&3q-p^qMvk-8pf73FxIgQh-V-QA1e&y%Xhl6)k+v8z6eQOY zc@QP8>v}tm<7IZhu~&SSFO%9%k{JGpH8x1y-}2S z@;Dn99a5n@r*cRH!FjNqg7sHnj=I1z;~4{Jvu)dR%u}5K4dTT}bjSHIwa$72koqx> zXX@Sk^4cP#RQ%f}JnWiz{*`tvsc;@uf5WXVm{}uFc$(3n--Yq$dvj=B&LS-5Q zDp|dI;6$K~tE-`9kL?3>1eRr*cb;RcHA8>5EXygUSJv&{5Tp+Qc)Q!x2%#7V!}NB& zGp};%TX@PKwvI8xJ*(?&|=di+~m^0_=;5y%WOb3I-JX=BePe zgDXDBk`#+It_~++Qf|75(T zR__0oX}PgfMFM=IXH+iQeR(H$EGdsnTITpFr}ib1*l%Nm))#2H=?ms~N z0!uQ4Yz{P%w*fyM8M1|3*+vOZ`}v;7-TMk#lvfy7RZ!%w7^Lq4Fn2~d2m&z>)#yDr z0QclBatY+EJ~C-GhzT+J4GZpuw$o0hKXHWA28sTTM45>$Jh-f#<=m_!&g69(Mxz^{ zyhbS5q!x~4c^--GQtLC@J1QefWKAHW=&X6w)V6B%_AT*YnOaT4j!4&c$GB8P@X7FJ;A2mrfq)LhGs3ZfP`I9Y zW!uZ;rG<#&c5iixAVogJVHn!`Gbu#@1`wkXQ#=y{!dattDZ0ZLVYm$}l3b-6TTAcW z?pwOdpuoDM-$Djc|MKH3)d)5N1LGF*5YA|R%$v{z`|bb39;o7?%8rNtW9P^$8`=p* z#&M+g^UC~E)}bEgxHj%5a9P(|WIMl!7ME$78oJGqsblH-opmpws&GZ?>nh|oPCc;H<`cBcQc+>-sOIcX(X^Hp5q+d;!PLsFyyo%M_t zf}OMXwDM3G0MpnKv@>=n0heXz_rpgj zcPaN`Y#9fsAyR?QX72tu&!L7wMB^N$ERV_;MjfdkSs7mb%?Z|00S<`%uW6dP)9Llz zc6*Zm;t+ySWuBQ==3S0b4=*}R=84)Nb=`TMafV&7=3$(#I6*Tpq|0!Qe2>EkzrD5X z(ze!Re&|c%8P={$+1tdQ{g;_4O*FWBN-8-~qoXxRIj5dMV^ ziiH>xA`wJU_u{E)7Bp0a{kwCc19}+pqF^w(Uvdp*0d0@3Te!tQhb;#_+qvW*5=0LtwpEn)|H8!0k4t0zYbu7eHf@q!#mTQ?CXNr>Z>IhC?k$brE z+=osAn#!7!ewXlNRkYz1lM3WwK?d%zNh=#xszmp0?ptG$jQihNMmF{UVCm%I-7Mvf z#Uzz;*?TVMWgY+ZducafKl2=tw={3c9tX8+T-JKf#7+b*IcslfEsXW?773ODU4-GmQaVdxs;<Z{r+pRfCaDl0q+*$LfvCBbB}|r%>Gu1%S%&ZhTQGN>%0Cttin$LXgi}E z1c4X|dSkA_890g_fFohXFlO9<;X_GGG-O%n!nUt{ZU3qW*LB?<_s83P*_huIE6UoM z%>nG@-qL2WC|SV9>ijMml~!+VoYytMygvFPMR?S+ugFMrQgVzaOc#aA31) zb)c4rYdo}sprUHsu65az5$jlfTVjq4n~xT-g$UTBm6z?B?5Rdt042lbdA=>n@`{r% zR%FO}gEpPU&CC~V* zjBIBOGm_;&graMdcsrBZs}LC=D`aWh$y5{Mg{-&+sCt^FS56rRN>EP%d1bIdRU9Zm zu4_&r#26^}c0S)-sUP(|WnD9;y%LcD295E3m0;U`S+t_9+|CeJ-J)06y}wd|x^1h3 ze7DAT>S(*_`Exe!F+d-@*2^2JGHWZQBWaKT(KJ z0cbn76og?Qit66F$SkOS1-m8Xh^JhKq^M}2;Hz4b%qw%}&R-2-@BOr1))#KRtPva? z*%wO%X+)*cOHyvUb{4w}S1(TTYmtUtpS=uo%MSq^m2(_5F3l(^(Uwe=_sXAcAGUR^D;kc1dz^$^l<)XBLu0U>==Ns6Uh+iu~tx) z6m+AcTWdQh0I&0y6SSMqZ|)J66>8=%4k~BHlIIrfYxJy7<=R?LR~47z=XhnFcLac$ zMS`Qx2`Ez*b9|E z-Uwa#N!G0W0Y5<@t5f(Mkk(w!_NelvEStVT=T)%KjJ*Bb1GymAyj`~kf|T_lCE_pZ z3hx5Yc5bH)13?sZsuE6Z>dme~pK%XK1IbZ1;jl<+0*Sz2fu6ggdEUMAZ-#K&w!JpU zhfu1VX9J=qQf7N=Jg#xGmL$4PmU)hsA!KZPi(m+I7og!}%590#sjwWSGmgM1oQo1v zY4SmH&7%LTH{q2QA=m5szFiJbV^#(kY3QtRy5LumYa=GTG=C$au<16PgVqLlUX8ZV zXUCz4QI(`l0EVs2J?)&~y;`p~IK zV+@&ms>l+ENY=_x!vc_j0%nPj%Gs1F_u#!bp9a7H0Bj`87?F0hn+A>@^~82?n5C6Q zMe6(>5xCc>Xa|&;p%uv0tVcV3uus}^S(ZJbA}!254vkAG950LrH9U+|IV^QXWSIeM zv#u*?=a*zge*R+w0n;#FkGIF={o|Yd?@Q&9ksJJG6JTXM4OwJt>>APjrL)qM&mwjJ&nKEvMY>x6AeQx*J2}OjPV&ZJz?rb}l&*!Y~w^6LEmvvP9g0dvdu^p{Y^H zYFaF2kdRnKA#vhoKY#v35#qzels(V$x3|@7()x*en8~GXY`HZRpGrm{uf-rbZdovs z!<&F@?xBbFQ~3B4pw<)BMdYF5KUSV|f&CO69|)CJ=_Mb>o@H;;<7X-9kKwmp*H0^r-))g61WH%|Hppmp|OL?doO$cL;h$Nuunmq{BE^M9Z>#t?PP4 zF(Mz9BV!Er4c-xO2O6GoH_y)G*BYSJOQ%Y(h`-?H4rnNAhOe7Trd;g%e({4SA>>OL z5kx5`r4P&(^?pD`S%c#^E*GmxkkVBjSTBouPkAZ7F=cQNL z7RWMwhUWuD+zWwPL1`(ByP_M@b^WdaO|8=>_u|t>P$+nH4tmy}T9u_nnu^qb$KKDg zsX^uLX&&L7VwZEq)%|+Ct~2*j<>$}x3cm%Q?aXoz1cE5&CE=!=Pc334l@7~?`ez7n zVCd=B>+8P&Ap*qo`B?>eRJ`H!Nr2scL#;OtpA!WXNGlOdhC2yb-oq+}Cg=T#oi^{N z5y9Kg2MR#e5bnkDttGAC2+D?gY}7AU2!ONMbmk@-0u`7Hao8km*s*Lg9c;_T*=7=-hjr$53wzE-YlRWuT*=?0am5VwJvY*O2J? zTK!iXo_%)Y$}pt{gkdHCkORqH8Ttb>`HewAVGOJ%cs?j+S}oXfrx|b`iWVMIJP)g> zl^MZa52UfW1&5@4W+tI-ZMR?8Y6;+o;`qsmkYS_e-7J4z5ywE_ar%R zD6Y!dC=cJ9%22$(bzOH5gdyfrD6vj*sRGD$(IhdbD}5v0me z&sb|1&cOcaz1^d2+aAlZ?1eMx=U;*0O90x=AO~R>27*1n+xo8lsh3{zCU^m8LPuJn zh^Q2DL24yvLK@ra_4+S{5YKGewm03%5na~}V*X58x-VzuDP)gwP0?4q)D{}Z+LnaL zGN-0C9~(w!R-%eIAC*p2NWp7Vp~XUQBTC`PG#F`|60*tGM?Iwpy*i^|;albnJfsAg zWSoSTeaVe1H4qw1*TK3W;ZKcFdYG=GFd2uP;sfnL)2f|hE>65??#S+bG!cSk!gNT9I(k2zx0h_F=NlLj?9U@Ld57n$M3J}S`907 zehzL0oXLTqWlBpjo0}%9RYBvn@oq07Oa!47-yU_aIKn10x=I~i4494~^P`56Q9FO! z?$hP^a$Hy+)+&24V#II?mSvgdd9JyvJy-lNN2()g6fP^A|D=>suPfBxb0%|mG*8bQ z8N;eVeaogDjh@V-#^P*GO26NCBT0BYRi@s^axNv+>=ME~P!G?qlveyid^`jBy8q2Z zlUBg_;;c}k_ZQI7ky^mq-~@jE+kFOwB!C)w85+!l28tbZ-zeA)YawGIIuPp@-OC&;5dBU!;jl z@2P`fAj&hxygxU4!k>D4S$2zd6wPK#F@%f{hRd~6%czaKn+GiWR8*oK;?W^~ReG)( z)~xkGNAE%henR1QerqDj?S)EY@)9)OQkqelS63#B7ETk65%Ny~!0r9VSPUT_}^!1d5~uY(bh?tK>8Q2jmVlJ`ebRx_Zl(aRz-XTtil5XDAkBu>A7V;|AjfC@A6mxM zX)JZ>SU(9po$W?K`jB%y9|Fe>Ali&p3rfJy|CLdx`rNYHb_L>eu&0l}T(`P0()W~s zKi)G5=0+P@oZJm%6$>rdT-VyLSwWI{hDjw~$z4jYkS2C6p~>i7$U67l*Lt{?(1BS$ z)Z*=0POY_7s!h6_-x1`D5nx5Ym_KKEHY{h(2gsZetTm-U1u@(0B$f56`R(p{yhtIz znls9l@5~zwjZpvvbOV7<7??-EhI>4KZz*BS4VIwo!KCCk7t9Ce1NcxPc(>_m7R|^i zPg2>t7*UI7CTjXFlQ1cu8fPsNzk+y(0jbzDs zkRpfTd>zN}uN}YN??)Zo=(Sfs|224FC(1*3DA&X$XheVdANQEd6zl3jrvjv3tVDiF z)*b>+3bu`mh*JdB<{{)_q)1vQ8!gC!U15FY>3X-AEw~orUb|TLCyaqoq}Y}9efnse zEwbfAb+t{Wwe%y21!E#wHR`H76 z(0X2IC>8dDUc@Al;OF>vLwD7!VjkEt9U>dJ1 zwf4TdkvtSxx3PHKZntwRsxKhL{KzmvX4JO=hJMqgotb^I%4_H_kQiQzC$uH=vRO8?r!?VWy@iWnn&>qf5ix`*A1N6q}#^%T`pQyx&x@J zJ><*AUO0>{th90h%=IY-x>tcH;r38#h}ZD>+wpAw`_pmz5rDOGNnsd1nG+cwN_v%$}Jzao1`R?lUH6?8uJkzDR_N^+z6d8_3Qk zyoJ#ez!Ms3QFr+sXP>`zRItTJndHlQQf3xCn^iXBghRg7a(R(T8RlVcwpK}nn<>b1 zad{<%Zjwut;T_DrhrbHNqH?`qg%uYMWnr5Z$$W)w9dDpkgEVQ7UPwZZ^9!J3G}8vSXu; zDi`qVZFh%BxC^xmAaRa#W=35$(@mm@230#Vxbv+v^JLuF$TDjWb&Qf^Oov)vnmhDS z{aYhZ6zuBRVdwb8}qJUc!K%jh*{>43;COc#V9B{Z(ER01jw98@$nw8@N=EfsQ5G2 z^F6pA_k_=oYqo7$j^pUP))<%CI~*ef1RSU-)b+D2=lAT zTx_?+9QhBjler&|T3Ty;zDQm%Up83CD3ZoCC2VRFh98d7=ZJ$#v3tf=rA2u;93Us3 zS@bBy;@PS^#Cwvg&f2$dlvTMSh$Oath1J#i%QxhY>PS=kd(@V0R;qLq`8^@eNE|d{ zkP>>SZe>J>ePa)a*UobCuG!R#f-mzsp8p&_0cbme9E4#Q2qHL^|9>QZD$f8WV$fnm zr7D3-Q7cNCxOVJa+tUo;b4Pe@t$pkwjxM6cA#;6Fx$6noS=?)SiRoD-9+r!*0#4kI z$+W*#vNe0Fo>vdG3_&Fgx)!OIHuS&P~dDvu#+2pzyisr+b%6=UQcjk{KlT>4xSnju~DkFvC z+_K(`gHW8iew4Vz0Rsg_27w0o0LQ{hBAkRGF!h4@;5_#voMVDB1R8J{(gncPs9}nc zM1I%X`hG4wAB-lITc~f!|8ZZAv&aHTuF5*Fe3uwROB}pYi9gCD`N9}<=BmH5=gVoi zF5Pp)5F%sXde&`~oyn2;AOwohXZ=vH%rP5HygqCskPm|q64Hz`)32(of2$Eb9*>WD zFA9n8ER)m{2Sr4<-uk5zJR6ty2zjbjDU!~}EnvX8Ey7w( zk!#8jKp?A$Qj^&1Lu1IJMGTKNpumqJXMzj%<2DC)L0PAZyWNWqgQx&RRr)T zb6nB^EF#SiXXs^lN^fSciUtEgeZS1O^Bd!bDkq*u@(b4k~P@t z56}rm^5=)J=U&j;;Eb^A9#Rmlk4kB(syTiT43U zDyDE`!vGw(CpK^C((C1VTF%SUd$L12fae-yV`pqNH}RaP!Q*;}Kl-fjq}s?AZBu|5 zIXA|hT}evuZ8g50EJlIaLjT4S%JP8uCYm0$kp5zdTL@2A~fWVL1wSHZBxiL_};(!Qm6Ww^*kp}?LPJoEHe zLpQ}3K7HKNZ820NDhNV<{pzd=1}X2vY#}eScAu zCpvqIOE2dmRt?BOS^6fIvC2SiC%+`63N<__0>Y&Vkv9f`hvX7YBb&BKb;Ew!xVn=y zmOF6wg17O6(v~*vr_m+r{ZJ03e9O6<1v%SJ@Q$SQS$tsHJH)GyM^OiFSvVR;<36MP zTqC#w^&O?vPD9wWp2a;+3^-3=D9D^~Lzqx#P(NcuB0Eu`b+rfO`Y8I0Rfdz&3x$_M z%OLiFl_X`1)g+A{9t?#kg|k_nVn71}!))xywTDtZ&vjj&ZE(%2{0kZPhXB0Y z+i3$a5QX9XE80$y7LqQK-|)dfIIy`8J=tcpk}PSiXJ-C{5tbce5nO8qx>J8}37zaB zF7_EaM$_RF+$7UI8=+Z{$VxP;5rOD0lwRwSFFY7yV+%JX?E+z06Cmknv%AO$!v}T} zs!g!H)g4YShxPRC%yB>{>mOAskd|%^e3B&ApZFwJ*kM*SA5x-=gm|v@{Vaoy{d$(I zU%#(nyJ!qsZQ(S@Z`jC6^ydX-?n&Fhm>M(Y5Tg^o%{&G~l_t^IOJh{+zP)aL>YD}> z6X?6zc=_2HD?ek5qTjpJnIf<2dLZNE8wEm&3B?SWOP?ihXnnNr^GvO83?lo?9f{a? zUh=(E2sf=xnWWazdL!)bZ=VeL_2of?6sB%&X>gTcs-+nlKgO2{Rei$doB#kE)EEUx z*Eg*>W>}wufj~y`oAxd~A^UwN#o5USw~+SUPoW`D)=Zbo{xMB{JwB;Z*j}`D|7-is zj0ij7ykjCgBedv0V)O1a7M!Iw=#ulY)}524pJ7Q%+P?+ODDcjYo6kJZOlM}@THkFS z0+4oZIT6G#5JeX{`(Foe5l1RTX~bi`&?qt8p4jF1`EMZn5a72uNw7F>@xdPjE58)e z`t*U%mLY79P@|95J$B0?)2LahHYToHHDOD@0=abyY_Cm+{+xoLEtem9JKb2*`jh|x zB7mo>miulyrRYuCb1OT*k2O5R6lE~>-I;Z{?$;X#o`QHALv@y?YzLX$bB^x$ZZPv& zdfSy|YbBrdE@-m!B|)57xOj>O%5TtC*A=J*R1{-Mk+GM;631?xv0Hj-c9z7zQs&VM zMEbj%AK=hIKLy+K0)=QL*nw$h(r@VY9o=Yl<1|sF_l&kgm#603-VuQN%MJQ^ zy*>ds&=wPlM>0AC!9bcvre|+`XTI-E9nn;yebE-166=qD?F;NHu?X}O(D#Y|>P!O* zB_sVm32Y2IAqfU5Ba|F+O_D!h7fEb#3|bq%#lGki^=cbycV^L0KA;;^@5Ly_i>-M? zV~w%ft^PNOI2!*yd6d?b{FFJmqv5t6@Op4IUcb73Z=m$tExY$g-#lfvo^D!oo+h5; zb>K<*%jaDH=I$u9VHgO)@I7-{AFcd>4+hbsY12Xtc?rm}Wl6Kzot=Ff2uqnrN&gk= z>?=yX4GOp{y?zJxRIS;fzqPkfao1rbuImv^d}X>M6VrIyoS_Ad?SB)sDO4;F`I$)E zuTDj$!Uy1A_sv?hsMaQf*alUT7V$F?gWt?m`c9zxvs2*7>U-4QM*OU%+kzQ)o^b=e|1V+X7>t9aB;rMl-x2!|K&7zuEk|zKZ=X)dR{>Mi)+U!qbct~j0c8*vM!cMmG=kE)*-VFMhK6NVF#F;A8P_3h6M@4rdt2HNLVMVK;_>YaX1H*R(7tF_$&s(Do{%>sK*(!&8-CCgk zEC(C-3CHom`&`I8AZo*d+i@#>`$+o0KDBxio-AvMbT+z+uoX2(%ZXmeC1NTD+Fz}E0n9lc2Ct{{oBOu39cbvXaA&w0J^Z?03({y)=0U2&)?@lHzptg z&~)gw##j{M8B!ivXSi>%uAo=zJyDU>##(=mpVd~Nm6T1@>U+LtLD;MQkiaarE?4S4 zc6+@-ZBzUjkK;HNDwOqlp65DPR8*1sIK3H??0ZLosWAX{LJ0^&)jP2_HLlVk`fuX~ zZC#rn_^NcwdYdT@eSh;q>8nq_k02}g$0qp ztg$*%yx<#zMBa(T-60A8_O(}&dBp3UfOp1Cq+n_H#IeeIO3Vl`0TH2$Wt zt0*)k+B!)gE-dCI<2jA_wVAK6EiF~k!j}U3V{gUAT?;FgP+$#Knd=9)wicEY;oP-) z4*f=rZOjGlYpEKG)q~Lklv|NGBV$xl!Tx#7140}_5Cw$5BvFQQxrb1vHGl|z1U&*3 z;j9s7A_X4RZoAv;5Bn$6%Jud-m+@Hh2Ad1xK#{ms@a8D10G2!*Pn+}Q{CIwAZFwFF zhieTNpm>3188bqJcL0i=rs**@-V*|S%NFdbC@-g+o2)ToZzZ-c?q;SZ@j#(qemOR# z##q`#M0Cbpm3}XkoE};kl$Z;?nTpZ=g6<)Q(Gk^Z3!$0i77 z=7L;cAWGEmDdpN-0OIa!1z{Kp!tndQwfq+!3`Hx}ihvPWV-C{ zY&IuNO2u@XpsGADhwKL1l1tt*DY?uyM7hn+?6uLB8x-?y@wNt{`h&aqIxv!?X(&r+ zwh@&iZeVVq0pX@t(3BV40KPc`dm8g5Pn+)+=zZqwKBl+)%V+Uw9gfNK>vO%L^)8<* z+Arm+nBQvoB?2}+vCO9R$LAHhN|!A{26?9mjx?<`@$^|*W}Kt3&4~W23{=`06T7v= z*u#uiU-|gb4r8r}`?Cw8)|dlOf?a_t?XiG6tuv7Jf4yVf>AMB6D0dWC)<5B+xyXyP z?|_Y{TJ;+P(#8o*c+ zm+^&VfM(Zk(`;$t$B63{vNzao%Pkov@S~A)``pns*zjAe%UU1jcLvaBiTb~2(#P7< zJp`Ojqv0O{@OB3&3PV8u@9ygAw}CM1 zu!K-PkqB*R9_&0M7@@COqG2K+jdX9j)&%7R$r~^ZQ^mdk;FaMdEkq8B=V*oNa~GR4 z?pmE#`6|!{r0S2lfZYA$oCZzI*zQu_Eu5NFYo`;+P%ywP*xk?L+uQU~=Y(pV)k&;* z)-!PpWM{1_w&P*{FX}5dCq#+yndcRQ`A|stIWHl!>+QNb9Zw6hG#+2Z74XRS8D%-` z07@ou&JCz)adi2;EUWt#m*=(Uo+A97u?08-2>BhkFYMPWTmg`DKmZGvBBIdM4S0Dr zxpu;*@e~6JbY?wkr54%c6a%y=$H)R91R#Vkr3iWsX6zXU@blkdXft*JLRz_93dbVe+(#_h@~&>#CbwWp%xx`a zYti+!(B~SPd>)_2K1HC(bu(wOI92bP`;O4d-#f6$Xx#;%?cQ<|24W}-_qkmNT}avg zUg!d7|45%?Mu}7?Cx_^B*V}22KP1+1vxF@nR|M#aPj{Mugmvk^N0x16hKNvaEFM= z;7>((gDKJTCGb;71%x!erA4F+djv`2lCjahA!f)?DLMFQjg-4OwJJLM5&x4<6NqwHezuzc+J@cC#q-NBcHAQh_gR55|3O8L&inS5WBw9(`bxP$o;9W!qsIA& z{_g1d5rDLN!A%&5p(wil^_B%xx8k6uQJ|$nLVQ9-lZie4J=^~hgfU&El|Y!cGRnIs zA#MXi&iZNGHuPw^ve1Q>Ml{!SQ>K0|UwL14ubCSmCo$HqHQRxNa zZb>&WO!t@N0MW*MA|alD6Wqtx;xG%4*)bPb!*#kP&ia2$*tpyCYl|41Lgy8M{l+Bc z`7|9o1LJ&H&SC&p|$HH=5nrZi; z^;I<1^DAHOuC4xD-#Q7+wcmO7_1eUeRClp;1&2h32VJ~nGXNLO4j?`o_6M|1H?iutRIW@J3#Ce9^e&a z*Uua@>jq*V#Ku5_?d)A9z!Q)Ow?3-?EkD=yjmt~St3tWf`hx%{x(EZspiz$B!Nyzz z0wAx5&h4(S-#;snQz!}6g#7L8_C@wA_qPgN#b_Q{<9RCGr+K$08F}!3_5sdNod>$! z`XE8>KYO0zIPRXH4lx-9%}+}%>`Yy2T~e5>9|30n8QVEX3AQH9TeH{2MQ)^J3&?=* z(f=(zvEOC5I4_iO&nmJ)@d@KT;=Ellj5YX>buexafFRpeo&Ku*em3&{*ynHw36{a1rK}j?NS4mvc*aL{3lJ@_ z@qdM0m$71vE+Lkb7M|OcF@R&d1U>;p-i}^vDQ%1En+MIiNP-zfs!_XdfT>sol^Xt5 z%Wf=5IK5puyyrnSp90ISD_ZmN{uSbF-%=vHy1)bTN#iLjX>Od`D18>@oR^KfUh-)2 zm<+a*j>^`yA{LD=Wz^hHw#FIIi9U3GmV3uLCmOq+i*K=Q@&tTn+4`S>(SFa1R|q(h zQyy>|0B;UXZj#~HJ$abP$KdIHOZ2^ZW^J^|g>(NKIXAE&a}MVZ zJR=$tyd?w1E3Z%ehLWdBs23VuWnNZ#-nl*RxJ*X>bE6OR&UKDaU7t)6P9zB zNp;3LVZ?*&M83`&oxbRK>A)Jtx#q**O*$} zbu|-Isxp50Kl)^psJ{9}@`I>ehEtpO0>W95%7})je%o7}NJ` z7Xes17aWCQ7>EkaQ_hfc=MudV=!HCK`TCmGG!FdRY8{HG4(E4F}wWfAO`J z97Gqa9mZlGYO(3sb#J;qW(EH-7XS?K)Sb_~m?z-NxUIEOg$4#W_ofGgUs<>O?^>fo z^xnr<$Kx2v0b>DaAPupSf zEc2XCV&J7!m)9~GK7okuvs;I;TNUnP2^)9J&NaVSTFR<)(Mm*89wvcq=f_6WyTwvg zz?g-`|Ka|1j?6`Ozp|clM_L~q3D;&Px&9>pYxlCNFbo4>n8)h-FZxKZ0qN*R`j8cI z5SMO&G_*~|jy+?4YzXTCHAx?9C-ozlPp@dYYffj9SXNdixd9_NMWeIkBruapbYf(b zbyuh3LLi_+l*8$FsOrL$EqV*07uW`7Kml?_2LS>>VD>9?a%1Q*2A{DW*D&YWM0l-r zI*Smm1)5#Uvy#_1O8fN73GV3Yt>vf`J4b+F^t?OWPBLhL20}&v+GY&2b8Z6K01`1o zQ{Ie0IW^8-^91@6BwJ5T{EZVbw02_4F_?{ST{1`n$AMY7FA^g?1?4@Xo(C%Z-|n;T zNNKPoMKpv+`wz{XQS6@V0UcT{=gWPpQ*L7Y#zZjE_mD$zyWSr9yxGu|ykpjRouNqi zAqCMnFwLVVHwV{g43Lt3NH0vMX{KrHqgmqb8K47abyMk-iSwP9X-j*KjO6UY`VGh8 zztAO&o3)oez4oif%sSr@ZKU40R}L#Dj?>d;`@WyHZF{5=-g%~f0uXmcsSU$G5Qgu6 zDPP71Y5NyG7*f+T#ifEgB(WkQTiVs^%{Dh*xBtD`wRekL5*5itJ$&!)rY8f)(Xjq>JgxRI{+<>iiyKnG209 zi+5p8bGvc4jd$qhwNTJjy!fy7tUAUWhH)J|bCq!s&jD>p_lLcUz1aqvmap$KLiJPV zS#jRtf$j-`eJ$t?>{ovzk>naZBN@`*JNYifHJz5!{|m09Ta)87X+|-{43bPu8L?t- zHewFhI$mN~G@3qZ9)e;!k@nvh<4=OghY?Jo(P=TmYAqt@)K3)-k_(cCu2HT@IjgPz z_(;tMi*;|h9$^jnhV$1L_5dW7#!@$tfP5LSIUyt>BqQHB>x({E_w^yw0RPH7wFt;> zPJ}D{*lagoY6Jn4aLyQ{tBtvpWCjge8R3L&M7#Dm zPQnM`z*L!c&nD&C`QX=o9P0`B?5P&NMw~OE7IB(njb{#|EQ@e8A!+q3_pWoxrquCF zV$gPzb+NIp7>s-_`HlSJDvp+7~GykP7wH2&3-mR~9cIaXs)V&Js3ec3d-myoo0CZV-n9nL%TFP}5N`wWO3W znRZmPTEVppdQU6Q2;*4bT5HbOSu3#^OAm6tP6N}(R-SjAe#ami80jpP{Rf%k}ah9bj@LuT;WSWn#2`f9;=TVp@ElVT{7euE`n5Qn+_yUhe(A|1;;*{-6IiEPii62Hvf)e92)z{TN^( zIb-{@@%RWp+})-i48%|r{i6%e{V!Ipav%(?6;TvKDW#ohCtq)pytfTuy+zA}v*@N} z{?-1V1vI0z2_3#l>-W+VqS<0>ReqBoa|;V^zEgNmE>WibyFSH$do875aZkp328Bm1 zvYV_Cyzi~eViDqWMvR4VJ}N-pim-T4dwakCiUhv_r>vyHM=;Wye}a~hR;+tIJu?tF zULDKessHQw#R$QGisaUaTQqL1i`c=2U>|&c#-$TUi8UH~cdT=QBhf}>{A8cTRFQJ% zTN+_Nx-j9n>=`GU?ahbW%(A$>&rJa8?k%-pCBa9vKOdY*F(-45^P2^3Q+R^`LWFc8dRj79W?04D|v}ODjfnAkOIV+CONcTSj z;RL}wB;iVpdq%0`y@1un^HseLGf~}1>M`%%GfSaC3U9Of3}*0*P_CD{bB%hs;p}S2 z0a>8bIV~+zKb2aXrt*wKpo;z3_2vcl9$_Z{#H?(6-GfNW9NK2DdM0EXFkd-R1Zs_J z3kW0AwAOyFrKIlzZs)GG2Ubb}$K!Z;^N2&+=7@NvdV_40sV?gBh&5V==GNE;yDcx|tT zfsmBu*4itXKy}AdfiROtQg%)H@G4%IMakLgFOxtr3u*U|HZM{-OE5E|GE@B37j+>? zi?Z9)Xk{vOorBa@(i&$TpXjRe$)c*jq0YksHGiAk4m|cQ?Y7#d`uflvdMTrvj3-t(;p% zRKsb#<0AlT_p;hB3`Al0+5G+sFZ?jwmOtey!w{Di*I*LtAjyt2M{_&#Dp#rs_?u2KHG|e4BnPoJnaVK@Mlt zycQgzU2BbR9SOO>843Cm+|)mn{5~tr?~-ih$t>T5$CTN4t|@>3i1CqXdurHEHNZPJ z(|mvYv}7Nklut~S*!b~fZ%vZri#($+kc-n?{a*?ctKLk76Tl~8zi~u>e;mhmB=Aol z{wV-!cbnoM5CmcP{bxPvDZXb>vgya5}vIWRqvj82hkuY1@cT zU9SdLwpC_D+`5b|m@o&WmZpwq3WS={ib<4h<~SLg98gZNYnsS&G8m$%z95>I_TKmI zuMHwdw0kCR7JS;+D9*_6+RoObveLT&ks=97wUDormg1F#EHm8K#u?5Q`<2+1>8jvlld9-Y;KiiH6I})4AEr z#oW5+orU>t0Ds1JPnFs?he>Sj*95NCRf(aBLz`IT`r3D}B`u7F`9cC_lmrJ9P+vw8 zqZ?+yxlStCW&kRz^b%2!yaNgs50K;(g*pn0@pz(RjORXklhO>nCnjm>24nGVRUi^= z>y=79W(}VEm*-f&$M5nCgc1J_MQ7ch9Gk)gdV+eyCzyG|_*IOqk&zh3l=@7?*1F!x zxO!?``;{zdlV1~Ys^EMF<$=Zyd!*s}8|7%L^RDsG4Eh?V%s;ZwGwOab#9W+PmL3g& z_5&@$)s0Uh02-8fx?JGp5L*a~?Rpfx1mNvnRuhPVAPndIU)AiBW%z{;ii5(KVBClZ zI%lRY)z!C4j&KKTzr&+n{eCygi?ZAdk=TywIt6zHmLM$Rb2cN+mcHR+Ph(1n@coS8 z+2g`-8^-MnOP%Z%XrEEBB0+*?ihlx|aWXLkLh}2Y?0%GsIGdASofY^h5L!_48xXZ% z;EIB6!O&m(pq9E{S?Rg=o}*Eb*nbwWW!!s)3QFYsdUi#FIhfWJS@3H{X7nS_mobSx zt>8qlOU6ghOOamJ6?3DlqDW69BwEc8DNeDd*Xkiu9=Sib4=+{*WEq4j|2Sr{leXF7p1<$P8zPucvBLbTHna@x+eE9+2^Ut6mySq!GT(t!9(pEY z6N5f6$<89UNy2I4(g5IF!N2M9yPk`> zwZzmG^PkZ?=C@)r@=h4b6qaY4dagOfCF$7QoAhWT9H}J|w6hZ}ZqNCNQuSfYp3Obx zIk}!EAK{fX(Lc3q&JM^-B9wQaWlB9sqSs$n8bCz)v?p228sV&2b#Gh8=Txz{|H;1WB0z04fwx?P zCh9YNu63aG+}W6i0L0xvio#G31kf4Att*d_OXS2kSv-S71)mh3NMuk(a3dN+^7E^^ zy1M!h2-kJJEz9yTMDOfHs!gt}4hGZ|@LM64&l~i5GKCu^a_H!c$R@`(*m19)N2Jpa zny4Fy5bx|!40@{Y?xGTuYttev&wh5jEd+yIMXX(n@7kcnA`>1r0^X3Q9H8x5ABkc9 zN^$w106Tg*EE z%m+2ksQ@s?&T-LdXkFf#2?PRmIk)^iSy%oiKxqBAR<3gozdiCCZc22#Kh1=U>y%MF zHyJh6oSSE=TbxEa#m+vn;cr%Ucb&m2jMt}YgH722MW!Xd9RPQk#(so}%KFg1#|?|m zr$oR#Lork9zY{w!B+SfFpp5GcTDQkDyU*Gs@Y;L*3P9Z%4;=zL^EK6i(x_f(P4ih0ruO&%*g4*)QqPf{x$lvq)mO(sOf_k)wW^c|_ zx=55(n{0|iQ~vajv9f1&RL?$$j;&lN;!--`&(oortfM-t>cW!+d0nF6WJ_6XzHZ>B zL}CyY%~>~7gU3<5)kIqVkPMRnAI&$mz~&?>Y&A zxoL)Ajthfa9_utS9`Y`8BdH6}DE($K;CV@Q7+}WR*iH9otsvtXs7gbcY3lK)mbq?A zUK9}4=C^(~5$4z$Y&4)5e7E|eW`!$d?Tl-A-(U3e+}n?@a;OQaZXM-1HkN99$tqbI zQrxD&6s8L|`_2ARuUkLJWcM2y1-=UGEM8?@m$Y%9ZB|m>0B{Z zhYxSM)o-50?XEn?7Ug$bpRiY;_qg~lFaO6*@V#?e7G-5+um9(_$f|m)vfapl%2Z;F z4y#V#CnKibU>#)VnzAuf^UM02re-wq>K~Dz@2)Npc+~NbaY^KibulWZp*J+Iv)vR< z*X=5fNn64>r-a0wo3{1R@!Pvb_7H%zdrNH~h=C}&7H9uEOg=&x4%{^32gLpwjPb}G zNi9`ZmtHP}!}BcwSDTIh{b8*jz@s428P9>W@Wi3Z_Uf6xQkFZZy0%uH4CK@V4l1~s zv*`0|tiX4>v?|Zo=(i7Oe~_(`a-pEB|F;|e;I$46?V)cAvU`;xU1+)DY%yGywWLDk z3?p>!EudGy?%tS_o(qK{$9ULHAJlVE*sU8I9DDn^-M@bliIr~K^%hVw`tHf=`{z$F z$-gO}%w`Z1=Ih|jb)V}d=fksqi{cod=loDHE2c>hidnw+h}iTl)OdCZWqr1A70)eZ z>N}X^uadZ;pd_8suf+N%QMLLy|86XG;*6s)EjD@_4*5kc>1@|sQ~d$^8zUjwh2I` zAd#5ZinG+%Q-CJfhSHjW)kSa5*J!9l|Z0Mx<(F)Pilg4P*x2PrAJ~`d? zwmh`?z6|EOL;7UBE$Fdj!zxidDZi)0y5?g98OzPz2??mEWs_(xjk%}YzyUqP*|#K^ zmhe{#yx6< zP$M9R@(U!$KG#Z1g#OOlurp5qJi*j940DLwFVQg9X_RMu7{)fzBR4Q!;MF4MJjeP8 zf$k2%PBp0|-*JcE4xgSLSI>+x$h^|=PZ{GY*E5>(%bZ~Ub*u85!a0d}n70Px^dgPa zl_ydozLR?H7$k00zVEi)!YEep!0@a?xLZUy_x2$Gb!VG`Fc3pQ?|-+RpRnx5-Q1OY+tc!e!V~an|?p?9a)<8esVqBR7kIo3fO%v*STkk)RWiZbc)0 z2%SyX3D;fNJ)5CZ(!f>l($r$#YjoP;RHMO8q?kp6MsHkK@?KP3g<`wcR0v>%=z7~5 zwPTx{F(;RFrpUL*dyEMGNo~3psPr2d>lZ89F!dydgtKAY;aj%ay5~Oe{VmJ#ng#&^ z2NYtI1U7PfEib}AvF2RIJ*H78N9Ob7wy^^UV{n9GUJ-_+-{)+c^FLFP{B0FG0whdpC+Ael4NoVX`aT6@d14z8R%HCefOvmoK8VKq2CmB>((F& zJ?mH&F5I+Szx3z7}8G``mQ?Rh@wK&T*W^?Im9--FO*6a0pXZC%A zO541_q#96D-tL2)*>x;AvPl^N$0Gz!eR?jW2aCD;(HXdO z1*Y$LHq)382e%PK&}c|TK_&aUY7{>Luy=1O2m?V3hC$!|o#huk2-1p*-q{-wD)z9O z?961cr$pGqEIk9vezji~aNaQ2%4KEL2=ehkZ76PqK<5sd!4NKo@~(OlmFZ0{v2vlc>9r$Edq zo@y`xi#%&-xLhyy4SGATR*pXVeb>|fm+p)NTNqP!8iNU9>`!p5! z3`o!3hcRyL1|33T=#a>H2SH5!EYk0X))aKr~~UuNA5_Zz${^x#T7Qdv}!LFbo4>_!8awUv>E( zzA~6BDP{ZCK%o$)IH@CP#?t6dN7&+T;ag0ijZf6Vh{~iKYkhLkC0FReX1uv=^Uf=3 z!b9UUZ2Urt+s}-%+H5zDQ`E!}so?_0l`SwD`yCqVnrN)EFQV(!S#2LiNlUB#;5Qk) z=1PrcvvEmPEjn=Tjn|32s0j~`X5;i$%k_I)N9d<9JB5xRYcDYe)u;Wzj8qP$bLk{T zJ%+SGav?+iYr#=_j48Wd1XkV*3u3L%Bjtn}_xO1{X(g?qP+Tb5`jB>gjxz_@d@B6c zYAS~;vlP-I?tQmTHhcG#{*ZSF;?6#K=9^>&Q8D1&{db)6*>Z?I6Lbpxy=$M=7Tr45 z-PXAZ7Pjtjn8D}#jb*=N%I_8jWg9{tl zfV_KKK^TaEF#P_H)i;w7KKNM_58#yrFRa?uHoKciW|F51;j~Q4TQt`EZtI*+7eTPP z^y#)fsTllxP^TE4M`98H<&i@$qRM(InM6pIhuuZ6bqR~$v?tMKX5RLWLtt!Ea9CL6 z{O>KNR&5i_A%xc#q^Xvk8i7JQ!c)9+=m3SDhbqS3WWW1mB5jD}n{LSUopHvD3u68)xO8B9zwgYR7ZIA> zK@RJcIHbAX@A}4O-L>u5*LB@(-(+c`X>Hy!AN;7L(KmC;X@jqh(GrTJO>*Sz{&MDf zKPAg_tkD&A?4Kpuet`yyOr5`gMgaix3>JM0gg1R9pIahc!_4lX^ZtTU0*JUj000@7 z@c<#VHPl$w3-OBrR6cPNfVF$eZ5W7QD7uX7f2D0%-~bnb(~q|KPCRyItOrF=Zyn)Y zkR5#3@VjXaf88*VY*X_}{&Wq_qRh|ImFYCLU@Oy8I4?f#nGDg@CsT+~!@7HGe_bWj z{9em~?65;YmuX>I&2Vs7H1arq_qBCsH(Hm&u7ndK3c92!avO+SGXT}J&4Ur>_$c+q zj-x6;$-Y#*;t4u!%ScrqE}7vPwj1~`UQa}bYm9D<(6ih?s^lg2_jKJd@2(j9g*|=j zXIY!=C)4+*t~5Av8JD51+lvKLbBx>9F-YgQb}nYbhT1G>ZPR)g#GIkJ)STVU-mbad ztOmJrxwSM$?+h*TBvdhi%+}|e_g!*qAl!}^(rZ=*<5NBAsct8L>xiU_0C^8@YlqPTXBL7SAqt#mg}i?YeLu}Z#ZZ>;D0$iMj?E)8xp$?`e)sg1=zY9iukQsu z1)%M2cN2(VAd0^KThohr&?s6~l_>p5A#8}_vBzJRK-e3iJidYGR~Fiq0=QH?s8KFE zYDm`<-V{&*j^ci3Ki(3$M)E*H*yjuQ6V3%u0>jGK2F{+@1x&f5m<&GM`WrQU0?Y)6 z#j-V%Ecz{CX7N17<@_j}6rGO$z0Mm&l)q@yXw2 zBMS>*)%xFWi^A7g8PsN(AhqE?0fcK>TRiT`EqGt@*bQm}Dps2YpunL?i^1$6NpNgt9ajjm zdNUzYQjf5BA)~fxUgRKl>~xrROSO*G9@g?K_&5^k56?0G(Pk!H|H`nVT@+ zR@Lv$=Gh?gxm+)_J3A24N^%D z1!^yfmUxn)@?GO+K)zijki8QqjVFbQy9&T`aM7o&vO$q!%`~3Ct^X>H=Zq+^=|a_3 zIYeVATeK#+GJ(y5M)xm2i#Jp5d&kJHw2BPTwZ;fX0q_3!@i$YgOs7(opV~_2b%hf3f|4%{1J2(r}>CkD8suhh60#QjT z^GdVTh0OC~blj^QqK8`FgYgD?FesHJacGw_RUaSz)IHy#laJeX4r&`jF-sK({L#i! zuDwkT`YJ7yDp3v88y8%=4I-IMD^C$kDX`k8T@PF2O4g=PA-MIdl03_}->egkz?Jc= z<|L=$iMNvRRbgFPgD`z1XWJJZeUP}huxOXx>jl8}Iffq(U55r&O1kvr4j*^Xoq*dg( zg+h0iIjc}H8_Q;bNK0Z~r0z`~_=JAX=M;i3WUexIWA8ImW&5lF%C3(9yxmC(!$1r~ zQF8xFC$)I+X>6}d7KRW^(}N^eYbafQ2v;_-c*8$Ff`q?<D-l3T6U2Lj5cZy!8~tku09lYEhN?^R;o1mEKznavI`6w2iIZgg&fr^5 z<=`#*X(*spztwW@Jf}a_v~ymkm!BMbz5?)eC#ektK@dfK|MOZaX<=gV;8Sj6BVjEB4QhJM z$jZneE*;?-X!m=EbclW}aT_`~4yw0mivyNb6w2To&(u%I;3Pexawpwmc1i&rm z)**Iixc_`8fML$16aoWm8MoCF4&GqqMpmcss7eC>%7{6T-H(1L&k9fXQZk;m?+Eyc2+(d8CDm>tLnHbZVO$w& zsizaTIy_-uymxFk0!mH}t0Jea-F5EVa>QneuA=kydHc9O?%za~QQ=yBreZ(GMx}oD zwkS)H3kNR#RI z*zT&b{c^z%K1}s}h9Nj52!stJ0z+&1PBl@dp0{n&$$1smKC>V&VPU(ov36_ez-X?Q zot8%`@5YdHYp7xF7m@FOA(^*HUUrW7Y?8YToimih5*&HqTSmfIaF|trc3pN29zpRv z1?(KeP7tjv+H+Djo;_*H-(0CSf6DxRgGey;q5)N}p7SeP8UhAxAZ-_Wbzqg#w;B1_ zPx3oa$EiAP2O=oKobdwN?z2-S=zHtwlzt{e5)}5nJy`N|d%b-b3Dpnobl>rg%6lkQ zx3}z<*r@b?HS1V0&hu*e#+A_MP*jFB`S1e z_N=6epE330SsIDI2%<}B9;@#i7THD%*@cwrH^t&Gr`Qu#x=I&+1VIT&g=w|-^o5NikC`1fln7|mai63pd zrIsv}R6p+oHAQ?v`22OabUVgu_ku-_3O(KSUAI2#BDfe+i<_2Ua&V07e(nRRY!du- zi&z$m?H&W@lc%xGzbTZwPsVK()YorHiDdu+km5d}66G49!4mR>wBsAcJ8N8qS@=*6 z^OE*jp!BVzP!^1(IqAL`2-ipnqA1o~2K8_7VagPku z67Aly4Gs|b+>)KAF83SmYkx?#N)_Y+o5!LtD4B$))Pl;vm_xt-VeYQSfg!UO?BgAD zd<#PckUVw|>x?iyWZ3!1W=;8(YkX=vmIZ+WrdATwPtT~_!Hr)LMjlS*On=#-VI1vS(j3|z%IQ;F;S%^lY!;o`=6>pTE>}m6b(uj5Z zE;TA12Im7hu#rHJ{vVavzAGbR?1?8B()J`R%*U`7izlBQuVBVpdgox)zK^a`4rxK5z!tr54`khZESp9V zfJp_A;N1m?t&j8EJ;QpEjQx>Pn{ zf8C(C&Z|^``?V|sKX>i2tGC?jt>Cxzy&|iPeY%F$t#XK<(T#nuw}Y|m^Nsf-0CV@2 zsz49}VR${W|J~`!A;Nd~39TT4DEJ~h<6JuFbX6)jE`*bQ|LzTZ@*+*Jep>^t-J^Ge zyNTXY1ZOhZeVr=QJX`21)@_Fh$tnztqvlXrO@h(NVk>M0!qN3!hiD5?%Rm*n1V5U5$hRYH`2a|D$nppAM9>0D-lz#Qa7-=vhHn z%*hIialm9f#-evHM1mKu5Zpg8L{5EMSdI~evkdJ z35(O%DVYk{N@W5q_|U+**}1>`IW+~S9SCgf1l2d)S~!fn#PdlJXcWWM)7{*)Vb&K?z+p z591!~5HU&v!KTwS)aRK9Kq<954kIAkN6C+ORHfD8)ONIKy%uG6W*Eu}Z4R&K``Mg; zH3;wQaJh4Z{_R)iv9-Lz@1RJ|6o;W?rr)fwthS8?s&J8F%E}`*x6j+#_2c@jMcNo6 zh`S6^-hWZSTq_4hR(l>b2xDv^)!93_AnO`O?ec#4N(Z#HR!5w<=O#;#FS1)^p=X}| zop)ir_Fpta4H)Aqzb_(FB)E&ju^KDaE$-hWtN)TC+`X8|d7VYFOD9br}b zqZFUFs>EL|<}bt6Fml^Ks-)f({N~<@@J|n@xrjO&rX3cj^9tTdhzWv{S*Ec9%<4g+0q6uV_mj4r;uD6Q;NyX}Z zjq0lG@#=+}*HnM|xjht02Lqp@x7x09hD8hZ3Kry`oqN}2909yNyJr3s_-vimy!YLn zAeBI8sD(+|;v72NZ&on(EgoU{gxiWmrvnY;9_AtbM>1Zygr36@V}8h zC)lAmur|4suq_Ct=kPp3tKCDPQHTXG}h0YB!TAQO{DN zw+}wiy<_P??e*OxWw?{X&DMyU^#_q7+_l;c*)mi7bb+P*Z5?F`(eMZlo0|l&v z=VerWeZTi8G60_Gt{3L4p;=Iot{1yj_`ls=8m-{z*@FyHpfpzf6e47!96i7X4%Nvu zIjrX%pgMI}Z;-St8@Y>SG@WzBbaZ7XmWAk(oY)g;x?q_`G@O~vQxP#TDbw1XKMU1Q zdFxqsj@!biC{0E^6!53|FF`^dc4ZgW6_B*29W{Ac!U;Gt)oSHPx57bt3h_PaW;Z)O99izkBfAi*2?b zSad2mG&I(=kiQ%;5*B3F(=5EHg=zxX&u4;(utfE_j%)y?-PudCTEV->4q&gGak??6 zF>oz4)@m^fr)~zBG$7q3cQl05j`7`^UPs%j#=Eba;i{ANtR=7NajPc3y9|?YLQb)L z;$4QT1<&Ddz_Wg0jPuTq<2dy^18GAn1Th(x+x2#i=Lt*xD9*(2=M&qq2`n-ES}NHO znCocz3u?4&073x@&Hplo;w0lZ)Lj_W`{Vwr69F-Bj+Emgs|NAt^-czhQ3?U1?Rb%BIA?^c5M~g9Jm*sY=FTMtK_G~NdJpb@Id+0; zwH9T{34Rl!CT@&22t$8fzkYKQ2)Q^s0G+}5COpvWp?H0vihEj;qjb;MciXD&+8@$c zwR!qV=2AruoRh3S8~t2(D>Bt8aB{Lo$MZK+?yefmMEyVBWRB;;F7ZGzfX>4O>i2Z` zI*d9b$24?4!iz%XC7-+-2wSn;gQ6b=!#3i#B)G;vD1**S_?db~WzmG73w3@<=&8Qx z7|g9yU}7R~M)JuT5q4%Mo?RunO8{D*WfueMSoH~gib7lh8{#)=?M~CQ zM_}Is$h|R_!?IhC>s7Osb0FxJQCTA@)#z|IjwnL+2sHsKOV{xWXU~Lty_eY4 zaT~aW?iDDv;*}LD5~2<4W0TJvu@Gq}A+1pE7V+sHUkzv`#A) zsNV=Yyj+j7yDBto(mR)YW*3RPQifworiQn4h;Pg}S`%Kuti{vp>ZY~bxnkD9bgNuj zJ4$0D2+nubB^9F~w_n%wz9xAl=mc;unzPgSv|IMeqhkeLQpDI%svX8{{?f=*Lgta3 zL<%Ux+ZZklJQuz{91r*QOq2}Pojg0^%d+CFWj8H~$OA$|KDu<5n>ZCdAt%*WfPlq5mlM_?9^-WuL-HR|1p zQqe2iBeZhK_J}Ib_i*;mldj1lv4oLES!hIhfM;U>=vv;B@0${cY>pJFLc1~|g_4PY zkQbe_`_M^5jDQ4sj2c8|ow5nET4vQ5gst_e=eVHV!aLDdHHOw6Yx;iG11b&bV+?nV z%t*{~19o>Dsr2feK>@>N(7w^Td-t{o?i_ZhGAH*ng1_S=ZVyFpNWcy=!yKJ zQA2t5eSe5E%dpX$8+-Nf6uv87M>z5C8RAvrs)b+y-WmaTtDR zBXa&i_RPko$)D*GsVvZO%|=H!nT^3gwj1WndVIBydlq@7?Zs+Efk3-|w?T#^O?GfRvs8fu$*f5bq#Yn@5D(7h*6MGD=n|D0V9Gf7 zB)T|m!-Q)^IRmTZ8vW4!#%bJXt>!yo=SlLIW$62@mB7_KT2-TrPB3K!@{Q%++=x#? zXPQvhUK979+1q7IT!ABV$z3W4bj$ym?Xy>hX za)kO>-xz;p)hz6b0qLw?1R(BQQV<4$AR56l&HWFO%|OK5LamSokH!R1Ndy-r#6^0h zKQ-M|SN~}i_8B<1jZuSObzW|@K7tf{4}xU~*wqK)8Jv04%GB^e9bR@2tOVC6JH)7Q zW&|%b9FP+dH4r1@I#N1p42!4Mu1qiPv!I@TCpn+;mO5Z=jn}*j^t?MKNH_)N=J+z$ z92hhAlCT7}1OkkmsMuNWCMGa1CUbYdg|8~`k>BGu4)c8;rrWe^_}=^SJUpV2SWB>r zxbE5{w^WC%wM*bq&M+B~0d+v>-3bjcM_YP>-`L*`M^21+7dSvFU3V)w$XH^CXW>M} zZotnZutugTZ|eZ5)WQu|NCZqh4-!W4?5eG~;KrBa&$m~@i_Ft!v|LcrRvOOYD7#U4Z%D7r@ zc+fOdz)iq2Ks4~cX0{;tc@f6rnmi=dZj8x1VUDba zec#Xb;V`5VjeyJb#M%Ok;dkmLSiSGG-1_F=6MVFI&a{9bO6FW9CqOLYktwQctSzIJ z-4)C$C+ga@2*=P_E#uxXF8?V(t+_!DL7!WIq#fR`5`)ScD%a5)w(W>&OKEdm0F)B2 zD`%)iBLv(&XWmnw+ctAoI^%zk6{7@JVQaqKxm(}i{`VAsw|hxp7zSbh+C}ewncO6h z`xF&k5ypW8;x4jkV~jnq=Oby}{qjr#Y~|z|;rUd~x}&J(nytu9cPp6@6mmCx(Wowm zLbq~ah$0LrkLF*QS9jJ>94C<71@q>3Idn;~85gvAtci9yYNc_HAegh~OvD>dqIp$a zFPudgeK3!bTOxKBx3pyIU;;0U+(CzN_9D?BFoP5o0(rx})w0laGLK{;av5ceaDNlo z?fd@Pw(W-)Oh=1cRJkC7Or^@ga}P)+Xw@js9LMoZ&+3sGhbihcn)Twtde~)t&wmqf z&U$5DIkaZ=*shU_$aKfhw#_~QxJZL>((E@!#rM;w^o*~23e;)F%er2bSYtb=NG?{m zff;}cU@gwd6KO$pP0lwvg(hzYVXWbf`_a;fSEy3f5s2wuwa>d4kN#%aQLn{E0Ormu z2VoEjqQAPGZh_UaD>Eb~9&fNEii!OA(@Ik)_cb&3#SmU0q<(eS?erQdGR<6|o%3)= z8Fv54{}ZKFLqnvBvWBA_Z@8*u$)J<^CMVz4!4gx7G$4HBlY);mnn;^v7|G#=J3tp-SKc#duP z(t^OQN=;Sc^xHvp0%RmnGCXPa)5=^vk5;ZH3ZA|9e;6)ZIPFcpR>ngB=FTOBVHgIY z$4OVd|K4j~!Y3&&@WLRP;(kJFD3l}wM>F7?IYVmUITaT>!ELD-F74p1ATLTtR~Q+_P%i zHtF+;_VVXunE4oM-?X^1qP^oL3%8;j`)XY@58Umx?Wn|Wrs&(OKf3v{kZ8suxks#! z;J;c?Vt&2%{rwzN%z@V0fta|CYn8ro2#zs!Rw_u7>m0tIBAz$)2&N+`c zyP6L;TNdKYq};j>HRSlOdn@B{Zg3L6lDw7(UfpBLt6Y2L57tmrv%8{&Q$Lr|4%w{| zQZj+QaeJ$Wd`c>DJY}l7hHDasSJrGYtN&oG*5cfe^NCxReFC!y?WTc!RiH!~Wnc3NwUl_Y;Kb}T#JB_8)Pu!iL7t9_F z9@QNWh-k<-9uJIhA{Wd1h3&p?yg)FZjHPRPEC{MXi zpEfw|54WnrT-6?~qOo=?R@e49Kj5U8t^jhdDo6p;kP*f6UqlNK8;p@!t)KPi{({T} zqe+8W_5{QdOSgdwqCymQZ}7Ua#_$^<9`EC?S7IC*lMv$AKoZG!lKzaL3MQD}PntB( zb5f!?68$mP7)3fej4@6DjifgrQ_VSlr8oH?^bOuZR7h=V#vZZ{1^_0WMI?N*Y+Wlo zA^V0ganC~bsXKx|=%KkajN8mH_X$?D@gkF2OwKcYi&N8ej(va!b1fnkNW(D~lx?h^ zyhDNvx z7U1I?72#RK+Ug4>x6+jU@Yhmtt%lGAb;U=tl>#AB&iJ>*zztm)DlNggi=+}d9e*uG z@TBI3_5f&zx|K7`57on7`>U>9jYx^_1yvbB*5mL{ZbglHoL*E!7-Kl_z8L2?j&06) z>gz#v_j^gh;XucL@r=RanUE-B@Qn#?5 zp>D+#Jx~wF3Q2p>y9@hPZKWi2t4xW~HqGI@{gQNEoPqDz_o_@%=l_%a{B*leFx=h$ zW8E~b`4WJ-Ge}_&2!h}<;{X5U$&Z8zloUe*1rO@Q_Uu5Yn&@ap{+465 z*_jLP4o+UsYVGcb@1LA|J7{;(R)ILFywy=s63kb4Z%!#zB@*(lYB;+c3=H= z@F|AG^=Os$D@|k2u1m?Zg;G{ORiN!@*v!CdNniGTw)bPtW)1{LGBo`&8N+WkPrM@l z3gCeXOaBtKLw{6?!uZG`d z+|G0BU=>n%wtGdX{xTwGYd96Ul{#$~mNuFe7=7*l|LiEy%zA#RC1YT=Bq;iROEX@{ z(54AMMQarT-4$DnM;y|}ZXjw#K0i1=b8k<#n49sawcUSZD%Y|t#Eh$70jRsz6NG^v z2*3qsG3mdo*no`k$*_bNB!c=o=COCTv+sHBQlW%@_XuZC;=5%1r}HGIB}?cX8g0v# zBAk_uJs_7770+(qk~a*%wbJF~2#a`+To;9hQ5=7r@_QRV=xc8d=r@X*&O88<_pi&{ zjVX&vBNG4z1dXZd{Af4F3wz05@jN=@+zcC&X`ww5g$!8}>k;{DZ^`d^d9p^RMpelu z7un6^Cd=@A;x%T!)IL+QtI;0WCm_Rw=+A;||k?Z|$@I?}wZ)ZwN`Y5s9`c=S1O*mWSrO z+}rn)LapVM|3|0#zBz#7NW0L{2vzS}26B^f^PK1Pzf{}ZtpY;1IYT`1z_!7 zZx956AOPD7B=p|`4bYMqlaEX`V2t`x#q*H8eecX^2xlwrzdV6Ykr}RVEUzMt$tO64 zRlfQTO#3QAl)LZ3y@S~`IiBnEB)iM7+m5@bMj8}?NY@`kihhq#oAplY-FVk1Op!|t zHu7Ji82$%TG$=?YY~6U;_wA=gG&))YYt_c5y-NC&%=201_LgONJ^$3#wrx8p zl_DEqqhHtcC6gjJ2EChE7*bS3WIo0$GI1QoW8e3)(ZoPKTB3X>>u0TuQDjevJULET zBd-B*=lbj`iax)ay+Faqbqu{!y&7iIBDK?E-Ddh|;Pi=itNxmG@DBnDZ{lkXW%CaL zmKWjbsx~@-dd|JyMH_d9uv4rZ$u?Q^q&%7pUf;qB(n-?v8fKJboJa6|&dxjbo>?1& zV01TUP5CVzg-n-O56?pYu(ZAhho!hA++K@?<&nAR^_o~ZjDzYS& z)`m9Zmsd{x?AaNeR5wx`hYH*dR|#?XjR%~~FXBGyAxnMfi#p5H`Awr&A;0SQ9R_X` z`RT^q)_>}0GMjHT$=ONzZJ@TzA8sfnGf-DPSd$Tu2~)M)^Kwb%X8#syh7+PugP_i zybt;6aLh80pLgJxaZDxCHVCjD+2#ue^UZJtdiOdO876U6nIZ$t z#=8cgu5oQR`q2rtzI_*fw=>8=7>0o$2d?m!{vrQ=6I!GZqg7HORB_;fXq&dd_S$Rj z-43DW&i!kar$-bK&08H{<~-Sa-`XQ~)^FJuj6DyiS%$x)?VL7UIYJ}Qv*?IFl$}3D zA}_q7+IEI+o#}!0eeDl~{>^ z=|WyBk+w4kkWS+8(De%v3la$uOExBG=JEXW5W*-;!+RW3oLh`)&=)dXIcEYGB3t_X z;+V2;b1afu?7!^sTrcMtW89A8cr!&&qsZ?`!VJ7!U3qmsx zK?*3%!=glk&>5a4uDE6iS!Whp8I@vFTu%cr`Te@SyCU1IjCB)VupMNYtc1`axL4cL z&a7Nji$5En;d#eq>0fc(wg+bUx0b0V+IStDhrpk9H$E=`csrNWhG8g*PC97U;*EI! z18=9{h#oiyIWbOKfrm+Kqv-0r`_ab_Klt5>@IObL{v~l6jW$m(`4M>@uPfyIirlWJ zq$w0#u+KQOSAbh$d^L&MzEd?A3(_aqnaZJ6wuiB zeY7!&H5)+t^*O+dLFK0RQxNhTH7>)k<%1Y-f}U-N5QfhohVejLtCelrMm2XF$G9Ir z)49O=L0m&M3Ge895Nx$C)Ne->%l!kUwtBS^bZE`sx8&utD`J*(3y z$hozmS!}-wL|q{3rCqfxuWWd2$qCGUugN$(g8+WTZ}~1@{e{rQRHC!ZKy?$pr72jo zVjD;>Z_XPa;%21OjUA76b{G!(McM0$A>}YQ%fVXLs^)XXzHu9^rIOY-8bygEt1}yu}o@ zta8Kw_Rq$5m3P?79n|YoE=N{(^Q6{GQswaVbHc{A@jr#~+#ulU#wo^$QNda=cF$H3 zfXOy5#-U#}DGs!TNrQCFmCPH26k*mq*sz82ey7X)Gl!l&Q(-P!Psb$o%DR+i#J_BA zC%Abqb`R9xk?#>#JBJdypLAY(ZgGE8Ap8Fy!8x={dEwk}foo&F>U^_xzkS`_K0d#1 zX@fD>4kvQGULSp&64`IQzjv;0m&@hx&h3FY?dpFxVew zEOHI#^7+>Cwl{DR4>bsC z6tyAaBGpeSN+*0e{wio_?T*T^X1hK^YP$UaG2G13jmTW& zrG|~z6lZuwA??|Q%Pzq7Vr)>+TQ793f}S*;U^s!O3v+^3Yn<+UZzV368TLwq@YIK^ z^6W;^EZvA7;BiB6Gi&QCH#VvJHao@!(2UsgJkM)vgfe7?WKq=hxjDPZt3V_x1DssQ zUY4uK2^*2!9mjFeoKTJ1MQ<=~x2D$0(HsCE zWNrX&K2r7k=h{|Em3l?TWsaIDRoEgRF^7yj&!k{KWHh|5QNK30lLjq)=D1U^)q?w{ z8JJC-we#$F)iT^nNS-8@zUWFz1KalKAp)Yx<3~GpptPDYg>87iu zzo+TX2TJMqWM^u&;+Z8jP>}F))Gc6UKXPBVy_0L!_5{~KdRQmfng}DGV>H^8YVKV+ZJ=*amLz?A)Z7wPP0sVA21Qrpy?w9JybBmJTjXtm(<-{I*FzE3=79 zw~OjdGaVnY%X3thwkPkN1mbg^Xzw`0$Z)y|vFqIO-K<~qJTgygE&!5)rqy(iA$A7K zrUc+MfOk6=*X4R&r}O1GY&8ILyWXZ{SvL15J3n?IkyF4bvdXSA0Ec%WAQ%Hd^X++_ zHyz6L@f2ZHNz_4p`QH@e2iVbDG7QP?bDbaO04!o>l!4?Kum=zhXD*^!eh(m)ti6e% z8z}JJ0*=lA@A!L9TzQu-!96;h;l>Oh1R)({bW_r?mlb~m3?XXNfg&Tf%AZzmwfVgu@VHk#i;QjBFzg((JU|oGN^!O^Y>~pw&{QW_LE~vSU8uW*an%)LrBRi8?q}*ooqu!DEd3<~ zELA7X;`fPAt%2zwxzZp-hI-d(E*ekU&sYyp1k-wnO&^eYQtz_miwBC7YQ6ATlXaGH z+Z_Tcr1%c;_1T-M@}#9#(F9qvoI3*(6*F{s zV|3LIq8X!`QjD3gkFNG$HvFiV+!{y#7(^K8LYvDRM zU+2?STt<{O+Hgif-t8l03Y=INl3B#NdsD+~wEH&(V>*0IJL%b>4A8QFPxLt*X;I~> zk+1JV3tRj$_~%nYxa&7sCP{~_V2A%+0?>9ZD+mNJ5Jfls|2NBB94ML|L{L|QI5TZO z@~EVe7f*tf^2FQwcjl-KE>^Qv;aLg&B+PG+7I$U|?eP1vX(XW{p0f!m1mA6O#m$ye z=08Z!U9ZOb^#42- zyqWDtA?af?Yzc<0Q-VD+MU(K?SXcQwic0yf<~pI8msYLN6sIzI&3(nQl~q$f9W+;r zF@>AA*gLyV46gU%m4a*Y0)u4x)S*H`iaF^yJwvAnEt%RIDc}@t3c19aywDVZ{es%D zMYCIz#sfaxUXs@BmK=9WL^`4EUHc6?be2#-aNX?N?MMItArGy6^S;Qy*+|>>ty626 zQK0+$w!YdN2*uG`mv247Tk;6Q##vwfs&jBN(ibwkB^51NMaFKykd-xOUdgYMbT%CI z2@XB)U9PeHhyn`a$@k-=xXtsuS4R+tN@}an1LukmdManlk>(`o<ola+47Fko=LnZ`Oc_`^RZtC}8RmT)$BTz3 zIhx;$&3vdTBN)t0fu+na_>7J67s#anl;^02xJbXV_4W=7ai#dwBW)zC;#0qvJ2l5z zdPTjsJCr6rY!nz18F;TVH#`s2Wz)X_;?J$mkSPsj`WE5cfUl|w2_i7E4IH4QrNt^0!fdE<)9-&Q-@l~NQ2H*#nk#w8lx_WLt z3+}$uUB(mgx#y5Qq1^-LotdW7eE-B?kAK=D77}E@+)qyl`HvyD4psE-Sxmvjp9zVJD3ro&2VD z=(_;KozV)yFbqXs{Qqy(BOEw{Y$^^m5MjEm>(ZMhxoIAy3g4jsX9e+gu7jb%*|dGl z<^pwB5eVU?>;WGDLCSjr>n-TmYi)mS1y?qxaROK1x?rWk`@0jdK^l?z=bYSHvn_WbsFd;gtwp%K>&-QK6tme_Y*plSyLDwO zC^|8ezq+wy!U+J5sX)(IHs)!2w1LuMys6iRGVGRiZJ%qg!cbzIN3j~0<9@i$Xb%Nb zwx=s}p3kZfSZ$`Y&~N^WY`goAiQmY)F&{VD=Nc?i02|BGdV|Ce`8Isg@>PP;yL{BE zeVie3|F=LbX{D}8W5}&+ zapj>~S~8xgKFZ}MMd-ZN<*&@&wI^v)IR3GsH@xw^@_7ot+r6bY3esA07EATk$`Ru2u^8N{uc7T4PquserLTcxD+^cIhO9 z@Au8FDwocr*p)grUKf1+y?XPT$rkerI>i;7JVOZLhuX42S9A z(V{o(zVN0QRhzyFi!0O0yk~@0tvoZp1g*z)-2Q|+?*QgN8Naj43{x78b?aVOq+e9vgzS*C9DWeXX<*#;rP?g>V{TbH>R$ zDNVA)$$Fu_d`rMY-(rl(yXoKN%P0Cny(QxV1*kl`zlN&6;SrW8&^hAM5UFr=F;nx} zO90x=HU(iAh=Sh#czP54Z)Jp$VQEyv3L>_eHXqH~eR;ci1=Mf%Z7D%LS|~GV5-TrV zX(wBmdWfGIq*Q8M{&&=Zp8{1?g)56?@2wY7pzpv{k=PdiwU?=XX3JRhPveui25CM? zCN#6~H-Uj5VE$6Q;3^|6pNIWjh>DY}-jtKv?6Yo`+@uEGlE@Tdw$r3WW;>{kbrP5x z!3xAPk+{F*9G(>AV8~QRrS!UB?RfH<4KE?C51`URyOs{f~Q~OxhMug2DuBxmU$5oYS+bal>yp4lPQ(20PcTPSiuB6X=DYp0wLJ2pe;_C*b{%oe=nct z!9s6@Yo>5Ylsm|arpzhtBV&8E4O64T_Os8)?(}^dJMK@#&&m=QZzlyvZN4lg5r`D3 z-}PPM^K5{UbYYu$vQ1AMI{zF4fr?WS4AWu|}~< zWFTk9V;kU1TBlv-3x<5stNAu&o382ZrYjt}>~1BkOf#1O9Z`xg6pL-=ep`ko#tq4} zXT(4x&Igd_CZBj-GDx*c%6)l8-eXEDB%oX`FYiN6cuFZ!T;Bu^9Z#pA#kBIAlyEH0 z)2CcnFS>Z^j1l7+Hk@3mzAz`l+#gwUTE&~n^*+I2#UiUo~?noXHNodw6L)r8HtwHR>m^s&-z<0Lg(xg(HB^Q40ef-N0 z5Zal*bl}ndzgtgYjXk!90L0x33c^4P1kn4RR!`8%6rK#B){066L0T!@>~1EReD>)P zF6(khjBv)~1iKrAD7>zVbH6SAcd5H)#x)hHMcaumd-1DYkT!)HJ)SH}&^TGFliDN$ zGzv;%wo^LF8ta&&7F*o}S*s!E8+K=mY+kV=iA2q(A9urI+oVTujS1XR}h@} z4ggTrGn03=N}KohfN)ah?YU5F%3##C0b?{LFRxEgFs=YNW5XQVc=4)YfGBIwttRu# z^Nqao4BjaZGQaa21=@L+{6FBdfz183U5mUVzUXMexas{gSqYS~SX#i9VTy87dzyE( z#_b2jidemM+k1kM(E#%e7<3!7W>U;apBITXMHLF8bfbTa25OMJUak4o2Ti{+`hcnu zhZq%(3;RVl3h0utb?d_${IrIUAu#hQrU&@%gL`}K=&s0+qtfx`Gax9Lu=RGn4*`ff zmlcL#AO`;bUza%y48kU*1bQg+ktU8!b}iY`{v8pP-!||_>2a%v=lR_)qSGp zs9VY=z6ST3(eo1pTl&Ruk0NufMgXqCTs7dMc3iI!aJ{hF1VzUZHbzsUlm=sah5QOL0(+~Uy z)aayyenLM;dmR^DqGUp($4|!ds}cT1jP1Rd*ouA>P>Z@vY)%NI$J9u=zHI_8V!bT| zRBUdrE_F!Xfav>7@gK(bjYMd>xQ7~9n1oxM;~Q~$pNSiqDtq&`?)+4iuB@Tu=ZxoW z?%RA)+r752RC?>kegvTHj8YH=Vkqc`r|W%tjh;zH7#TuaT2Vm+DKTz#lTGrHJipz5 zzfOqi0X4)XG+hvax09m0jzARkuv#d6mh9aN9b6G~OC);x>#Q|4K8oG&+w_t=R2)o; zcm)^CTDLP<$wxhC4!Mb8@;BVp0c)T@3317rjgnE|dLxEFcn%sULqokbW$wlmh#^Qq zqIDYVCn1v~>SXz(8}vPKHvQANym8rhD*X&p1n=)kDbISxVj&9=yL!Dd z#Cv4ekIIpzq5Rh{h8ZQ;lYw$Qn}&0jzn1{a-BD`8Fc5^{-Y-}8q00a8!BiO2&=&e& zMB>DjE!nfX+L`?qYlPz4ybG~mGEp0@TA41ErjTAOLhE`+rzd%yd%@^Vx#0;2&myA0 zcNJ#p7yh151)w;&ZDd`mE~U}fq88xQbl`TfM=yjwS>y?O#6wIcF%l0fux>*Wc(^!u_! z@iX)O0v15n91Vmz)^%MUuh;8~$aZa?lRE1-ZFz-g4b~@{Q{9)wDC&ec*!M}e#Z3fC z)MdQ%YZ39=l!`J=^|$@~KhLliyJ&^X+O9bge#t#ulW@BEgQvLTe^*0p6KdWq^98(l z|7XP<2FZrwR}n@Zc+ZHZ@SOC&8?#-iRZV#WGmWGj{^SW`}Y0ubU&XA zkM->T0u0w+xifNQ^M5B%@*QL2Qvl-bWw&7%2BPTy|8;Q}2N(!S+yV)@^TL*7%i{1c zB>&waq(yPtNqFVP*@W(dz*6$LqX>Y0Jhbg|h9L}}7H9P&8%s9TI;-8BwI&tkT%AZn}*3s56~wgzhVqG2O50X(^xzU$^_ z0SC#>)F;-HJ2=PR!?rxfGM!)9h$4_EH;eH=GF_a@y{H& z*4erO$F7z1>+C2W7-+^AZEpWS_s1%A4!fs)X{<`VMc!GLEV9v7j^RC6rE%j>PXP4F zows#(oyYAsv2(BWDIKeG)>=|H*6Z+Op`K+HjW1VG{Z%0wgtK+uenPQZYgGF#@!^yh zA(>l2@h9NB$g%jZvVQ(^5u9lB zY{cunt0a5|5JFYIQLfO&1}R62b93=5l9NS=ExI*W7dd|O;oE7Zj8cH&da8?1U}rpR zJ4Tq(qMOY_Gk0z%NK$76?@c~hvur-r&P9w$OmRDrcs_SB`6V;4%}^E>>d8{vO$S*) z#oUYL)pdxB_h5I?%bMMP!X^PqOb(c$DWqf)B78kxAESbinc|HRnxV^`*;t{f3|(=$ z;(Q1YJ)?6j?2Zgy_vUg^`v+JD~i-g{L9|%_h zy9H4DR_^Q+UFGI9N(bwy;#L~G3d;rU$FlIzcOlhwi2rLG~?p-t{~yYbyl zAaz&FaAn4QZKIRkF(p0(pG0Bv`a+At6UVfdx@KUmI^LVAPpn|@_5 zPHCVG1VY-_>-Bm^BaNgt6Yxq8u2uNhw0EtbTxMKJ}ZKTWW&b4Hp339A!1|crzw+igC0>y197w`MqL)=eYl0zg7{v zqDTEf{f&XUHB}d!8MplgiRzj1jDHG1+nMAr2*g0}l8?=^`CU{tJB*;dQbIPVBp zUzk!(@!5i{T8*tH-c4^U$ufR8A1Xr@v``NHS2$T6L&d9gswdLDV?ES*xHY7jGSU9} z+^Y08%C}#KmB{HkiiRjo`ixP+JS$uoA7i30FW=8Ow-RK&uj{(+gR&F0=07M!JuZ|e z=TVY)Fa*?aE%zk39gmSV>5KWS5_Ti>@lvH?b1ic{9-nCrt_dq)Fc#V;KM^I(Ji$T( ztSgbV&(ol%!pij^nqr{Euh88PqwN`NC7b5^DjBvgzLC!pDUyHmAENC|A-bMsf`9js zpCT^bIP{WB7C&=wpW-G&UqlABefmPPZ?McXJxcG;DlW}ut}L&yG1red+M;z{`xSt; zJ4;~@2!a5b1H}vYC7!`6d#_N!lR_qBA@L^|8Mhg`yQ;UpBf_@IMAKc5K|o!_q*De| zMDSA3Z5=ey4%W5?Se;$!h;>5%66}3W%JBL@u;?LJe!Ug|oZ}Xg&J7Xh&YdljfkH9% znr6^Rq$Aq8k)U7qlIy7q(G+m3e~Jo{QEClE35_choM&Y1O9K&blk1?DI%NggLangm z)O~HkqmM%k86WzMkTRCij8LPbos-ay(&-N9s5%|Z8zoa-t~oNaM%8|-MQ9cR%RNLH z?fZV)w(TqoU_E9_G-gnE0vVQNImRSPGt_1xLG>%l|LIq#sV<9`0?U4o+dR()id0Ta z=K+*!<{^qUbD#Uom?%@d0i_yD_vvga#3pb*L6K2dV^>~!CL2N*7y*E z5`DY!LYpS+LJ6aqp05r~O}&&$dYcAIo93mZFFDp=bf203;}C)VZMl*Ue*{6nnRw4n&75H~U37 zV8zx3PoYifs9m2_&AQsASIU!NbfqtXKY$~d)qOJ*Xwl|n~YjxYAM#e)3yCh z^aJ(*7bS0`tmfDl;P7D3t}9R3{5q5$^x60s#>TDuqS}~^8)4@CeqZxQq4as4=cffz zYsV($n2?j)v5qL1)UBic%MdL?ddvG!vU_%Q(->Rpb?ftj*^{*>pm}IGOx6&U-zt_o z<>kqHYZGsc+Pf~JZ@wjTd_x`*VM9Xp8ChfsYuy~lhck-V%IV!Yu=EJ|Y_Hb;GV;sF zU#E2Qtcy4KRp&ijU{a9%z8{q{!y-tH*1VIT&=@a=qbpR4^19}J62`;rC%Atd&C zyxG%Py3h;2O8Xg;qKYB9ERhT6Go10&?=e zG$)O8N>_IsojU`7%53uwk)S!vshHok?P3_sCGQV{LbGm_9zyWW zwew(1;)pwL$6rL;ddS!b$cKaozlEYXGm3}rSBT`QIi;P7-`b+z9P7Ez+npi#6s)N@Xn!;Ii{ zU5^p$m62>5jIe_Cn%wq3jd>;CNTlh$Z`0&A{of*xjrDEkdgy@jw&fVbl_Xhhw-@V& z)BM-+VUoExftD6a)d360`|=;GZfek4h+klFZ!XBom_Yqa-Hg zJrwZ5?(FXD?B8pIT?l`dYG~xfKru9}`qJc?{>+^t%p#kJebrk;p196H?Ajl+FYVHW zR}M~H5?Q2EnH~a$Gw5B24#CGDiN+vl4hO-c9n-hIpLT}M1$q*7N)tK`0*W3dk-Nyr z6b+GS_X08kdB}2p3|AW&s8rpx8D9p(QfhInSu=89aS}NPZ5FPh)jV2co5myxyZwCz zYV6)WMj5K_u{r%e?^~gUD0cSUwryILWgI6xf-$(cmN>?2aqLN%#yQRNJe}t`R9uoG zJ&t2q*LC#e1ytm3ro$&ynd2w=3NV1?pO5EgvX4_tB$+mb+)rvDh%fGmAmW@8MsbWD z;uGZ>fGG|6`5mxJbM9HIM5qxIPZYWD`-oNzd5#mL@S^4^$|LJX#}s)6-QT^^Q2>&S z=I}fpoe5C$15&f@vIz_#Msq9PSi{^C<~#;0&xzm9QNxVpr>5?LN4!)70hm^d0vO?%FcA1pU{Af{%gJ?>y9w= z5`eZlSZx@HfiQgOd*%I4d7JjqLir6}85S3MXaYHeII+FE)<`p2>23MfS7rX}Ch*e> zS}JdQ$9bDT^p}bHZ41F&`tB*xZvw(yhS^eMw7s)T8#--0$8E{7+653mt;t^E0gEDN zDGS&u65lPdQ*&jkcd@uukqfP9HB}U(N*J7gHAWpHib5NslUC>4eLmYD)c9>rL(v`@ zS6MlRIHTEhHxJtV^f_=qZP*&ZK(0e&?l##7UA*(JOx3amYOrp1>rFUd+&L9(j1Sa0 zPtj8M)|dr)egAwuFA$0Ld^{f4e-uIaeGg_yDV;yy?0?b>8wdJdz5434u#?S?{jY~ir*ji_(*#IoysB?XQ%vs?yHh!JIx!Fj|I*F<%ubh7LYv;~ z_XUdG%JtvCaW)v20Jhh1R&6;00GYna)U1=erQBY<2fg*9kUD$9u446;8SvaMHM}qM zJ+K!Meha|bz2sI50znj=WSDHz`(HwIBb}!ba*{Xj%(4&$4BcHte?C@$oP{Nyp5Qwh z%OX<mSx1=b$WmNC>Ll_(XK`B3;R;_fR<#1m)g)Q8u;7apbzL7cDHu zWKJ>lnR7|wD}7pbhY988T)!#C=91D%VKx8OsOQ#3XiMW$D7Q5c@&MWWAf&I)mqJT< zrsy)dQf{q{8j4~WLx<}iQeRL}-wkETT2uSJskBu6NB}Meq_uHI&m_={rp;l>$lVMr z&Vra?_n~O0>zp2QB4slSzdGNzTacm3I8%9dgKz6Bue-clQe zp&$&ugk*i*|7OYrzVahTXal8wODtPTbnJ7{%;=_3_i6j@!(@_dYJ^sZ>?dO_0l#9z zuh!fe6>-p2erYyKiABU(%0~P1AUa>rPYM0aP9YnWfXZWRWY$fJyB+~B;u=n|{IZrW z1tK+e5?FS*hXO2#z8P%i%e6udMFHOS3MB=&o=CgVk{UzCcK1Xs%2^*iwF ztdj^fb{`wi7Iafv6htTscWrtZ({)`>N9aY0|2Rjtc5@v2-5V1c$oidx8W0K|;l{oU zaM#ZM2V9v$+V{&QcMc(#5H}~kIYiZ1Mk=CS-)sN4Kfc!mRSkA;rCZ<}j%Z_;Ghe?P z;qJXL*ppD;#jZIYnHdmV5qj*X>Mc;4-S5tStR4Bga`U=Q-)ulT8G8X?)x$k28G@Ui zf>;WwgJQ0L#V4B${}z8ykW1+>eHKqepLg%xibs@2R2}2Lsve%nOEsq1#BA#n&3{!9 zJU_D;*}Lz)1YqtAQV@uNAn3tA?LYG5JZb%a)Iv!S_OODAf|tl9F*@nYOsD7G3yJ># zf+Z@{czSuZVbM?1bl$$%iNIw?2Wpih<*O)2}&`_=Q{%otfRzuu^5P$%wWsGs#w(S5oK$mp{SOhmE z)bQkJ$NM8BsYk}!g9rV&PI!Eb0|>z^B^)~EJpM0?gT3-Bzn8=xJV1aCGL2y*<|$2n zf9x;DC;-kF>x(g&v!0#l2GS<2H<-S=B-==#S)w#mysPtv`qbjm| zgY4s)dRXzltrJtJ$twVOcGr~8WKtU~dkVnZ8Kf`_!$9ye%^z~e|NqpU%A`!03PN&e z=_wF`u^n40ORM$AiSQqQ&`_kH(XxRSsa_FXJz{w^nB}I z_5P;@=aejJXs7gM7eY6Ey~6^tb%MRSQ7XA1PT7d+ewK2K(W~bq;9&5L-3xd=tKi?u zhkF7pK=x!%V+Cj_;;qqFYD|Z~6QiMM7dQqJV`|Nmn@LdcX&#g|RLv3i4fQr8Z~r){ zL2TK!?R}b5^xd%lO6$7rIXU`Dm{iB-aevk1@y<2D_pnO)zaR?11_jswYWm1&k6a{R zN_&JZ`IaY!igFCbUC{yO0>DyU4REDR1?zbapj#qCU&v7|w`I?BN<1=8==aWiMK{gT=Ymrf~7>J=LRXIZ0(gT!L_PPIo=pOP0p7e-MfwPl=2G-$EuCa5J^ zq@lu82K+{ObPu+dp?jz?ty;JRo&V**s`sWTLL~;a`$j!Of_X_;maen_fwD#L(XKFC zeO_M;i|O(<%+NU$d~dCfvg(3j|Oy}x;Rt^)9OFR2X#F%X8c$kw_4`J8(MQwd-A z8O8<&VuSI@^XQgZuPW)ihtCA>Swr}$nxO@tytVB28ooXfUPcb&mN&=o8Q-Mb&;ALW$#^aT`BTS51*MtFNo z5itm@h4Lmlcvlor^xW~+^VH#S*r*}2%MWFMa6P7ic9^%uLD486!hF*+Y9?xeLwqh; zf~JMk<$&y+W*qSPE+3b->*w{mOU?|Gec7{UUnWI5O2Sf`Gm1;4F7g~tZ}(Vwb>J6K z?hNzfMIX=^4-JX;J~N`ygG*xq`bd3F_E0T2BKyB}6D3bScI~Bg$-s=S#^TVLqnFpmaBwc|dB?c5KF+~8&hsoqrZj@%ti8(FU!t^Er9~ULHFM^S zcr>Y{>Bl+ZLp4K z+ZDcT6P3PNxN})NOxND~DRh`Kpw6fWk8olPU~lRI#RA+u+rcbm5<7|M2tjD_UPT0Y zYppLG=+&Ab*oV)tK2=N*o}Q~Vd032A6aaoh4lbS+GI(mL+C36zhus>SMFwO`k#7MyGBesVoq8jJBwclIoP-DgWB(DWjY z3lzY21=2r-gL^<1ccZse8qUB+R3=)IN=v-%N%jV9^4nig{7+wXwV(0fqRTXxuqh)x zH?&;<=I$k@ffx#+Xg1pm%QhLIi*%xr6(9^iWY}r7ow)7ytE%^S8ikYp_A%K-A}-qT z3F05t%&?LJlxNSL;4R#BEBtksZ1K0}N`1 z8qZA~ZPU$+EG}5%ETDh~<>2XBhZMCH*#bs(+s^3v;E-$nUPQo>6-e+~9qebs{cQah zIH^ym5~?*)zUUmHx|0s1z93TR-X+OXHxUIk9_g~QJR`14(?x?oB`B52Nw~e;9_l>Z zL$IK^=?|F0(Hf-DNwEd=p8}2O?0&!BuIqX@X{AFcw=|E|p0;Ynv+I%T0bA5e8^<9j zBHxsE>z$z&**5bK4`l0TNPebk zc>-@l?nK*{ri5UA3S2M@XdDbV=WLy;pJuOKrHcIqz(n?9YvAh?JZp5zafS9py;>Bo zy|vN1{+WMS6I~7HuMF^(sLu6SxkT^Uy8x`+ZEnIa5QO17l;h;+T&{gvJ!oVh@uNYC zkRSwmZSUH%AM-MVK|Xh}fd6+u?W$Wu;Eja=K`a#5Cm7;gW%OMrs-nE}DW32s$26fX z-HdmzEd#SKj|)r)Cfl7YEFMhNeJRQ0u@ob)^c3qFYRbo{#>u8v&q{vUj?h#>{YG#~ z84wEI{BUAyVWfEb%_b)=yS;unF_%TFgrDPz+2=2D+gKtZ9; z=kqr@H3Qf>RjyFcI49sIuyp(Gf2$zyx81iIs;ZHNi{nw_yFnH_p-<&xcU%G{lc*~!u;-{ZkW!~K%D5myEg*j2S0jD?@ zDZ8#)OW$>^d?3ZayG~iPt~@VwdgU9-zqQXjr}q?JsLb!wFbf5DCS^xOf-*K{#(g`{}8CvhaMP zOPgC=BV)OTH}}3?8SkTneB1<~Bq^nGe=D?>I_b@v}WQKMwJameG=#$jmQ zUjh(!M=1&eK@dQ7S-nX<*8ATfN60Po1TInoPl`d8{ZJJA2|_00q^rBSyZXB+Bf5Q` z20({X(E=(@&dwp7XVJ|Qs++24;OI|JtLWkjFCYC)K){&GFU>;I4r7ChJW~v2&r0;- zp?{4?BJ~xon-DZ@QnXpGzZK$}?gZ@d+5;U_BpAqf=#6A@M^mE)##t~_AJOQ+-UFp*>Kbtlx10lSan7rB?4@LghYX& zo9-<{JF7Cy`XZ^OuMq1J@K6YoNK^3<6&X3TbzMj6MSuyAWz7M`fDcB5W0QUHn}Aw! zzJQU!OYRd8>6+`aRDSa7<6+wr%5jigQAb4g-1py$czfeonjn*M3Bj=gWBj;o*3= z>xFjZUiOo)y8Q|O=U$KYzZsy82<37KD&*7R2pvT@bJ&TN7VEsKGzBWL9hz6=_h$R^ zY7k^Y@(iZ;U@yGKbJW_y0XQlCFTKhXpE%0|(|gWj%g4P-Y7NESfZH`A|1FGcWu5%b z97ztsO#tHVEv11V3c~OP^hqJ^e=S*<{E-jJCP55>fsnandZur6>h!sM3$gb4^8dy% zYeA?H(ehK>xOD$fzP_`vPN3A#XFR@*#6W$z5+BA?BcK%h9>*?u*IsbGs)otz=CC0$%x-Q3U}^u}%ALWiTIaa$AYqTGaaKIS>5Bx$ODY z=!h}UhLz&Cx7js*Qk7uK9QZNSO|Wa?6i64VJGBM|^4ZsX0-9VHVuNkdN=QB{g%WU$ z?NKE$9_f6?MX+eU$-g>^WtB`<^c#8q0-YFR?~vdkPhOyQy0@*%7%mrjUL;HdHW+3RD5m_4fW1eEafoxjkRs$}i}4Y}~pg zMy|a!7((}LZIN%|W-3|tnzIi(j+xL#=)>BwvSZlVn`UIy^#r+f<1v=>*Js(yT5vy# zt^C*X<<`xreF5YG*D~{UKQPWWN9k&P5-QHIgG4+VC_-OAl=#IKnAt&scdgjcQdC!-Tgu$U;mMQTY=IY(Rd2dLf#5 z1QR+wM)MNB6Qc9hup;yjRB;2ggs238QvQ)!2C8``k1Yo~SF-;*4ms{v^*SEfT zXd62Pi{PMml!A7+?%k>W{o__tTi+D#p1Jq%jFoOY-X8aSQ*2YbH~GWU7l*6XMf;DH z>G;k|LB~+l9GN%IFx)$Bj3&txAMBYYSq0cuWTg{q%73#-TXU>r2ysCn6A2T}i|_rE z0Y4?jwREBQJ$$q8Rl<$mDv(kX`WBt#T^G_ni9y_Jzcz-Uz&YS_6n|@*r_TQuy%oEs zrKfbwIkL91hVnbi_H6Ojs6#6RJ_TUz+*S~Vp&)3or8(+=g`A%|dRxZgg z<#X&pcO$Bz&|-~-P&j-ovp2@CcWAi8=dZ-nZcVDQ=>J+ZSCBKTIX7V8M&kwk@C5Vq|UsJ^+vB!Vn=xM}df*yJ6nyIhIU7j{|`4`WiBLcjN+@ zZ^JRR5O5znHCqrE2j~D&+)sdlK?cxdJsHP;7>7Z0oX7Gg`5jP`JV5bf))!#&;O9LN z-PLNYA>e#3L+Ej?al9w{$FQl~qK3z;SQTUy@0DWB-c?Bm)W%$Wm4NcgQ}kNq>k5w5 zmGj#%0?{^wSuisXY4>eCn#vAMI>Z)Od;?UCY!q-x#L+%SpY5t9^os8?$JODqce(lc z9q_d7LVzes)SXz+9#Z#e1&)6??@a}H_B;h(?(T9BhG7^09|6v>`yUWo=|fgjG(dZR z7sND`{-#Z8JFkr}jZe7cA3hW5)m);PCP_mroU_>e?3iyuASN%v>kbCFAOEI3LY~uZ zP+A4P0Vft|p2djqHcZl) zoGSn(EkeNi?vU^=2Ym;m-CgOYG_ouAg2|6=+qClnXM1*KLRK56hXBN#?G1uJ5Cvla z+81rmB_+_649S?u1;s>-{vn)%+dIO(g1X z<*x?e|t4Rk8`eCz}M!g-$e$W3w^1rNXpdAJ|JFn}^+vJ8xyhQnIf zU)F*`U>*x-vmO)Y@slpgvdhI>tOdDc8rV11&Uwpk*=JH}9$6TZJ_WE1fRpx@=|Gl( zA^TzKkFA*i;U%(bT~6vT&hG-yc4sRML_riq#o_-y*Wi=x z$b#dgK|y^8-O$OMIyG0F`jWzzt7svLeo~|6 zv}u}ijF3gdQc`NMB^ekTd{UXcyJy0lhRV9wwC;^#Qf7+LRlAp4F(!Ryo^K!T_37~* z7wgJ`Gv9V#Ki@A45u>}k-X5M`K3%Bx$aTp*rmixf(C@n!`%Fl0Ob(C%&}_|uJ7Ypp zNrQE39hHD+Z(P|~vC&}T^{o3o#UJ%5?7ne3qsC}_9VuE%0$7G#^r_BZZaD2w&w)!#&B69+^MZK9?*Yv zEjnE*C@yGuv$rKjYzz?1T!BijHHep-iuK7K%jf^(?K*hUw@T~v;E&U}u$S6<8AgE9UFQv5GZ8ww6B$F2)+^Hmh7;m2aEH4qdwurWeXNL>ByBPkAPj`mg`*Oak>k!EXBI*`--kFCS)AZJJ zSXqVK9rJ@jvny-icNxdM z?lQlexz;1L=9=g8w>xU!>QH7E(|=>&XG^%|DcdpcIBMPL$ylmTBIY#t^yEuFR2YfK@deJS*6#kr8s*CWjNs? z6l0S>3>w%L4?Ri!@2dVdD~+XuR-pf{kxV7o1tLFhxZahQjaN27yy}qp%dXa@90Bkh zFjEe~OR<$!ObfEKDxha`+eid{Vxl-ZD<#}6z}Cw;Pkst)28Pm*E-iC@g~?n)*dq8r zbvKbz=a;n()DFWLhAFlg1f8k3+wD=4+Thsx=lx+Aru292faO!RQ~ZG9jHi^DZa`7$ zSxJ?2m~hqUE3{>bbqCAp3!x<2noCP=jWx*}$MH=|2N$^e zfQNLlhx-;i+Wzx?Giwv> z=}QF6cb**J5i%V8zn=ptaduk zRV4UK?>lEQSV!$k0N&0e2SFeTf-AlM)mU&0xqurjNSVrr2|=S9MPwLcc%ObfJ#QHy z4=WG(zXW4Hkx^s|D$iuZ%Ha18(}?ehtRB@KJ>v+yLG-JW>@D!u3G3)A{7dC-?SgIL zBd?)K5uF~=`Bq~cZ=6P=(dYo+9!r>!S!Naj9A&+Ve&dXIVGP;k_p+@DzxKQ%Oi{HR zK9hYIK;Y!a0)grLjwOF+7bilNgF}KTsSt1@M$aRu#Xw^(T6a9?Fu4}%ibCyVJ@mm9 z9ykuiL~X9djy5FJ$nwPz(5~4U!GaFa+7@ig5_f24nx@rZDNVNAmKA=aJ>DHR^pAE3 zRN1DlE+$O>AlGm_+4MZmFQ?o|=)&%6z3RU0yIwZvoO`W&8vE(DaHdEEK_+$0b&=oa zb7*EM{A`W35PgH#t{Yfm+vz@CecWRV0EG4(V-jr?aFFR+=+qj0>v9$4XbI)asu3eg zS_#0i#T_@bsiR!jw>HxNu-U%~NUAaIWp1@Gzfeh9$Yy{0q_g+UkwT}9nb_P-^0gO7}%@lPv=MKqk8+su5|KS0<8+2s@? ze^+qHowD5CV$_b!0xY&4p99Q~u#y@3TYubt{S9Av9}L0<61_xGILMfbdZHAR&I?zy zBqA;*FPhKq9By;=ER|&InVKJ}j4u@nm!oD3{oJ~d$cE(gEx(6FF?X(+OYjPS*2H%^ zW(Xch{o>((;^ z&s1D<7V*ScNYC*IC%TVvVR1Wzux5mwLfGx}dg-;tE1OyI0oNwfDsO@$T-kRYY=k z`JNC01OXudE)x3R6;rVmAV93BJgXE^a*bl$$kHVr>*l!ry}4Nz&nxK>ccxeO`?adf z`hWZ4B6$Xm&rHFQIV7JM{#yXr&L9UtAcmqY+{p>$>i&KywUHcD)Z}&qPO#rUdx>794I_yQwI;%hy2Ia?0o6!GVTYxWHHv^5&go zIW}MNBg5BMiSyn5bH>zgdX6Vd-k+3uQV~#^jK#U*(8CbVobPoFaxX>-W5e^g<~@;x zt(t&X`Ig81u^VC`b>)x2(>VEGWg@rj)N)%c+jHB?{TYLDqkxPJp)g;qDr4NyIZ#$+ z(;v$IcC(`As1a1@wSS~(94)ChAu|z!$^2}6+oLWNt;_oloX0wDz0VrdGx-*d(_$O5 zROKY^RTp=i>fIh~1di@MlTcZQ$bYJRYB!BvLSa^hDl+jFfVXo!K^O?ap#IcaQbI~d z|8-~wI^u-!Fc3ry90*2pxx0Pue)}TM?;70^V)^wof-a8&ro93!WUf!Y%x%QF{Kwpz zjq0YDlv1Sk3L3RRQ^lL^Eqay)&*T)H)N##UU8de4%og7?*P-`<|Pu>!3_0&X>7r*OYoN_#XA?7IP24@5zJz z5+mGPAYzfFV2ppurkOM0%y!yVUBf}ja520cu=T?FxPgn4EZ_hs#goyT8EuA~F(l5| zE)6!46ahJLJUfklr4yi%w%WsXr`Wu$;(e(@Gw3`@z)RG_EAs#SUV#sTy0ul$0djPE zVL4`VpROIJ*z9o6nj4T_x*TAi2#0FmW*=DkIrnUjh(! zZz%}GKoCX2{cqA)iCpkVAtU(VV}2)&2}!zAo$l((8Ctd&ew9A)OmWv;$_Po4{RQKD zXW^~;V3prjR>|pw-XCyjLL}WgO*OGL=SF7sKITLYXhXYS)jL}kg>(+VGFzOIyF|Nn zEvq)qQ0+m(-B{n_`Y}G>Lm&XKXTT~cl+nec8D?6bSil*p$e_8S#G-ct7|W{pxF-`V z0@Q3CK{6_o$A)^JK_?bnpBiIeV_vZ~0N%L!R_z)uX4q3XBL@#kE7C9mtAH?eR{Dec z+}bf<64HrDNI$8MwZmp&f&G`$vT=3y$PFZjNRoQs7H}4^sytYL+FUg+7-x5nfwNr3 z1^wfCJdBn3n@+soP=J0O4lG{A9hknOp{?Hb^uN6Rf z6M(vVNo^Pif-t-ZgybyFNqqnNB){Mbh0sEaBoKqKkVYDVX8KWG-TiWfpJw^R9KEXV z_#2q-IW1rl=+XJJH2)$7co!PIVy6+76b2!fa8bXLB3!bIAhu+7n~0*)MS)Tv(A~c; zcUfc$VX&&iTP-4%+_@$wPmmFU1*%k>Ie9_gAd627E`j=dK93SztTGTS&uyX6^Jd*{ z6t11yv7F<#8>^Du0Q*1$zd&eF3OofuI}{|rokDEQNluTQDfe+>p!@Cm?v0~Z`RkWQ z@c#Bq20~iuxAcaTP70vsGdz${c&=E8N}xrI;bk(Wz7p$VBJcU^L@h+xcrveXAtkNtCAT&HQvmAjAO~R>2BPR4=>6}C{^FrgP$gC%*g%1# z4yCro_QY?7FlCSu_!c7EJm5lO%A3cA^!@9Hf|Ijqjd780lc#|=whQ(u{gm$Z4qGpF zcfSzY#utyt6QQ*qrn?ZuMMeDufZ+ziMRjnaD+_ip- zj7sZhy*-D_`V8Vq{=%SS*LM=Si3*`gH6s$Gq;uewW&oQnRNCug>->$m9@ncQL$Wpw z4^W8P1^|uMr?1dZYfbjv?;3Xf;%)Z2wP&cCyYJ;3Waw}ug+1l1TdR9h&KteNf1ZJA zjt!GS&u8cHE$-k5L;20wcs=Fpb(-#SJ*5v+A#dxmH6WDhaxQo0qfhh~r_Y*%A<6a) zW4Jr7K=|8Z^3HkuhsW*&v<=!%s>B^#ZY$~Kinp4!d7c8$cDE@F1W^!0aW%S*EG7%r zxDNFW94SUYAsU!J38cGcrn}x(z4`)#ADj8%iSh?mO~UC#(fTPRe>vpIJ7UoMwJ@w`JCH3X0=$N_AOfz=J$K8j1H*^020 z@?jM4upGcN+JHI!pTjcGsJvO=(t+PR0yWx!lqod$20VF6Gz#;?T3gky-HY;Na%_Q0 zeNu0)w_|=NGJy_oSXFgvZ|vr9y zmSX7B{Q!tduwN<$Ls9{YeB}yB+c&GPCxWAm-O>-fE9P6;5D#}FJqq7e1M@#ZrRVwx zp+oy-^*4V*G5G2Cvl#YS|Mjmzy-Smm*73ZyB33jGHk>_i?~^b%*){!<84>RSFn0zy z2*N-VC6T+xruSdSwi`T$oI_vDOMV&}H)v#qfzSdn|IhT#%zQK%7#<%4?DZG2-y9>; z6HG72gzSIVQu*q`H{>E47W`6$X=$xbU@JH#1DDCj>}2Cd#3Ds8Dd!fHbNwvUrjBo0 zpH#;R@B*jJe6wwo%pGG=N@-wd*)Yc8e7qLDHGwe0wIg}D0Op_D`;(1p95t*d#?nyQ zRF>=D=`e2r&X9|FgsLU81Rd{#a{xcZB7`dOm^27@WUiIsaj|c;8TJvg)LI*0;ejpJ zW!mmrBMi1$0+cweu!Z{tOl_Wv;k9-tMw|Jpx3z_ROc<6J!2NnZfIgdHN(?^nZUsUM zSqQ?e4O??FTlaYXjFSQ`JvyHeV|=c5fR>?c8gZ#}ms+lHD55G)u8xP zpTNrF0G0rXS=6bp)`A)qy6v<6jtmP0+l1%lLd}^F)LfQAAgqMWlxgHub^nc(AnU!) zaug!8rd?C$vZHH^p@DDDxpql;W6C1r)NIrgm-bDqe|3NTC#9iAF0ap=Q+}atLzXs9 z-vikI=cH(FAGepw+vTTogE=&Q!ac>Oi-Ysm_v^Q@0;QS)Mo8TJ?8%gzJgH)NB;{Cw zI^Q_Q4)8+!Knsx5j0(T=;I}i2=f>Dk2g$(0#ky=x3-jMx@FFTHLZ0bD^m$a>-*19` zg|7NT@<69|hS=ub&wz0LVx(_*)mbm?5rOuWw{7p!XB+@6%MP?5^fT)ye~Rg7na94K z`Rk_u#NAO2f#n2>b8DxU4rfZcp2 zP6yT^1$a;jB2PC2$b6a`qhGGWAR=PPNmIMP)CHx*Xe0_!2tMtmLD%O5k#>rq%a2DG zIoHKF9`=XP(oNK%m>mlev>hWJLzle;Kqr@>41a(B7{c5Wa!k-1<6y2>gfZtlAIHSp zkUw^wl81;ed)Ft*pF7taPfv;>2v8QVrEC&os<&yL2`d^r-YExjgpmO|B7$TrIa4{W zSRX8iP1$8mU03Qo)k=cnKTX46z;fo5EfML?v3~|kw>8Uht7xqa?OGG>Z=|k_5y!O~ zA2jmwNe9h*=#%^-UpO=hf?^;fOeT{` zS5MteUGBc~O0x1!t$Vh!`DugGeSTGNyHnP8RLOchUbi*Qe>^s&n@182-8`GnVnKzU zR$zBCz{a*HeA9z@Sjrs;`Gn8T7dxk0Z~2A<3AKF$+yc#QgdMZ9sl>v28+O4%doj(Q&nm zd$_;tE8#Y{C5Ot& z7skjYU3@3M_87w}KKLAT0b}0|OlM}}Zykvb-Vm66Tld<aW0eioDol=cd@?=1yYF=y{Y@DZSo}_0MAFDR5C?W#>LEKeXonaVY1LtB(7< z`Sr8%?Hlib__ckv=e`kfGo3oHfKx0hlB zsSE%|DQ?{G(n0f%f z?hpP7K-|6LAP9p&0QLa5l0Dx4GTcbb5I-^@NMbaB9j0n&Y5&)BX4eqrWd-9t+Yq+e zLVF}BP|_;{|057^&<4UBC-EIl^TlMFGVqd%=b=*rmS ze?@<-oB`Ep@#i z&3)RtXE@9+PF43dVzoeJ%w{2enFn32Q2tq*+K&kh{{{JuY-C~3z!$lv0q6DD= zxhmbA-PzsQ>j@BELIt%l#IKH4QTZ2T1eJ({d-YVIrx+FU+8A@-))63D5>+X}6v6RM zX)}tjG=jGHZ7bV|mYN#X>j%Jl3|3DD7)7qpOg(57NN0n`z{hbiWR@}0yv{>kpX*+& znRWBtsM9bSqlj*gy-{)7c_+`~RMZlqjQX%iZ6*NAXi~*N`DLBZkey#Ozc9}`-{&nt zv!RsFlP9A-qrG74U+O%FMs=SVQT?T=B>|xCoUs6Rz%cig2s`VAN~PM8_f5osOU#=r+m(5^Yd7UezWegdMR&P0Y;C)b(tI2M-h=mDu*9je>D0FrXVszk~8 z<@w1B_HbxXf$O?>N)+4_fB*jgRp-Hua!yUD>O-`5I1d;Ax!@i|{EcEmHWJ8l3f{>n zwphqfbT|ShkUSfp@QI^GZFQ@d-{gTgR%iBl)2N+pyW>30hkOaZ+P&m73JER3*Fj!X;d#*IcY?lm|1zt%pSK3wuze(F zHuqZ;O22vkPty;;1W2KG(gaU6nTbFk1w}woiOWa1)M0=Hegg_f;Vv0Blp4dde3=fe zx{6KTLu`ocPMt^iyr@h@kn%G%V?FDhbsgLD8r_w80~)y2TOOZ28s#6}YIiAXDAi<= zk_I+f&wSIi%M4M(kkMsSyib~pEP7_ff+6Z%Deq(#NTfBX^BHd>vhRJ^S~6-P=&n^G z>%N-i+so$lmHLFlEN!WFCW_0T;sT{)W-fFb1Gq#+r_j@vuZoNET-fNz?PT>Mt2c@|Dj;$j^tWi*Ed>j*JMG9HwB%|z^ z94G&^huUdmLofm*1H|T>Ap39}$EUQqmYCADMa4i*YLFD>wqq>tt9y}fFN*q>V&3c! z1KoG1ZzE#hL_x)JlC6Qk{i}XDx0py{a}JVo-?S0qxhA;tM7P!_a^GlCO4*sDEB?E+ zZNH22e`Z{Q7tjiE&**Cj>&z=loDr`t0`PVRISRu-5Jg#V$s9WO7%l+Y(U0^{%L=R} z6Dbm4C2?%yZg-Wd@1HKt%WIQvn`|d}at+#+mlUY7^;WB`-DcP5M8F zL$-tNDU&)O@1w6?&o`s5Edm*gn50qkWe`|%FOqR1BG7ZXxA30uB1ehvz{G_x2Qv~~ z-{)3JR+OBG+R=pBSsP@uk|~oJ!k#R|DD~@mhVH=c9zXBBW7RS3&aSgn1FkHb7wHA2 z)w?vIXXG-_u({60fj?^)Vx*hu)>xvmSs9(t-l^xN;?py>ZM*IJew1f;rM7ZpAnT9X z02W=Js7HOvC{eztjDfCPYA5|(n`_(NafVrYK1L<1mBC~nI7=Bm6JEc=-6+M7R^wc7 zb|$VwNFl>GBOogQaOM%5d+=70-Z!WOJYa=Q=FU6#KTRQxzdFDcLYfFdFg!RgqkXp0 zHMWJ*E6o&oauSMy zAPl=H2CN>IpnK7=@}nQA7&Q(Q5<&>%-t)SryQ{0~d}|0V4|?$E>mG+f-ss*h5Y4@q zqF;F@ARSNyuR;=B#Ja-Aa$vkji*`?1X8?*=z-uPhrW@o$)(q5#VF<2VOnny!g2FWt z_#nENN06Nbw#BL-R+RV8h3WmCfoX9$!?Fj5%+=O(_1_ql8N`)q+r=v)FwR%zzq2`ay^wMSUWm-KJdM z(Yb32W7Y%Qyfv@&r8b;Sr)xVJx9%%1Df;9DGIZU~IfRUUzvUd9&*z8Z@pzk~qSGSM zit6h#%}?zO`c%i)_&hznlWH$mEpz_}qAt65F2{cRYhZs6$r7f}s6XMfd$&Cp(rt49>ii^iX>qQsq z+iOrg+Ye!EduyFVpec>$cXR-CXW>GU03mioP$lHmZvknUp0j|NU@_5w;OVo*e@-_5 zyquq=sbf0YEp3|R={&PWYYJ3F;)dVKR;1ykDbsqh1WWYE;&J}|51eEss-0^uncT|jjFJ$`-v+-LK(UUT-|p{^6i=>c4_O|+q*^Ytvc zZ_Bc*Yx-sdwnyuuDcS-_u`Bg$rayFFvLq>L0jb(oZuIsAG3sx7Xiyq3GY);e+}9*MSHU2+(i%R)xhQV8uo&S+>U>Pd}=wdVZYc zpdZ>H+0bt_xqJNR!CFWNJKGr^LF7MnLG6+u0e6Ox^wOtuvo5!k2qNKb3l2edoVDz%r zb8DjKr%ydd)!FRtCganUL=@Y*u`Li7=<(s*@X8uBJ!Xs<@gT_@TgU6#LjR|x(mgbu zRxe@fnwQ2>hnKQk@3nJtlbGEsyg-{NLyYVw>9ROD*ER)4nk?K_6|^*B-( zLXZ13535JSBHyio{zCrSKoa6%eFzNLBX)2bLUMBN7H%B( zHvMO7*`=#~@hcr6K0|1Uz-}3_es2QMc1Jl01VIpnP4psi4-U&cIGp)0UsBnCVpQG; z%P`FDbWe9zReu=~wh5|Hwei+C{4u;~}An;JT)Hp%m=Nb&*w2T8-0l z(Kzadn|jK??)!x~b6)FU)rS}nErb?vxC%52jfWu2sA@F(_WDUUSNkHWz5O1$Ch9a%!*4hndKm&@hld_LctTkD%c@4wbXqp@g_b|0%fhW73E`fT+a^?w5_ zaRAh1Vf8_Av|5kGCu9IrwY?%mZoRZ9Bi?S$xEHG&18FR?A?v~zOS^7)KqUEy^nEYO zwP1~Vjd@r2-5ygzwT=V=Rw{0@E%ww;?dfv<_Mo}yR!2vFL`XjCh!z~Aekd4VpYe77 zich#G@m>3k?2oPRzEjg_Uv%hOFyK)Y=R*MA?qD}z7zhHW`Vn0Df+$~}f1@{g0MSmR zXN|111<{rZ2qY56$$={yZ5tQzuh;2h!+9siHdr)GZ^iRpFI8D9 z>AHEfJ@C+>nE*jMfx@C~@8C`t&{V06jk}0oB47ZSy}6L3YGLSgIwBjiLhty|&M&jQ zR2u>$h$q;hSOKiebZ+1WTvTR~2i(5IptEaxs-cNdliEpuGKvNuOPr2}<7ZF`z}tO2 z|4G)Lc{#tGhq#F~nuk1};{byWCB8surs6^=+C|=cdk=A>Gd@1(ad)OX22q% zv{ZM%QA`o;Z3N+`KV}=F|04~ciL`gZXfN`qHP}$eZbr^H!*eZCH z76!z%VZNYJ%ovEA>^dTF=6m-E>fM@YFKe`GlzWg{NV6LGO`8e^p(_K)VH?d;ShH?x zOSOB%ezSV=r{xkYKTIO1mRmQVHDflYf2L}3&tWNy(U`GOj{9i*?&KBVQ;c>MIRn^l zRfV3#rmh<#_x6STs+W-GFLm=C5WWk*+nty;5ClOK&BMw+noY`l;b)3L!UwhlizJvm zXSUDk>Mv)d5YmPa{`;e@$waik5+uMOCu7Ac72)RHPGp&|VL~e5V)1PcKIH6E6Zm3zF z{VI7VK!6P4Bto=jw;cvhR&5t>%r6Uk5JIEiF~#Up2Nl}+%Uxw)G*+1kj}udd+#GhG z#d_p-8p-G$MC~A3Ynqs!JB&9sEn)(UW|AL(%89xzJ~IpS>d@VB|ox@;mNb z0NU;awP7Fz!Z1zl(BA*1;cxiLu#lF38wdf%UhjKW(n$Jqw2P$wj%a;VCy4&OlVu|c ztbY1G>jHQIn~j31jD5@r8hL=as!ahHA(pIvBuN8EcHg*}{Hw8{06%a_Oo9!;CNgb$f5g8m#Dxb=C^Dk2QVxIO~%*?|`6VckJ2#Ob9;? zXTS|hdXqiZuk}yg)9>yTSWp)V+P$f+)&+`o1-!zp3Tfe7nct=9Jui^IKd= zaGA5_j6L^EY`dY)t`It`0~$5In=C-Ugw57-wy%0+MmV$RoS%mPyxmJ~gFp~PQANtg zSwS*m6D*$vuqj6u=}0An6o615bPGkXnW2lI?3(HSK?0R zxh%xV-%W4Mxf`4lM66>9O5tFOG6)--D&-iDO1ns~p1|sv#2eh(!mgS+k3UeU@2aO8 zhl0%Ug)MSw114|B#m~ia>+{;vvEEaVd5q%qx?kL2iV3{h^~KZnJhKLi6;$P&bynXb zONy^{rI>;zQCYG(?)NxE&@A#eBgpUKj-oPKJ1mgCX3pYP*6Pt)7i?ch6m zb-d5US_(Alz5lEqvOaM;5(+>DSboMM4`2{Ag~3X;V5*H+`%|=4!l)lQM~+P!1P)5$;dvE;HcMN*Lm$kf{+`=R|8|B+=SKfZp00~3m|2^y;vatn z;O$;k8-{@>3~%~k-uwNZr~IZL983~g+SHIm78=QxH20bF@twt;=Xn+9I%xl0$LA1> zmu+&%JLh%47VD07RGf)+ya1jT#Lt(7*X5Ej&cX$6h3R5Kv>BaL2t?`75)T^BQV<*A zwu*-C3j*|dOSW#ccwDRtJLK}*VWMTv7`n}$RTPERJJWn~vHnQ%$qRr#M@{dk!?6~g4PFhRvlmI-A02J;lwqx>tX-9>i+3`<_w5& zpbkh7U>^H!aD$q{}W$HTY%je(kA?nkbUt<>=81=tS?VXQws%OfU9soILYW(CQxu>Sfs#YuS*x{sf(-u&;@%xVH&h(~IzYa88z_9cexg=4O-PUz z>#%iM4AG@e`+8DO8k-(fMylOr5-0p2Jn76*8;dcn6wWxOw^$L-Ta`SGF-Ii_p1mCqL0`j(S@>LnX zXKR)6h&JS4U(Ly{0JPoBO2bePhT(21w4gVY`@f53>kZh2zJVtUp+W`grdqx;w`O5=uRU6y4xriczGFC46;Z~MLLyl*&Y zA(ZEUX@D3tHja(|OU)113+s}a9q@}WRb6Yky}5}!!#RvOgUOldp7=ZaY#-WRZ8PmX z1}5hbScXIG9L|wTQtE1;bc(3w5gpml0iO&m>i^0ChBSMJ=d_yNS~s2v6lUshPP(Bx zM59Kl{RP!IM`ld~@kE2W*Tf+FH%8<*qn7-$H}g@8i~V3jYX1}c&z{la&$j@?-BD`8 zFc5^{UL?JZpM6-LA-747kWzlr&n%_|LrW{jLlQ-iEm^yooz+}&7n)S-y8cN5`&R=$ zU;kYUeiOb$tOW?^Vg}|h=5`hD&jjn46l|9Z60>WNPX#ubj67^DyFBs0Ik1z;-hWTY z5&COqcx}diz>VN7221iZD0QZen4JBlc9D512t#w%TOY&_#cbqX&iD#KOA9~cdg%@s z!RPyPKYz3LErL96EY2yJLu9slnU^RLe^2~=dmLV4{b#I$RU*FBZaX+es=icr+qRcw zSq{~QO6P*=qqGhVM)gW#aIPoV6Kq<&=2V4IxV_#En3GxusipdQzu)(^`aABYqS6c590)JfCrlg~@k0GgS_=>tO0@yPtBpbxbHb2y z1bk9odQKZlXQXH`N^UFey?$#G=uBhv4$H%$L9KSx#o%asX8*SUBy+a;uy)1vXtG_C!JhT2o*r(NY$_6#FTxbL`1Evo zxV~K9+RVk7Vr1MJ=Pb6y4Uk5)2SnuV5icZ|v+M%n^nImVs~-sxHA1@vwYTxADnwAk z+Mp>S-G>6wGZKcy{ZTeHk@8xQ{Xc34v;k<0ut=EIx4=oL zN4yXck*k>QJt>jqQNp}&Y)Az|_sSL5_OF?{v0`MpCS+vl!G3FH7WCvDek7uY*rsMNwSgBC4*OiJv z{#PR2gy7pBW-tc|<5U=xHq)UK>)G$-Lb|cO+X0Q>rD5@3eFe6EgM%a%2Rwq5O#A7- zh~4_DYE$+Y{a3DM*8oAs%pM<)1HH;Lx&GD0;2kF1h+-zvkkgnN^Y;Dye#E!M=xD^X zRsRS)!btc$nRxmB#2=nDLc&4cmn&7J2?d3rQCsWgY7<*qGsIry4|!GB>e6~Jh3z=R z*Rf)(Mkq96?YVu+sGBHxNO6Pyq!$;unQz1K4suKfx-uqC@{ulH(0Xb6o=-w1@j z6PUGgf>1(X{)GuD%|=UWo+Z@3S|dDadrtD{z0n&0GsyL&U9ZNoh}Q+ixu4Zly^1zd z6gmgzJj;Z&O?~%UXbTke?d|r%uc;#a`T7)qw!2Mj7>I!|d@P_M6iWk-+BILn!oz@pJI#d1^2oxK#Ph3v^dt)C^*|^ zT?DoUBErbVCs;Y$n-HsokCnF!(e>SPnQc8l?nSYwt+cWEeg2mvi^0d;)n-SRm(NJx zVfaxZ+{TCyfI*6c6^jP1RwrS>ib=4^?OR~f2FYqlU_S1TD<-6kPnHvRNXKg&Idr$L z+jU=9b^X@4cFbbokxK}Yu5;E?^O2mMVrp`Dk=qu08)Ihv9s(_6pB~_I$hgh zg4@5cxna9XfuNkT#`=7A)%d<&@zTatms4%Yey3D^iwmFgXb-cNfh%Md>`WHlwg&5a zfXw~mO13wEnC4+@xqW~YK+yS8Qj}T`y&@GhSix?8bo|yGcCWZKP^X`zy<>iWsLmPk zJhz6Xjwieze?j;@&55A)9?$?}#YV(1)ESE| z2m-hEqQ|c@*WKazRfN|f+Rqk%To5COKL&&E0HAXMqQkY;p#?$%mH|a|!AFxXYRNb7 zQ5G;VI5M_-X;0+ch5_E~A4Nmg%Ou)rAB5iq_Onx^@S?CI!Tk! za$x7v%n>mricoZAZ^%%^C}(OOMdvL`rAUjhYL%rn_JXaZTQQ{FaFr3uwRu0(8kMGs ztXe=BG;bG2;U-5M8Q3{v<(_il9A&;y&iglWZT^w2HuZj6j>Fo9x_IX9kdb-AL*3%9 zeTtH?FO+)}VXYnZI*<3xj*xUB^(Ym=cJ1vrzl8#_L3Y%}>rDq6*z^g7UCD{Z5eia3 zt6RrS0Osx`H(?+M0w|G^tdi?k^8GhH30}Y*AcgdxG>T*vAYf?(ZjWdBQ(fKtd9QGP z8|-7A=TkOT;H`HcuDpV{(}l!cDltxTw(#9?{y%J8zJvFQY1#b&dAv4c_c&fv-C`1a8 z&5+(GdF2-xS|fUdoDv5vIl>qujhYcwV$_yp*-g`QNv!9$>weuGj)yCxrO#{bllz7= z6N4GXXi$=#)tQ{2vV?pRJ?1~+p+?>q-P}9O)hNm2^kP(vhZ3!tm6)g}1~lJ;AkoVi zO2cqP@IADc0Zr5p=vGd;^ZiO-E;-Y$?<)fubQqaTZ@?NgRigJ92(}r#_DSA*NBE#_ zN}OYb2qv0xW}H26nJ6La!!R<|@=TPfu1#{85EpfcoY5X(CZgR^_G)jz@Xmqj~2fQfiG*kl2C5hIutJ(`}bsE`Pl;NN}^o<7$!pgwN85 zPnz#SdXvk(CfQDIdYT^AN^3z*&IidjAH#LB+pgNi>_;hpF9s-YnWwDl!5Z%Mkhgg+ zFKlJrgjbqSv>}CU{Fl7%uF*o>BKduPEKnIN4Q$(w@bb2+5-u%lqX{kcAp^ierp2j~ zgxsud=n+=BR`qKL2dj_+F+gYS6VZfRny_KN7v94jRzA^oJqbgUiC-i6P#S7ZK}jZh zMq6%iJB}#5fJ79IQ&MT%9oKzbBq-GB`Eju1e!8A^Sn|HVHHo)BC3@MOqW4)&u%LwoH68v5vVH2M{!_%`gRXH&&_&nKewl+6~z+;#(T?{fl;EsvKLW; z83&msYl%|Hp7Acv^IZQ)j#89o#+iyBu{_L43{ns-QVp*o#^rGwi;PC#<5D_D&$Dy>!1k)NxLfO8+<%|t1@lg`r&>j+Y||wG89Fg; zC{&&0yNZk$vGwHqAmoS}Q=mNVJllFQxBTu91Y^%9N>P1V1^~!B>sD0=qJUjG+=wRw|mP$7>0o;Dz?D>_X=FWLGuA0MJkmL(3UnSP8>hR zb4U?B1nBY@{5P?JGd5K@Tz`3~HerPlTEfXQRw$qTsCD^KD3o)bk&Z4=>9WBqo0c2T zibqTaq{8I12}w&$LRj?K@h!6i=AjK-99*GXpzB6j?luEKf3b&)&%k9-((S9=S!pax zR-kfewN>$CAZ}TOASB(lb0pG;`=k^p6xOSx2{9l8R)O)_8wFAm9n74hi_Ysf99W4h zT{p$l1dE&&7BKu_$|&G`v`O`??UAu~XD#}epFi?PsY*BVGmHG{0!+Pxbu*83`Kn{v{r_6|IbWa=^W6jGeh1oxhj1k1XWjfnTKzUyGfuR@q$u-tIOvVIYda z@DE*377@t)cT`^CDW`=Nlv@9&Bu+Au@qV6r?)}*tEuRsMQ=y^1jCt?GHtFfXE(ah^ z$~LaNRj-9gzw<$LjRf501zCfbZs!_Z(WjlCjwrGfFh){oUaKg z27e$DoO-N4;G(pyUQ*d&LI&>^dJ3*Ups?6a# zS0-kX#zF6e&7^RuHBRW4i(7JUL;*TN6xGPfYTU@E``r6=T@R(lvjX_xu`YceJL-{vPuqIDTA)^9Rq%16ajT@o~O08cZJ#fw;O94|1xS9 zgtp;0Bn)VHcOel1bCXF)a0bvuYU7J6`;Ti6W%niW-5CeBh1?<-#OJW2|uB%ona zD~~`-h_e;|C8ikQ{PzA863z|R*a1#2IEpjET=Ka-0K(0aanEg&P@Zd3E@EKR{eocd zU^ceKpR1Mvv8?+&C(AF8qm(s{fG>Ax?Xn;@prk%2KY0e4huopZaeRVzV+dfHE3{C! zQky4rIuQ+ISqcqry%Zi+Cyv4;_p-TE_fQEWiXFkd79r(BFc7ya;_LE4JMU~B@^bW? z`T%T8wv7)}xuD&z1ejEubMUC6E6NkO(ZI98%;S zC4awyMYzXGj(MqgAcPK6@1>{AS`-#bjd}3w18*3QUB)O;?dSe^rq6 zU3=EBAV@5$%A{=&mS?zivjoy@D5@18Sy+VYQSe4G1WxQWM>%`XFnaeGSc}~IrOAUh zu<2-6wvcVKHcRlP4M`!_rJ0k1E1tELpqr~z+MpSU(6VK5j@$7t7WGeJxVH9Pa41Mm zY(ShR&n*}-xYFhK8;AOs5eU{)J5rum|3z5`WR{$lgI04AY#D4?JTZe+$^w-cuw!JH zNM+cSwK-#(T$_}K`lf7?F;_nhRJxuIsXl#0z#%Z;G;G|Zuynt6qQW;m3Y5AWQlJsy z$$eh@4za|X3Ptq2tp_O`$68s|rS&9MYvZz!N!W)*NGFo+z&pg2^^7CRh+%?F9a^AA zD#`cU%s35apnP;BJN*ofFSd>M7R(RuAW4KzI_9us}HD*`KNG$`E5nLG8bLG&y zum6Y-zG~w_ezFtm#Fc9PQSOVyPk|trnmS1_F$C zcDuu%<|}{~u4k0Hz7~Vl9R7f{PANox+LeFW4oI55QwFgv8Op6iYi?~~-yw-5tqA+> z#@93YFVyEbZVzTQuQ^6Y`*gf5f7(8xYje!e*`ZJleA~OdQk*w0O9~=o*XF78fwBoD zIKPEOJH7;?cd2{KAEqOBF1Byrn~s} zFCIcOKWZ)AwAtm(SYRh{g{4s8PiBg}`@kA-J&bPf)QD=@xZ_jwcU`<+hRt<$Q45yU zRipjFZu3>#FHtKkQD& z(>ll&=mRJtov{1tH~YbGIV?SjDd(Jh5rl8KJ>LH+6mY(*4i%%*?GvVgWC4h+wjv4u zlmSnNWr@*qs@l2Dx)lCwbJ`eU%cp70=@DkO@$ufN0LMUu*|z!jM-ihQX5En?a(SGg ze}xa(o3@cc*go$9SNA@5@sV^)OD_Iv>1ft7AZ(pgw$FB{;+C>;Z={D_Emr|(y93mO zp&$suXQ=nTRG{9YM`-`RM~6^EiWa0|W6XPfW_D-i&Hf7rn~<`?L^H3<24x7O(<_~| zh?i>dd!tNZkXN;60tyzw3JMlr03r*hs~4j2+3U3amaMrte#IB+UyO>W(w1sjYGEbN zGP-rA*)G~^3XV<|AsZ`7Gx@yifJY-Ls+)Vq1U@!P1BSiv=>o1fFp#UpmL*u{0laS5 zYH?)k?B&$4{Jp@Vx*S&)*<{aUTY*~O*7dEuUC*2Ez~OAM^s{~f7M&5Q^EG#Xw(PEX zI*#LfU)OT~yr0K+{%Fz0h+d3NZTtbFeUr8v=#!{jQrC3W5x;)TwiC?M0_*m1I{~@R zlr0)>@9BJfCmToqcQw>Nr1{gjsMpjfsfW=>+d)LonM)0^5O5@%5&W#N!TLbza3Sbw zEjRz@*2b|E@!48yf-|*t^fXoS0_D|7NdQ3@)w!*u)*ql10AY}1#kOfYs)=1YrlS+p z*qKqhD1^ulj^?mjBxNTFVUr5eUFXp9hwl2&2S%e%h-$%*tH%Ka&|va!xq#( z^YbkLZFi8gx=Nc#v{T@8GiLP0pAO9qRQu@APy!AjZq( zau^WCvfnah3hGyRqJ8J{`H1Rtj*l$E`ROHVe^6_YXhych`}yVhxF=0=J1576a{wvG zU||+^e9>Rm0h4x&?iUtx@5}Z5ddqiuj+`whNY8R>1sMQi-$swJ@8sTymy^^&Ou|rI za$5h@HNfQL#4vsdUavu1Cg?_~U`(Ys47Pi=IBxS^^{UO`6|F!_p_D`&hmz5jP;5&d zb9IR|TU&SUbC0dv?1IQMli*!(_ zKN3Qa_~13uO!v6$a=H9=5-pZnMo2B#vKoI2f%oPBi>;!>_7HQEQRm1QX^Dfu1`^nE zhLgJdA3Xkyz-%@e!meTrgR=UgB1p_WV??zlaI338 zmoDg-Nv2i0&>Zx?ix73O=-M`JMavpI%Ws&A&c)H{8uVGvraUX?m;;7@ltkU;*d0^J z11(WfY1hx|6O}M`B0c%vl_O(>DEaidsCGAq6S>%^YTGqo5rZdfQVa8OpsY(#voUev zwuAzIfFWIYRK2SxWZVb$d&eMS9VK$;qt4Erk)m6LSDL5}QFHxU1%tnoT`>pE$fkFrn>IvF}spR~v z;Iaj0jfZ4#rm(jr<+vm}V;>Sot+#a`p(IcmzwjZfN(KHUueIG_{`cwI_H<(j;-u1mmoT}rY4c$DzM z6ky{P@)WKMGwk{4f7p3#yrL(~Ige0L=AIvAn)lj#c+2)~3r@H0JXs+(7B4L72#Z~R zAM9!8j-b}=NayyWz0~FB*xzMR!uf<>d8a%+X%OvC?_$>|JRoehN%3bz*mG;&n^$A4 z0k*k{(sC#>rS8rc9^#94wS8wyE`xF#NH1d*M8TNeHfzrW^P@KIecav|UiKEQXZ-zF zdI7vvnEw-HL~&#=$`6IZK67Ng_1V-oEO^-h9G%Wha!42)rdj0j)p2eD&~`_u4a6`I zhH2;xnv3lHpY~?uU-)320!tFVv?TGaZER^IOQYX+2ALKv_bNfcguSEbAuv`F7sKYs zEkZPLe*TcXe6?ji0M$S$ztKmc@w*n`rekdMUK@wivQ@PSnhr9TA>=F2gizvkP%KnX zN1rFiTVsO7Z#Jq+O*#Py!t6JZoZUsfEboG@xFQXcKEnmaZHiThh*W?)R&Du^98X)G96xKojv_uYA( zm!;SIA3u-l|L*l9TK8^N5N4X=IIh}+DOVO+V<}<{vrNCuV}Sp(gWCJrv$gt0^xgg_ z_$K1-gn086z~Zhpftu1ysYllBTs;4tm&??=BFv_^nlqqgJ(U9Uy!xpLX+Kart$pL) z`@LGZgY|8ktz&cTUD7&$C?W2vSe$8RiACn#5s2)$n|6Q%fZKK5niLvBXf9QJtLv%a zN(5X0G%i{}U9Z6N-e2jnw0?kvbN}hwyR8KY^sjg5Zd;P_m2>vO<|=Ov=C>`uP4D6E zT(6I_*g6DKu|aK+)}8h*0Bd)5gD?yO0r-IdVB|7U_vr$33^<9eIt7ZVib_0DC29U_ zpU?JXnx@l(d>x4U>tIjwJbz%}zcBIML=E+^5QI&%-;uV(>gjq}T~m*C*lE|!EZE41 z)pyr1lb2ITAP10d#zuu%BZJs9{oGGA0>2 z+TXzn0h{>`)+6tHj;0xN@N{%d+|R*2lVO-&l$KKj}ZoebZJLYiTQ%UB(lkmA`g2=@&5$be}$4diF0uh;z{dizdy1 zK1cYHg+@?zlIDg%`JgG|dwD@Spueqguq&cWC#Yx_%N|ki=&x%)j>700PvaL)LVMnU zRtWX!yIL67IB)+BpKCv1v*nxBjI>2KN1;soV3blhM&BV^_oMwk1)%M2auNuFC;+=a z7P`STBbS)_9|?kMUFd7_Ot}KpabYBF{gW8Tq5F5tS&V@!Qv4UW|q$yz+&)_ zUtD@DNy+zM_YNKlYmK_fcwv@Mo9iUzMr5s_0$S>TZ&<0 za1;T+7%?JozlOcrTP54FCN)L#ELeYiz{L|Iu;P+q6>@`guQ@;ou?3Y`vYu%_4PcJM z^1SDMtV+*1`EC9q>n1znHVKMj4zwE-&ohoF0JRfKQV1l+U_MsVIT$qC>z+pO>&AHG}i-(*}w%*MR`%pXoMm@*|8y= zPRA~n%l6xjFm%{Bj=O1^eyOCMQKIMyR3MZns%hG^5m+_=q9@Ym@`M--)53cK_b2NK zyRRk#1bMa-lB9>Gq3swSDmFB$!)OY;NN`Ke)yIrZ6=DAESK1AZyDNhZHeGV@A9%@i zyWe)l({WwD&L$=$#Q5im!*G8eDr89@0qwP*BI}5u_pU{V&PNvvQw`cDAcR8G>_GiU zb1u%8^D2N5%_b)zf0ld12`$R#d1}S==ej!hI2gtC!!XRWVD1-CAo5RSn6nvr)fvn^ zL^W}m`JFw=`wzvM=h4@*BVlJug9x-<%2~W~dxLsMr)q9Ji;E8X6+EE3dX!hUAj5>% zTe-sqf}%d6p5$q>C;p=wy8EuP{=8eyMTM$PwDVpJAEzdNM?Kv2Y;8B#i>BmJWI!o8 z5R;NMnPb?B=`E`Fjxf=|-FFzE{bsZ6W^X!wXkAeRNq!TqqJv6KK9Ue51jB2L zJ$AXftE-;|!utjNo|`8%{_FMn1q`_hHgCv<=e;c!YVejUBc}}k1Zid2nwW8R#m-@O z_!rGlRtw9;gamdbzt>kI)h?BFqr?lP6ACG;SKxsxvr0N-tM?`(m{^pMG61XHTw@gA)fei}alr;I#;mrJJtG@d zKbYWhGXoYW7RVH&xqwa2Rd?uE%#H4A-^o2HZGhaF{%%YNiw9iXFM(c@nZ~HT zSXGy5~JK~zPgnZ+D{`|Uu9|G`pZ@CS_Fc3w7X8)V=!kYAcoOTcx zDDr6inLxHhOCpDl;me9J9=ER#bFE?TaU8$8^V*yigAF2sY#CwJlH6j-t|pAbapN8~ zs&TI_xK$e5X%s93xXOLe#ad&=bx_*a>$*@EwAS3VL9(&7>&0$V0eeX(xGW_R8ACQp zO(c%t9o=W+K2Z8{m|j1B_&*(>P{=Z$NQUS+;=Gg?nf5y}Z3l*N9mY^51Bh%xLFAdD zDRD(24L7YAjq(uavuB_z%Uzm6%-y*O51~d$J+$nnQREb)UBrZ~<2wg}M7?o%1{_=78KFFau zhNdi8y(pW1vV*uhPjhIl+Z11NO4gge!g!Qe!ia*jwubh;52_G_1Jc^zzO`l+g)u0^ z4UJo7mPbP+TZg$GnkD~coW2tYas{4o2mg1O!(UxzikfF4G?>?C8$CZu19uaEw>!vf z7>0o;y6L5S|AV#oKwmI0&^9TAc$vhqtym;yL=Hbr+-w_@*L8hXNL-tjzmjFN>!C$y zZ={DHJk3#TgIV1_876gM${I3|5`v@#@8SG) zl$<*BxRm2v4TAu-g$*H+w1UF-#adlZv~J@=rx_KhC(x;2#F*Nibbno6U8jhD)p1Br`H)#-Y#O8Q zx^^hA0IdH}(pO`4o`fY@sAW<{+cbC0lhO#xg%XkK2$M2HDX#c23Q=%?Qs2IQx<7nJ z!w=^yp{e8@!O=5@2UU*-hg4DD=5^)B)FSp-^8kr%t>1Pouoq_yL%EPJ>b;->`|?xr z$_8Sna@p4Fs5pt0Hx%sscMoj$!S8L(>}Qg3J5fsEd0lq}0octGK;YfSZ(Tm_zZ38! z=+Zi5>sp7eCdoLy1fcHTQWOS)C=7!Gx&dcDdCdM-S%WY|Cg}*N^Af=btL_j6WkVBQ!66MtQbZAj_t4AyuW0bjHM+024-fLbw?&;F%(I zh}FHt(6h}8hoh?il%0i1v48djn-m7HdRYsFb&)ters!16N7V0` zX!eUJoYPWMXx{W)&aLqWatR$P*a7D1IW^8QJDE)X+jaY0)$3Jen3G}+>93UR#QP_SSPd!_u1WHJ#9kawDz?@mR zHT;d1ri|IzR#$CojPwKpos|t9Yl9r2Ao{;&gi~sBHW_e_)#u~iHlNwRzj^odp6x>b z+U_U7r33&&q-}2d|CX5_m_`bSvBWf@DBe2guR5RT@?P%w5uv-6GiPLZqiQ>V zF@3KP&r=k+NJC0viYy>dDV7Y$&ePlJ(L3$F=U>g72Ev2#_KDZlOSdUZmI5Sg-f+ za*2drKNLbO37t#3h$t8Gl=7&4*9Pkq-C8o0p<8yI-Vr!t_)LN5ccp67fkmYCB#Iu@ z%S0hH?_*lwAobZy#;!d>pYaWu892uC2*KN$-9vR!HRAL6{Kc>VJR_P%-?r&Nj^r}? zBtuFK9ov6LMi}E{L+ubSYaLyPPav$7VlxM#@43GR?G~XE2X6h#@)wZ=`jX7}XzJxA052Gaf4?FU$vvCw*~ zdnI6L99^UGpCY=>;b62xYy1Huhupg;67JmIL(yQ-XyesxjWZV^2ZTy6GT!EFwYNIG zD15ig6!8-viA;#fS_jR(wuK;&E|PT(4Ihw}jTkIV*v?6_2MS|CAp$0()!vc-2FM(m zfsb&?`Y)h$uDZLv9iqEyz~(D(T41~K2`lm6@{o<3cB57{aDv_)Ff0)AEl9o^XSR2W zWBy^y?iY@HO>2X_>ueM$`Q~^Fz}~&3APfXS6a|-+{Vz%X;cI~^sINhY$y$L|1C?iRW>cj?;sffR+QY+U;x9MVuN2|#JIK3! z!mkH|gw|wFDX5UodQQL*^59aFQ%n$HE>Cee_Dt~lp#+#=i+f6vEP|1A64$ZlUijcHcF6?U}7N$Q$1^r4XAH z`e5#Mh=&~{4FwR#?EZpGH`QIdQDP255N{%*(R2C)p{>GO#itm@W{;8yn+I@~Pjz|n z7^`c{^Lk&2y#Gq@929zH3leSqkeR|h-)wgQxVxhigkc~E!-&2A741#bU-)1Rf}nj6 z^HhY|q)B%+vpbvZU?4o*f$&;K^SCE?WE4;!v_G>zHqY)|^Fe0N=&dX^XVGOK?3Pf6 zM^!~w)2ZhK@@&hDlh}~46Z0YZ2VTGd-NYzJE}`+7^a_asaFbL4B&PV3aq`Y*)}TJy zeW4$vev~>7 z1kmNJg*?Q7k>+%Y#OqUK+r$0wRv%J$ZTqkDh^>S%~RzYUjW51p1`#-FEeZURm^|2A?tTJHLSpQ zYSTUeD0HfV0~|@ep@;t^bMu#4-#{S(8{V0@%)RO(5$k`1FVVWcK5 zt14L$85!>xpC{)XV}R*`>_vu+kM~hw#)RHVVTLr*SbZ)a@i(*~XQ#3g;mK*W|Tl0y+?^T}8PHplW&inRZ5-!+Gh_uhCNo00eR@{sfO@|30Y zX^?7NQ@?BM)*PqfaQ-}RO4+&+=b-zHZ!mdqOgSP&mW|bGQuSaVVc^;(U!iqh=}%EM zJ9ZkOR-YSVmKNnDG(OaV}LlPXGbuO>`{MZb9UHU2DEn$I1@MJ% zv3L=Yzo0bFNRRh8Y&tgRjjJcZdxfyO~{9w0kQ{KM$;5n?wuz zs>^JUzRDC`N0kjoYl8fZ)C%wRB2d?6^#pR`8T(r_POK3FZ z0sybA&iY3F>+pbe`xcE@d*{o*y9IXINJp)xPBg(8_;xF%K9pbN-tjf19|EN|1)wR( zc;(F~$-&Mqa|uA?`%c|Qg|&N!0(URR?s_3fB)_9m1I<&~zuPWt@w zKAdkP^k7v2WHe>|woJqWrm0)ZIr*gf$&>^D)|y}-<95-y&buD%((~pVpe~WBJISnp zS7$PM9yNOPJG4k%v#9ZIl_bDzrbl3K20&_#*H%rv12V5)fv}|xnz@9XPBOd0;&DAz zrt67oK6$jmOtP{=i^?&m60*xyH(vqRySEetq8JFnxSsC)Z%?g(4}Js(8XTYIt;JUR zTue?XRmqSL7@8dk2y1^0*NAo7%Ua;5D ze$O^TNFsoxX~WJaG4eBNB3>tN4pRk~-9x9y`B%`}2C04BKZ+iAU{SeC(Mn6oDcsD6 zV8tN;ZGHD$bCwKqqa+S=P?)YAVDVN|5lM*jC3Vce`l>_H805f}WIc$oPS zcC2Sa71nYeJcj}?iBh5rcyVa$o*iMSQLENVa|3n^rVWk|I06TT8JWDkz@*4O`IR0J zq6&x+G?%g5L(vdayjZCiVp4=}<`Ch_5J1DnqGf#eZaf)67nITo-IN#>GPpk1L|G(- zKsS5Ffmmu3Unjv+@Wxt@H#0VCnzhTG0HH!bc$H$|j1UlcuFu-Zhs*wOHZrGt2VNFM z%#+)me>y+V7KIC1X}gvO$S~rKgSVRj-8C-d3nQxNLLp|T;tTe3#ud%h<|^-Q{W``c z&a7qG>`O>yGz8jbuo0FCv%caHygSdGr`PpG$u7#Z5ve0;bk6>SQ{MeT(3#E0zh!a$ zGe#)aJdo(JEE{nwdqnYwJ2&FG_dRX`uy-%14Ff?ChVj94|5G`(|HYRS!iGS!%q#~Z z4en7_KdUeI2qWRnRef2fx0hA=IF93cg83>WAfx6mS?Ew6grg0TV|Mjw;UU?=sm~wCT`vcH~^$ID9D2H z)2o<=65*}qnLp?3$tFb>&;m$g zIJ}W%1Ie2;wVsFAe$NHQoyn|1%rTU5dw5lM>=kc>H%3u+J~_SZ@pQ+@KsB*~00aqu zi3j_2{~2K1|J(1|M{~E;j;3$8H{`4kO1|%`Xggc-O`co9Da1~u?s5wyoBwY^{=Rd@ zaqr!Ms|v*c83Um3ukS$wV`&7piWH^c4tGB5hy~8y5MnPU@H>xei#z_;-VH&CT=M*$MDv3KpgJrMSTMN>7# zn1PV{hXMo%@)mTrKF1;>5m4BXg{}2W_a19n^l47MOS4xBcFj|uu26*NrabTLd3VYy zAV4`I$RKD$PKL-_j;PxvDRx00LIhAu2fg+}rMv9HqP2?5M(I7|CKbO32tkM(euAW? z#NgC>3Tj!<%m;EmDjb3m;Eb=!i0{ZVHK;J-k`-w3ESPujhCraoa&SzwlM4)5 z%_V5aMe#M2MDy>2)5>f1^0Y+&M&G6Rg!n zYFMCd_S?es4rJ~1>);3hU**|WAKokU)O*#6BD=Wn7maNH?aDkRj>Hfjpr9T6987Q9 z?B4=#cLym5LqQBc74%%ab+0B^K~42Z{3{pMg#|%G@&D4!G?`51u;nK1NMJur({-Nb zRY9u2=^_!RJ!L7l3qFvan@KIO$D9Z(C?tqvYhJ$FI>ygC8RD_^zj5kM!pKVi$$QG$ zMwFV56^z-ijo;C~M~E^y^%E3nedtF11Rp`&`D_OfHN6gMf?v>7k_XqDIG;dqoMV#U z672I(WSmddp2Q*PCE$kwRU^vpB>=V6715m@i8pj?*2}#niIETo^MDHM(L3IcRK1?X zP>y;Ot)c5doO>kF?14E12O6HH)-g^@$hv|qvyT_zTF!41&9w)iJ=-s~hbcqY>V#{H z$z|Cc562fe@&BknR3O0;fmvT09)g@xc7|Cu#ESw{LuS}+?%~?@@f5^hL$ZgaRNK); zUAx6)7zhe!iekgLo8}x#7g|JGI5XDF+tTrqrtC&~?PxQKReq@){pTb1bsWp6(g|d~ z;UnG0O#s^NUtpf>msRvMzG*xCX`zO^-)?`8rp~AHbIo+!O9JX0{UL3&=)LcZ`AWos5kNpm z`{sKSjKKTqL2AEq1VLb3CahCVuz`&U$U9@*&}jb$QquB`V}kuyv#*WXyE8H*7;vp| z>yk)d-!;biR>bPph}X!8XpX?v+KJy>(5%i8?X;FegT(9ObR*?G0-xir-s36&b9a}6 zAPfWn*h6s!&ZRfTSACHo`OMg8G#V0pM5QfkJ3ITkD-dR)t3aRDMIO_uke{d7(-`gL zux@`&gJJtn_<`E)FM_OvyoINmc0L2aS4Cex6~t~1%5TDSD*(Y}?Vf{xo!Lmo1sxjz zRRn@_9<#x6ayS4J!X;wSM(v{I8sjqcb>m@O9sp_%SF8b33ZMp9B)F#rD8Egv1BfJ! zGn)k@-6Lzt7)%{KKc&=iof47%BvC#04tQau*hxSNJMtcwLp=-CZ73+6HbS=K5}GSE zi0x$_fWDg_w+YrEjD@wYOQoJpUIxC#!^{;B2-^&pEazoYdX(qOdII!e-5QkUcbV&^ za9%GDT~eew_}=&(OvD`_vN-Rd88tc0Slk=fRCh4}l382k+l{CJpr~*Axg*F0*6`(a z9-}DIE}Y>Rw+VA}QS|rUur`Vg)@q-Rd5Ikr`_Dl5E?8x6AavGwM-&>$;XKcWX`1dO z`ZT-#HGzKo+yr3n4ptk8VIU0m3HR~#UE5O`nlJoaLMWlVRba?r**K0Z$S1=O`zbOf@p-HubygF*t&rc|VkG6Xc=6`H^=4@O zKSGlfaS@yLl{{N{0SiQ8P+Jnf328}(z05Ea;y=>k_m8hU>JI~6a|%Mm{K>6@Sh=S8Juu+t$a&-=+@B{u`M31$uP zJW+n|?@PN!N+hqt=xqh`>-aPp7|-aV`-^o6z}vm#FbD%N0PSV6;VRsJm%~(EJY+>s z^@EDUqJ>mIXgnW}=WkW#Avf&%e#GW^ePQxb}M7Ldr^3M$olmIZqx>jw9z_UK&sBMg3d6qyP;f4U1HXK*qDE5L+@H8K;$f zx+s}v(sXYgoNy`Qf`+8~MaYr2VpsrT#E!mqo?CKO77q20$|X8?lk3sKDj*n-GWQU0 z%k^}_-aH!}II_vXC5)_GK`1$Mkn5jw9__qxJRTLo5RW;ZwO`6O8x2-@ug*mSLV(i( z&7Hqy@R19onnZ3bzqg83cc%{JL&z=+F8ZLrxPiFm9w=TJalA3IenO?WzB~)So$vJB zl&=>`CuA;U4cIYad48g$36y!;p7Ux{ zbStP=>&G3T&0qE_GSIu{f0L8!U793omATII9AiATZ9C>vsob4R(cYc{Ped!`(^zrB-A;gum@f?6M*csAM$arB{q+OM-lLtJ`petTfBqPxp0D9CQ8*P){H0m(w-3PQ|_Z6gqHWq{SF z^|RoGBbqR1T~g3+895V55uLMYR&T>U@{Wicxu47t)EOg#){iNexzYS%fI)}alYxji zLd1?+9x63*{?|*SS0^Ht>q!h@oiU#I-b4WomeLcsK=5GhOG9yeNErr>7h~pGiB3cc z)?7c(Bl5i6&pZh=jm%fuv^?MSv7XQ}fnoQ|@kl;XM6bIK7H}&ebid6xCp5PlLjn=$ z`AsLCR#36$6}^k9sd3~Qr~sl3M-dt#x^gepTM7W_Nb?C~IYyY1VqKfi@~J@g%mI); zXB4rt%@4`y-$py4R}5#K&m`h5l(fiMQbu%7AN>|ONs_l}ge z_{g*fB51)qDrMQt{!P9llgUFI;RldEAII@_xm=#k^SqfF@!huRhV6^{Dw^XI)SUq1 z+5$xWq5*#uXhZ`Bv)9W>ge|fz!7dt-oC`Y8;nLPo%mHiS^uqulz^cIqw zD?-*M2i&?p*@D^0$%?eIk&+HgQS}K8@lszz#rJyKKPS|6^xKE2*5_GR$N=Znj`iP0 zN7Vx{ShI&b+cK7`7kbVXOyt)%yw0m_Lkb%pFEI;1ueR?!8N~Z0CBF=7S%Yn{*$9gY zRJP@~JBNFx28%Q%8n8H%7UfLn+|nCfAhejfpJA##>KH5Jjyte3M1KnSJ2GnfpW)1B z=3~k+|IHD)zmKwi1w?wrr9+cbGsm=ds`uo#2{OCA3qai+AKK+Kgxi?`Yytli=bRA|pm zAeN7z+xp;uYCAjF6T~vS1+^>?`E;ZA*&#>tg0k)Rt9iz(X^$y$P03vTA4wNFKKB#` zsOdvsWlyzW2PmrW4SW#azT2wFnzyNSzlR4v+4z#LSjI^huD)k>huqn~IDnjuk z2}`VwF`h}SIDaXjFI~)s0KDBv4uU`w1W*%oulL|6-2WJQ0;3kmGnEc(oY)x+NYnhW zs{Y}hiyXAiGu^$<^Sn4hfQrsKEXo$Fm$B*1zgFXBM7p=dSu`K6=>*+;-xAIp3A8

hr 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

lv*E+@rFPO&C)_k7(gc@q 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

4qzHn?qg}4mYxXEOZ1W?5M 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 literal 0 HcmV?d00001 diff --git a/res/mickey.png b/res/mickey.png new file mode 100644 index 0000000000000000000000000000000000000000..e278799dfa94411bf2600cb9e56c177443ea1530 GIT binary patch literal 58807 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 literal 0 HcmV?d00001 diff --git a/res/pinguin.png b/res/pinguin.png new file mode 100644 index 0000000000000000000000000000000000000000..f8083b6395a140563962a1c043d98076fede9fd6 GIT binary patch literal 53787 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 literal 0 HcmV?d00001 diff --git a/res/popey.png b/res/popey.png new file mode 100644 index 0000000000000000000000000000000000000000..9b986af5b1509238accd6a749cbc3f46c69a5b98 GIT binary patch literal 39428 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 literal 0 HcmV?d00001 diff --git a/res/snoopy.png b/res/snoopy.png new file mode 100644 index 0000000000000000000000000000000000000000..38f8fac0c19013cc029f98e4581bb69a88c91c90 GIT binary patch literal 46143 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%0AsP2$CHA;kclI; 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 szEXg#@i$LL?j?htz)Z@n+a literal 0 HcmV?d00001 diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index c76b209..5e745f4 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -12,6 +12,7 @@ PRECOMPILED_HEADER = src/precompiled.h QT += widgets QT += websockets +QT += qml quick TARGET = SilentDragonLite @@ -33,6 +34,7 @@ mac: LIBS+= -Wl,-bind_at_load RESOURCES = application.qrc + MOC_DIR = bin OBJECTS_DIR = bin UI_DIR = src @@ -105,6 +107,7 @@ HEADERS += \ src/contactmodel.h FORMS += \ + src/contactrequest.ui \ src/encryption.ui \ src/mainwindow.ui \ src/migration.ui \ diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 1a2bad3..70df68e 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -8,7 +8,7 @@ AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) { - headers << tr("Label") << tr("Address") << tr("HushChatAddress") << tr("cid"); + headers << tr("Avatar")<< tr("Label") << tr("Address") << tr("HushChatAddress") << tr("CID"); this->parent = parent; loadData(); } @@ -38,10 +38,10 @@ void AddressBookModel::loadData() ); } -void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid) +void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid, QString avatar) { //labels.push_back(QPair(label, addr)); - AddressBook::getInstance()->addAddressLabel(label, addr, myAddr, cid); + AddressBook::getInstance()->addAddressLabel(label, addr, myAddr, cid, avatar); updateUi(); } @@ -59,7 +59,7 @@ void AddressBookModel::removeItemAt(int row) if (row >= labels.size()) return; - AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress(),labels[row].getCid()); + AddressBook::getInstance()->removeAddressLabel(labels[row].getName(), labels[row].getPartnerAddress(), labels[row].getMyAddress(),labels[row].getCid(),labels[row].getAvatar()); labels.clear(); labels = AddressBook::getInstance()->getAllAddressLabels(); dataChanged(index(0, 0), index(labels.size()-1, columnCount(index(0,0))-1)); @@ -70,7 +70,7 @@ ContactItem AddressBookModel::itemAt(int row) { if (row >= labels.size()) { - ContactItem item = ContactItem("", "", "", ""); + ContactItem item = ContactItem("", "", "", "",""); return item; } @@ -97,10 +97,11 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const { switch(index.column()) { - case 0: return labels.at(index.row()).getName(); - case 1: return labels.at(index.row()).getPartnerAddress(); - case 2: return labels.at(index.row()).getMyAddress(); - case 3: return labels.at(index.row()).getCid(); + case 0: return labels.at(index.row()).getAvatar(); + case 1: return labels.at(index.row()).getName(); + case 2: return labels.at(index.row()).getPartnerAddress(); + case 3: return labels.at(index.row()).getMyAddress(); + case 4: return labels.at(index.row()).getCid(); } } @@ -168,6 +169,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto myAddr = ab.addr_chat->text().trimmed(); QString newLabel = ab.label->text(); QString cid = ab.cid->text(); + QString avatar = "res/yoda.png"; if (addr.isEmpty() || newLabel.isEmpty()) { @@ -204,7 +206,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) } ////// We need a better popup here. - AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid); + AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid,avatar); QMessageBox::critical( parent, QObject::tr("Add Successfully"), @@ -256,7 +258,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) continue; // Add label, address. - model.addNewLabel(items.at(1), items.at(0), "", ""); + model.addNewLabel(items.at(1), items.at(0), "", "", ""); numImported++; } @@ -267,7 +269,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ); }); - auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr, QString myAddr, QString cid) { + auto fnSetTargetLabelAddr = [=] (QLineEdit* target, QString label, QString addr, QString myAddr, QString cid, QString avatar) { target->setText(label % "/" % addr % myAddr); }; @@ -284,8 +286,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString addr = model.itemAt(index.row()).getPartnerAddress(); QString myAddr = model.itemAt(index.row()).getMyAddress(); QString cid = model.itemAt(index.row()).getCid(); + QString avatar = model.itemAt(index.row()).getCid(); d.accept(); - fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid); + fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid, avatar); }); // Right-Click @@ -299,13 +302,14 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString addr = model.itemAt(index.row()).getPartnerAddress(); QString myAddr = model.itemAt(index.row()).getMyAddress(); QString cid = model.itemAt(index.row()).getCid(); + QString avatar = model.itemAt(index.row()).getAvatar(); QMenu menu(parent); if (target != nullptr) menu.addAction("Pick", [&] () { d.accept(); - fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid); + fnSetTargetLabelAddr(target, lbl, addr, myAddr, cid, avatar); }); menu.addAction(QObject::tr("Copy address"), [&] () { @@ -324,7 +328,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) auto selection = ab.addresses->selectionModel(); if (selection && selection->hasSelection() && selection->selectedRows().size() > 0) { auto item = model.itemAt(selection->selectedRows().at(0).row()); - fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress(), item.getCid()); + fnSetTargetLabelAddr(target, item.getName(), item.getMyAddress(), item.getPartnerAddress(), item.getCid(), item.getAvatar()); } }; @@ -370,7 +374,7 @@ void AddressBook::readFromStorage() //qDebug() << "0:" << stuff[i][0]; //qDebug() << "1:" << stuff[i][1]; //qDebug() << "2:" << stuff[i][2]; - ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3]); + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); //qDebug() << "contact=" << contact.toQTString(); allLabels.push_back(contact); } @@ -406,6 +410,7 @@ void AddressBook::writeToStorage() c.push_back(item.getPartnerAddress()); c.push_back(item.getMyAddress()); c.push_back(item.getCid()); + c.push_back(item.getAvatar()); contacts.push_back(c); } out << QString("v1") << contacts; @@ -428,22 +433,22 @@ QString AddressBook::writeableFile() // Add a new address/label to the database -void AddressBook::addAddressLabel(QString label, QString address, QString myAddr, QString cid) +void AddressBook::addAddressLabel(QString label, QString address, QString myAddr, QString cid, QString avatar) { Q_ASSERT(Settings::isValidAddress(address)); // getName(), remove any existing label // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) if (allLabels[i].getName() == label) - removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress(), allLabels[i].getCid()); + removeAddressLabel(allLabels[i].getName(), allLabels[i].getPartnerAddress(),allLabels[i].getMyAddress(), allLabels[i].getCid(), allLabels[i].getAvatar()); - ContactItem item = ContactItem(label, address, myAddr, cid); + ContactItem item = ContactItem(label, address, myAddr, cid, avatar); allLabels.push_back(item); writeToStorage(); } // Remove a new address/label from the database -void AddressBook::removeAddressLabel(QString label, QString address, QString myAddr, QString cid) +void AddressBook::removeAddressLabel(QString label, QString address, QString myAddr, QString cid, QString avatar) { // Iterate over the list and remove the label/address for (int i=0; i < allLabels.size(); i++) diff --git a/src/addressbook.h b/src/addressbook.h index 6f8308b..6c7a450 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -12,7 +12,7 @@ public: AddressBookModel(QTableView* parent); ~AddressBookModel(); - void addNewLabel(QString label, QString address, QString myAddr, QString cid); + void addNewLabel(QString label, QString address, QString myAddr, QString cid, QString avatar); void updateUi(); void removeItemAt(int row); //QPair itemAt(int row); @@ -43,10 +43,10 @@ public: static QString addressFromAddressLabel(const QString& lblAddr); // Add a new address/label to the database - void addAddressLabel(QString label, QString address, QString myAddr, QString cid); + void addAddressLabel(QString label, QString address, QString myAddr, QString cid, QString avatar); // Remove a new address/label from the database - void removeAddressLabel(QString label, QString address, QString myAddr, QString cid); + void removeAddressLabel(QString label, QString address, QString myAddr, QString cid, QString avatar); // Update a label/address void updateLabel(QString oldlabel, QString address, QString newlabel); diff --git a/src/addressbook.ui b/src/addressbook.ui index c2d255d..6f3015d 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -30,7 +30,7 @@ - Nickname + <html><head/><body><p align="right">Nickname :</p></body></html> @@ -51,9 +51,130 @@ + + + + <html><head/><body><p align="right">Avatar :</p></body></html> + + + + + + + + Stag + + + + :/icons/res/hirsch.png + + + + + + Denio + + + + :/icons/res/denio.png + + + + + + Duke + + + + :/icons/res/duke.png + + + + + + Yoda + + + + :/icons/res/yoda.png + + + + + + Berg + + + + :/icons/res/Berg.png + + + + + + Sharpee + + + + :/icons/res/sharpee.png + + + + + + Garflied + + + + :/icons/res/garfield.png + + + + + + Snoopy + + + + :/icons/res/snoopy.png + + + + + + Popey + + + + :/icons/res/popey.png + + + + + + Pinguin + + + + :/icons/res/pinguin.png + + + + + + SDLogo + + + + :/icons/res/sdlogo2.png + + + + + diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 956bd63..6131485 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -3,32 +3,27 @@ #include "mainwindow.h" void ContactModel::renderContactList(QListView* view) -{ // QStandardItem(const QIcon & icon, const QString & text) +{ QStandardItemModel* contact = new QStandardItemModel(); - //} + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - //QStandardItem* Items = new QStandardItem(); auto theme = Settings::getInstance()->get_theme_name(); - if ((theme == "dark" || theme == "midnight")) { - QStandardItem* Items1 = new QStandardItem(QIcon("res/sdlogo.png"),c.getName()); - contact->appendRow(Items1); - view->setModel(contact); - view->setIconSize(QSize(60,70)); - view->setUniformItemSizes(true); - view->setDragDropMode(QAbstractItemView::DropOnly);; - } - if (theme == "default" || theme == "blue"){ + if ((theme == "dark" || theme == "midnight")) { - QStandardItem* Items1 = new QStandardItem(QIcon("res/sdlogo2.png"),c.getName()); - contact->appendRow(Items1); - view->setModel(contact); - view->setIconSize(QSize(60,70)); - view->setUniformItemSizes(true); - view->setDragDropMode(QAbstractItemView::DropOnly);; + // QIcon avatar = c.getAvatar(); + QString avatar = "res/yoda.png"; + + QStandardItem* Items1 = new QStandardItem(QIcon(avatar) ,c.getName()); + contact->appendRow(Items1); + view->setModel(contact); + view->setIconSize(QSize(60,70)); + view->setUniformItemSizes(true); + view->setDragDropMode(QAbstractItemView::DropOnly); } + diff --git a/src/contactmodel.h b/src/contactmodel.h index 2bf3fe3..b643bdb 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -14,15 +14,17 @@ class ContactItem QString _partnerAddress; QString _name; QString _cid; + QString _avatar; public: ContactItem(); - ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid) + ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar) { _name = name; _myAddress = myAddress; _partnerAddress = partnerAddress; _cid = cid; + _avatar = avatar; } QString getName() const @@ -45,6 +47,11 @@ class ContactItem return _cid; } + QString getAvatar() const + { + return _avatar; + } + void setName(QString name) { _name = name; @@ -64,10 +71,14 @@ class ContactItem { _cid = cid; } + void setAvatar(QString avatar) + { + _avatar = avatar; + } QString toQTString() { - return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid; + return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid + "|"+ _avatar; } }; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d685005..05126f8 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1319,6 +1319,7 @@ void MainWindow::setupReceiveTab() { // Receive tab add/update label QObject::connect(ui->rcvUpdateLabel, &QPushButton::clicked, [=]() { QString addr = ui->listReceiveAddresses->currentText(); + if (addr.isEmpty()) return; @@ -1332,7 +1333,7 @@ void MainWindow::setupReceiveTab() { if (!curLabel.isEmpty() && label.isEmpty()) { info = "Removed Label '" % curLabel % "'"; - AddressBook::getInstance()->removeAddressLabel(curLabel, addr, "", ""); + AddressBook::getInstance()->removeAddressLabel(curLabel, addr, "", "","" ); } else if (!curLabel.isEmpty() && !label.isEmpty()) { info = "Updated Label '" % curLabel % "' to '" % label % "'"; @@ -1340,7 +1341,7 @@ void MainWindow::setupReceiveTab() { } else if (curLabel.isEmpty() && !label.isEmpty()) { info = "Added Label '" % label % "'"; - AddressBook::getInstance()->addAddressLabel(label, addr, "", ""); + AddressBook::getInstance()->addAddressLabel(label, addr, "", "", ""); } // Update labels everywhere on the UI From 5dbfe1e4adbd5f6e2a127447061e90866e3b99d0 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 4 May 2020 16:06:08 +0200 Subject: [PATCH 063/253] choose a avatar when create a contact --- application.qrc | 20 +++++++++---------- res/{denio.png => Denio.png} | Bin res/{duke.png => Duke.png} | Bin res/{garfield.png => Garfield.png} | Bin res/{hirsch.png => Hirsch.png} | Bin res/{mickey.png => Mickey.png} | Bin res/{pinguin.png => Pinguin.png} | Bin res/{popey.png => Popey.png} | Bin res/{sharpee.png => Sharpee.png} | Bin res/{snoopy.png => Snoopy.png} | Bin res/Unbenannt-4 Kopie.png | Bin 88464 -> 0 bytes res/{yoda.png => Yoda.png} | Bin src/addressbook.cpp | 30 ++++++++++++++++++++++++++++- src/addressbook.h | 9 +++++++++ src/addressbook.ui | 28 ++++++++++++++++++--------- src/contactmodel.cpp | 2 +- src/mainwindow.cpp | 26 +++++++++++++++++++++++-- src/mainwindow.h | 1 + src/settings.cpp | 9 ++++----- src/settings.h | 2 ++ 20 files changed, 99 insertions(+), 28 deletions(-) rename res/{denio.png => Denio.png} (100%) rename res/{duke.png => Duke.png} (100%) rename res/{garfield.png => Garfield.png} (100%) rename res/{hirsch.png => Hirsch.png} (100%) rename res/{mickey.png => Mickey.png} (100%) rename res/{pinguin.png => Pinguin.png} (100%) rename res/{popey.png => Popey.png} (100%) rename res/{sharpee.png => Sharpee.png} (100%) rename res/{snoopy.png => Snoopy.png} (100%) delete mode 100644 res/Unbenannt-4 Kopie.png rename res/{yoda.png => Yoda.png} (100%) diff --git a/application.qrc b/application.qrc index 42f093b..62ceb1d 100644 --- a/application.qrc +++ b/application.qrc @@ -12,16 +12,16 @@ res/sdlogo.png res/sdlogo2.png res/Berg.png - res/denio.png - res/duke.png - res/sharpee.png - res/yoda.png - res/mickey.png - res/snoopy.png - res/popey.png - res/garfield.png - res/pinguin.png - res/hirsch.png + res/Denio.png + res/Duke.png + res/Sharpee.png + res/Yoda.png + res/Mickey.png + res/Snoopy.png + res/Popey.png + res/Garfield.png + res/Pinguin.png + res/Hirsch.png res/hushdlogo.gif diff --git a/res/denio.png b/res/Denio.png similarity index 100% rename from res/denio.png rename to res/Denio.png diff --git a/res/duke.png b/res/Duke.png similarity index 100% rename from res/duke.png rename to res/Duke.png diff --git a/res/garfield.png b/res/Garfield.png similarity index 100% rename from res/garfield.png rename to res/Garfield.png diff --git a/res/hirsch.png b/res/Hirsch.png similarity index 100% rename from res/hirsch.png rename to res/Hirsch.png diff --git a/res/mickey.png b/res/Mickey.png similarity index 100% rename from res/mickey.png rename to res/Mickey.png diff --git a/res/pinguin.png b/res/Pinguin.png similarity index 100% rename from res/pinguin.png rename to res/Pinguin.png diff --git a/res/popey.png b/res/Popey.png similarity index 100% rename from res/popey.png rename to res/Popey.png diff --git a/res/sharpee.png b/res/Sharpee.png similarity index 100% rename from res/sharpee.png rename to res/Sharpee.png diff --git a/res/snoopy.png b/res/Snoopy.png similarity index 100% rename from res/snoopy.png rename to res/Snoopy.png diff --git a/res/Unbenannt-4 Kopie.png b/res/Unbenannt-4 Kopie.png deleted file mode 100644 index e9d0d54e65200d11b447666bfe67509719442df2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88464 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%0ALx8KyW@??b$Thi56L| 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.trimmed(); QString newLabel = ab.label->text(); QString cid = ab.cid->text(); - QString avatar = "res/yoda.png"; + + + QString avatar = QString("res/") + ab.comboBoxAvatar->currentText() + QString(".png"); + qDebug()<<"AVATAR NAME : " << avatar; if (addr.isEmpty() || newLabel.isEmpty()) { @@ -332,11 +335,34 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) } }; + // Get Avatar Data + + + // int avatar_index = ab.comboBoxAvatar->findText(AddressBook::getInstance()->get_avatar_name(), Qt::MatchExactly); + // ab.comboBoxAvatar->setCurrentIndex(avatar_index); + + // QObject::connect(ab.comboBoxAvatar, &QComboBox::currentTextChanged, [=] (QString avatar_name) { + // parent->slot_change_avatar(avatar_name); + // rpc->refresh(true); + // }); + // Refresh after the dialog is closed to update the labels everywhere. parent->getRPC()->refresh(true); model.updateUi(); //todo fix updating gui after adding } +QString AddressBook::get_avatar_name() { + // Load from the QT Settings. + // QString avatar = ab.comboBoxAvatar.text(); + // return QString() +} + +void AddressBook::set_avatar_name(QString avatar_name) { + avatar_name = "abs.comboBoxAvatar.text()"; +} + + + //============= // AddressBook singleton class //============= @@ -515,6 +541,8 @@ QString AddressBook::addLabelToAddress(QString addr) return addr; } + + QString AddressBook::addressFromAddressLabel(const QString& lblAddr) { return lblAddr.trimmed().split("/").last(); diff --git a/src/addressbook.h b/src/addressbook.h index 6c7a450..fee3ac6 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -22,6 +22,7 @@ public: 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 loadData(); @@ -58,6 +59,14 @@ public: QString getLabelForAddress(QString address); // Get a Label's address QString getAddressForLabel(QString label); + + QString get_avatar_name(); + void set_avatar_name(QString avatar_name); + + + + + private: AddressBook(); diff --git a/src/addressbook.ui b/src/addressbook.ui index 6f3015d..4cec4b1 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -69,7 +69,7 @@ - :/icons/res/hirsch.png + :/icons/res/Hirsch.png @@ -79,7 +79,7 @@ - :/icons/res/denio.png + :/icons/res/Denio.png @@ -89,7 +89,7 @@ - :/icons/res/duke.png + :/icons/res/Duke.png @@ -99,7 +99,7 @@ - :/icons/res/yoda.png + :/icons/res/Yoda.png @@ -119,7 +119,7 @@ - :/icons/res/sharpee.png + :/icons/res/Sharpee.png @@ -129,7 +129,7 @@ - :/icons/res/garfield.png + :/icons/res/Garfield.png @@ -139,7 +139,7 @@ - :/icons/res/snoopy.png + :/icons/res/Snoopy.png @@ -149,7 +149,7 @@ - :/icons/res/popey.png + :/icons/res/Popey.png @@ -159,7 +159,17 @@ - :/icons/res/pinguin.png + :/icons/res/Pinguin.png + + + + + + Mickey + + + + :/icons/res/Mickey.png diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 6131485..0475e6e 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -13,7 +13,7 @@ void ContactModel::renderContactList(QListView* view) if ((theme == "dark" || theme == "midnight")) { // QIcon avatar = c.getAvatar(); - QString avatar = "res/yoda.png"; + QString avatar = c.getAvatar(); QStandardItem* Items1 = new QStandardItem(QIcon(avatar) ,c.getName()); contact->appendRow(Items1); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 05126f8..5e166e4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -436,7 +436,9 @@ void MainWindow::setupSettingsModal() { this->slot_change_currency(currency_name); - ; + // Include Avatar + + // Setup theme combo @@ -461,7 +463,7 @@ void MainWindow::setupSettingsModal() { // Tell the user to restart QMessageBox::information(this, tr("Currency Change"), tr("This change can take a few seconds."), QMessageBox::Ok); }); - + // Check for updates settings.chkCheckUpdates->setChecked(Settings::getInstance()->getCheckForUpdates()); @@ -1468,6 +1470,26 @@ void MainWindow::slot_change_currency(const QString& currency_name) } } +void MainWindow::slot_change_avatar(const QString& avatar_name) + +{ + + AddressBook::getInstance()->set_avatar_name(avatar_name); + + // Include currency + + QString saved_avatar_name; + try + { + saved_avatar_name = AddressBook::getInstance()->get_avatar_name(); + + } + catch (...) + { + saved_avatar_name = "Yoda"; + + } +} void MainWindow::slot_change_theme(const QString& theme_name) diff --git a/src/mainwindow.h b/src/mainwindow.h index c767128..0441de3 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -83,6 +83,7 @@ public: public slots: void slot_change_theme(const QString& themeName); void slot_change_currency(const QString& currencyName); + void slot_change_avatar(const QString& avatarName); private: void closeEvent(QCloseEvent* event); diff --git a/src/settings.cpp b/src/settings.cpp index fbfb1cb..2d99ff7 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -225,13 +225,9 @@ QString Settings::get_currency_name() { } void Settings::set_currency_name(QString currency_name) { - QSettings().setValue("options/currency_name", currency_name); - - - + QSettings().setValue("options/currency_name", currency_name); } - QString Settings::get_theme_name() { // Load from the QT Settings. return QSettings().value("options/theme_name", false).toString(); @@ -242,6 +238,9 @@ void Settings::set_theme_name(QString theme_name) { } + + + //================================= // Static Stuff //================================= diff --git a/src/settings.h b/src/settings.h index a917d67..c598369 100644 --- a/src/settings.h +++ b/src/settings.h @@ -67,6 +67,8 @@ public: void set_currency_name(QString currency_name); + + bool isSaplingActive(); void setZECPrice(double p) { ZECPrice = p; } From dc61bb38c7e8751a5f035a673014a9050f11af1e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 4 May 2020 20:17:20 +0200 Subject: [PATCH 064/253] add contact on Chattab --- application.qrc | 2 +- res/{Hirsch.png => Stag.png} | Bin src/addressbook.cpp | 23 --- src/addressbook.ui | 2 +- src/chatmodel.cpp | 137 ++++++++------ src/chatmodel.h | 1 + src/contactmodel.cpp | 1 - src/contactrequest.ui | 358 ++++++++++++++++++++++------------- src/mainwindow.cpp | 46 ++--- src/mainwindow.h | 2 +- src/mainwindow.ui | 54 ++++-- 11 files changed, 372 insertions(+), 254 deletions(-) rename res/{Hirsch.png => Stag.png} (100%) diff --git a/application.qrc b/application.qrc index 62ceb1d..09ec74c 100644 --- a/application.qrc +++ b/application.qrc @@ -21,7 +21,7 @@ res/Popey.png res/Garfield.png res/Pinguin.png - res/Hirsch.png + res/Stag.png res/hushdlogo.gif diff --git a/res/Hirsch.png b/res/Stag.png similarity index 100% rename from res/Hirsch.png rename to res/Stag.png diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 6f209d1..d318f35 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -335,34 +335,11 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) } }; - // Get Avatar Data - - - // int avatar_index = ab.comboBoxAvatar->findText(AddressBook::getInstance()->get_avatar_name(), Qt::MatchExactly); - // ab.comboBoxAvatar->setCurrentIndex(avatar_index); - - // QObject::connect(ab.comboBoxAvatar, &QComboBox::currentTextChanged, [=] (QString avatar_name) { - // parent->slot_change_avatar(avatar_name); - // rpc->refresh(true); - // }); - // Refresh after the dialog is closed to update the labels everywhere. parent->getRPC()->refresh(true); model.updateUi(); //todo fix updating gui after adding } -QString AddressBook::get_avatar_name() { - // Load from the QT Settings. - // QString avatar = ab.comboBoxAvatar.text(); - // return QString() -} - -void AddressBook::set_avatar_name(QString avatar_name) { - avatar_name = "abs.comboBoxAvatar.text()"; -} - - - //============= // AddressBook singleton class //============= diff --git a/src/addressbook.ui b/src/addressbook.ui index 4cec4b1..b6d8d0a 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -69,7 +69,7 @@ - :/icons/res/Hirsch.png + :/icons/res/Stag.png diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 550081c..e80c436 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -164,7 +164,7 @@ QString ChatModel::getCidByTx(QString tx) { for(auto& pair : this->cidMap) { - // qDebug() << "TXID=" << pair.first << " CID=" << pair.second; + } if(this->cidMap.count(tx) > 0) @@ -247,9 +247,7 @@ Tx MainWindow::createTxFromChatPage() { void MainWindow::sendChatButton() { - - - ////////////////////////////Todo: Check if a Contact is selected////////// +////////////////////////////Todo: Check if a Contact is selected////////// // Create a Tx from the values on the send tab. Note that this Tx object // might not be valid yet. @@ -377,25 +375,80 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { return ""; } +void::MainWindow::addContact() { -// Create a Tx from the current state of the Chat page. -Tx MainWindow::createTxForSafeContactRequest() { - - Ui_Dialog request; + Ui_Dialog request; QDialog dialog(this); request.setupUi(&dialog); Settings::saveRestore(&dialog); -dialog.exec(); - - Tx tx; - QObject::connect(request.cancel, &QPushButton::clicked, [&] () { + bool sapling = true; + rpc->createNewZaddr(sapling, [=] (json reply) { + QString myAddr = QString::fromStdString(reply.get()[0]); + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + ui->listReceiveAddresses->insertItem(0, myAddr); + ui->listReceiveAddresses->setCurrentIndex(0); + + qDebug() << "new generated myAddr" << myAddr; + request.myzaddr->setText(myAddr); + request.cid->setText(cid); + + }); + + + QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { + + QString cid = request.cid->text(); + auto addr = request.zaddr->text().trimmed(); + QString newLabel = request.labelRequest->text().trimmed(); + auto myAddr = request.myzaddr->text().trimmed(); + + QString avatar = QString("res/") + request.comboBoxAvatar->currentText() + QString(".png"); + + if (addr.isEmpty() || newLabel.isEmpty()) + { + QMessageBox::critical( + this, + QObject::tr("Address or Label Error"), + QObject::tr("Address or Label cannot be empty"), + QMessageBox::Ok + ); + return; + } + + // Test if address is valid. + if (!Settings::isValidAddress(addr)) + { + QMessageBox::critical( + this, + QObject::tr("Address Format Error"), + QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), + QMessageBox::Ok + ); + return; + } + + ////// We need a better popup here. + AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); + QMessageBox::critical( + this, + QObject::tr("Add Successfully"), + QObject::tr("juhu").arg(newLabel), + QMessageBox::Ok + ); + return; - dialog.close(); }); + + dialog.exec(); +} - QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); +// Create a Tx for a contact Request +Tx MainWindow::createTxForSafeContactRequest() { + + Tx tx; + // For each addr/amt in the Chat tab { CAmount totalAmt; @@ -408,71 +461,41 @@ dialog.exec(); for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (request.zaddr->text().trimmed() != c.getPartnerAddress()) { + if (ui->contactNameMemo->text().trimmed() == c.getName()) { QString cid = c.getCid(); QString myAddr = c.getMyAddress(); QString type = "cont"; - QString addr = request.zaddr->text(); - - + QString addr = c.getPartnerAddress(); - QString hmemo= createHeaderMemo(type,cid,myAddr,0,0); - QString memo = request.requestmemo->toPlainText().trimmed(); + QString hmemo= createHeaderMemo(type,cid,myAddr); + QString memo = ui->memoTxtChat->toPlainText().trimmed(); tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); qDebug() << "pushback chattx"; - tx.fee = Settings::getMinerFee(); + + } + + tx.fee = Settings::getMinerFee(); return tx; - qDebug() << "ChatTx created"; - } if (request.zaddr->text().trimmed().isEmpty() == false){ + qDebug() << "RequestTx created"; - QMessageBox msg(QMessageBox::Critical, tr("Please insert a contact Address"), request.zaddr->text(), - QMessageBox::Ok, this); - - msg.exec(); - - } } - + } + void MainWindow::ContactRequest() { - - - ////////////////////////////Todo: Check if a Contact is selected////////// - - // Create a Tx from the values on the send tab. Note that this Tx object - // might not be valid yet. - - // Memos can only be used with zAddrs. So check that first - // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - - // if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { - - // auto addr = ""; - // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { - // QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), - // tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), - // QMessageBox::Ok, this); - - // msg.exec(); - // return; - // } - - -//}; - Tx tx = createTxForSafeContactRequest(); - QString error = doSendChatTxValidations(tx); + QString error = doSendRequestTxValidations(tx); if (!error.isEmpty()) { // Something went wrong, so show an error and exit @@ -504,7 +527,7 @@ void MainWindow::ContactRequest() { } connD->status->setText(tr("Please wait...")); - connD->statusDetail->setText(tr("Your Message will be send")); + connD->statusDetail->setText(tr("Your Contact will be send")); d->show(); ui->memoTxtChat->clear(); diff --git a/src/chatmodel.h b/src/chatmodel.h index 490f336..cde16cb 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -310,6 +310,7 @@ class ChatModel void addCid(QString tx, QString cid); QString getCidByTx(QString tx); void killCidCache(); + }; #endif \ No newline at end of file diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 0475e6e..d6a7e25 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -12,7 +12,6 @@ void ContactModel::renderContactList(QListView* view) auto theme = Settings::getInstance()->get_theme_name(); if ((theme == "dark" || theme == "midnight")) { - // QIcon avatar = c.getAvatar(); QString avatar = c.getAvatar(); QStandardItem* Items1 = new QStandardItem(QIcon(avatar) ,c.getName()); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 1bd758f..cee434f 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -13,138 +13,222 @@ Dialog - - - - 0 - 100 - 351 - 17 - - - - <html><head/><body><p>Please insert the Address of your contact :</p></body></html> - - - - - - 10 - 190 - 461 - 17 - - - - <html><head/><body><p>Insert a Message, and ask your friend for the contact request : </p><p><br/></p></body></html> - - - - - - 0 - 240 - 591 - 101 - - - - - - - 0 - 140 - 591 - 25 - - - - - - - 490 - 360 - 114 - 25 - - - - - 100 - 0 - - - - Send - - - false - - - - - - 320 - 360 - 114 - 25 - - - - - 100 - 0 - - - - Cancel - - - false - - - - - - 0 - 10 - 351 - 17 - - - - <html><head/><body><p>Please insert a Nickname for your contact :</p></body></html> - - - - - - 0 - 50 - 591 - 25 - - - + + + + + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + + + + + + + <html><head/><body><p>Please insert a Nickname for your contact :</p></body></html> + + + + + + + + Stag + + + + :/icons/res/Hirsch.png + + + + + + Denio + + + + :/icons/res/Denio.png + + + + + + Duke + + + + :/icons/res/Duke.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + + + + Berg + + + + :/icons/res/Berg.png + + + + + + Sharpee + + + + :/icons/res/Sharpee.png + + + + + + Garfield + + + + :/icons/res/Garfield.png + + + + + + Snoopy + + + + :/icons/res/Snoopy.png + + + + + + Popey + + + + :/icons/res/Popey.png + + + + + + Pinguin + + + + :/icons/res/Pinguin.png + + + + + + Mickey + + + + :/icons/res/Mickey.png + + + + + + SDLogo + + + + :/icons/res/sdlogo2.png + + + + + + + + + + + + <html><head/><body><p>Please insert the Address of your contact :</p></body></html> + + + + + + + + + + Your HushChat Address + + + + + + + + + + + + + + The Conversation ID + + + + + + + + + + + + + + + 100 + 0 + + + + Cancel + + + false + + + + + + + + 100 + 0 + + + + Add Contact + + + false + + + + - - sendRequestButton - clicked() - Dialog - accept() - - - 536 - 262 - - - 389 - 207 - - - cancel clicked() @@ -161,5 +245,21 @@ + + sendRequestButton + clicked() + Dialog + accept() + + + 536 + 262 + + + 389 + 207 + + + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5e166e4..c2b1403 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -40,10 +40,9 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); - // ui->checkBox->setChecked(true); + ui->request->setChecked(true); logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); ui->memoTxtChat->setAutoFillBackground(false); - // ui->memoTxtChat->setStyleSheet(QString::fromUtf8("background-color: rgb(224, 224, 224);")); ui->memoTxtChat->setPlaceholderText("Send Message"); ui->memoTxtChat->setTextColor(Qt::white); @@ -436,11 +435,6 @@ void MainWindow::setupSettingsModal() { this->slot_change_currency(currency_name); - // Include Avatar - - - - // Setup theme combo int theme_index = settings.comboBoxTheme->findText(Settings::getInstance()->get_theme_name(), Qt::MatchExactly); settings.comboBoxTheme->setCurrentIndex(theme_index); @@ -1008,8 +1002,22 @@ void MainWindow::setupTransactionsTab() { void MainWindow::setupchatTab() { // Send button - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); - QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::ContactRequest); + + // Is request Contact checked? + + if (ui->request->isChecked()) { + + + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); + + // qDebug() <request->isChecked()->text(); + }else{ + + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + + } + + QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); ///////// Set selected Zaddr for Chat with Doubleklick @@ -1470,26 +1478,6 @@ void MainWindow::slot_change_currency(const QString& currency_name) } } -void MainWindow::slot_change_avatar(const QString& avatar_name) - -{ - - AddressBook::getInstance()->set_avatar_name(avatar_name); - - // Include currency - - QString saved_avatar_name; - try - { - saved_avatar_name = AddressBook::getInstance()->get_avatar_name(); - - } - catch (...) - { - saved_avatar_name = "Yoda"; - - } -} void MainWindow::slot_change_theme(const QString& theme_name) diff --git a/src/mainwindow.h b/src/mainwindow.h index 0441de3..a98e622 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -83,7 +83,6 @@ public: public slots: void slot_change_theme(const QString& themeName); void slot_change_currency(const QString& currencyName); - void slot_change_avatar(const QString& avatarName); private: void closeEvent(QCloseEvent* event); @@ -116,6 +115,7 @@ private: void cancelButton(); void sendButton(); void sendChatButton(); + void addContact(); void ContactRequest(); void addAddressSection(); void maxAmountChecked(int checked); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index e58e4ad..4c958a3 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1334,7 +1334,7 @@ 0 40 341 - 551 + 601 @@ -1342,8 +1342,8 @@ 0 - 0 - 311 + 20 + 341 20 @@ -1355,9 +1355,9 @@ 340 - 460 + 560 921 - 131 + 81 @@ -1368,7 +1368,7 @@ 1190 - 610 + 650 47 17 @@ -1396,8 +1396,8 @@ - 710 - 610 + 720 + 640 114 25 @@ -1418,8 +1418,8 @@ - 50 - 600 + 30 + 640 211 25 @@ -1456,7 +1456,7 @@ 340 40 921 - 421 + 521 @@ -1484,6 +1484,19 @@ true + + + + 340 + 650 + 261 + 23 + + + + Is this message a contact request? + + @@ -1694,5 +1707,22 @@ - + + + request + stateChanged(int) + MainWindow + update() + + + 481 + 721 + + + 636 + 389 + + + + From 5a8d8c7421ef899157e11f47a8c4c9a3cf3d68df Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 4 May 2020 20:23:08 +0200 Subject: [PATCH 065/253] fix stag png --- src/contactrequest.ui | 2 +- src/mainwindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contactrequest.ui b/src/contactrequest.ui index cee434f..5edcfa6 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -36,7 +36,7 @@ - :/icons/res/Hirsch.png + :/icons/res/Stag.png diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c2b1403..a4bee22 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -40,7 +40,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); - ui->request->setChecked(true); + ui->request->setChecked(false); logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); ui->memoTxtChat->setAutoFillBackground(false); ui->memoTxtChat->setPlaceholderText("Send Message"); From b8a14438329a6c98f7abf26004e737a78e8406c5 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 4 May 2020 23:40:28 +0200 Subject: [PATCH 066/253] show outgoing memos correctly --- application.qrc | 2 +- res/Elsa.png | Bin 0 -> 93888 bytes src/addressbook.ui | 10 ++++++++++ src/chatmodel.cpp | 13 +++++++------ src/contactrequest.ui | 22 ++++++++++++++-------- src/controller.cpp | 12 ++++++------ src/mainwindow.cpp | 4 ---- src/mainwindow.h | 3 ++- src/mainwindow.ui | 28 ++++++++++++---------------- 9 files changed, 52 insertions(+), 42 deletions(-) create mode 100644 res/Elsa.png diff --git a/application.qrc b/application.qrc index 09ec74c..51a4cc4 100644 --- a/application.qrc +++ b/application.qrc @@ -22,10 +22,10 @@ res/Garfield.png res/Pinguin.png res/Stag.png + res/Elsa.png res/hushdlogo.gif - res/logobig.gif res/silentdragonlite-animated.gif res/silentdragonlite-animated-dark.gif res/silentdragonlite-animated-startup.gif diff --git a/res/Elsa.png b/res/Elsa.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d1341501a88c8fa2dca612b7509453301402df GIT binary patch literal 93888 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 XQyn;mUG!Vl00000NkvXXu0mjf8pK|s literal 0 HcmV?d00001 diff --git a/src/addressbook.ui b/src/addressbook.ui index b6d8d0a..f7877bf 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -73,6 +73,16 @@ + + + Elsa + + + + :/icons/res/Elsa.png + + + Denio diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index e80c436..034500f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -228,12 +228,13 @@ Tx MainWindow::createTxFromChatPage() { QString hmemo= createHeaderMemo(type,cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); + - // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat - - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; - + // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat tx.toAddrs.push_back(ToFields{addr, amt, memo}); + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + + qDebug() << "pushback chattx"; } } @@ -472,9 +473,9 @@ Tx MainWindow::createTxForSafeContactRequest() { QString hmemo= createHeaderMemo(type,cid,myAddr); QString memo = ui->memoTxtChat->toPlainText().trimmed(); - - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + qDebug() << "pushback chattx"; diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 5edcfa6..e2939ee 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -28,7 +28,7 @@ - + @@ -40,6 +40,16 @@ + + + Elsa + + + + :/icons/res/Elsa.png + + + Denio @@ -162,7 +172,7 @@ - + @@ -172,12 +182,8 @@ - - - - - - + + diff --git a/src/controller.cpp b/src/controller.cpp index 81676e6..5fdb7e6 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -882,7 +882,7 @@ void Controller::refreshTransactions() { QString cid; QString contact; - + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { if (ui->contactNameMemo->text().trimmed() == c.getName()) { @@ -894,7 +894,7 @@ void Controller::refreshTransactions() { contact = c.getName(); }else{ contact = "";} - + ChatItem item = ChatItem( datetime, address, @@ -906,6 +906,7 @@ void Controller::refreshTransactions() { ); chatModel->addMessage(item); + } } @@ -918,11 +919,9 @@ void Controller::refreshTransactions() { QList addresses; for (auto item : items) { // Concat all the addresses - if (item.amount == 0) { - - }else{ + - addresses.push_back(item.address); } + addresses.push_back(item.address); } @@ -932,6 +931,7 @@ void Controller::refreshTransactions() { txdata.push_back(TransactionItem{ "send", datetime, address, txid,confirmations, items }); + } else { // Incoming Transaction address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a4bee22..325f076 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1077,10 +1077,6 @@ void ChatMemoEdit::setMaxLen(int len) { updateDisplay(); } -void ChatMemoEdit::setLenDisplayLabel(QLabel* label_40) { - this->lenDisplayLabel = label_40; -} - void ChatMemoEdit::setSendChatButton(QPushButton* button) { this->sendChatButton = button; } diff --git a/src/mainwindow.h b/src/mainwindow.h index a98e622..ee2e5ee 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -93,6 +93,7 @@ private: void setupBalancesTab(); void setuphushdTab(); void setupchatTab(); + void setLenDisplayLabel(QLabel* label); void updateContacts(); void updateChat(); @@ -168,7 +169,7 @@ public: ChatMemoEdit(QWidget* parent); void setMaxLen(int len); - void setLenDisplayLabel(QLabel* label_40); + void setSendChatButton(QPushButton* button); void includeReplyTo(QString replyToAddress); void updateDisplay(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 4c958a3..b5f3539 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1337,6 +1337,18 @@ 601 + + true + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + QAbstractItemView::SingleSelection + @@ -1364,22 +1376,6 @@ font: 11pt "Noto Color Emoji"; - - - - 1190 - 650 - 47 - 17 - - - - 0 / 512 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - From 492ebbf1c5ee0de3c8b6b82c49f31f0520c97932 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 5 May 2020 17:15:05 +0200 Subject: [PATCH 067/253] some changes --- src/addressbook.cpp | 2 +- src/chatmodel.cpp | 54 ++++++++++++++++---------------------------- src/contactmodel.cpp | 1 + src/controller.cpp | 41 ++++++--------------------------- src/mainwindow.cpp | 1 + 5 files changed, 30 insertions(+), 69 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index d318f35..1dd1a8f 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -8,7 +8,7 @@ AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) { - headers << tr("Avatar")<< tr("Label") << tr("Address") << tr("HushChatAddress") << tr("CID"); + headers << tr("Label") << tr("Address") << tr("HushChatAddress") << tr("CID"); this->parent = parent; loadData(); } diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 034500f..b55dd5c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -10,13 +10,10 @@ #include "ui_memodialog.h" #include "ui_contactrequest.h" #include "addressbook.h" -#include -#include -#include #include +#include using namespace std; -using namespace boost; ChatModel::ChatModel(std::map chatItems) { @@ -108,52 +105,40 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) for (auto &c : this->chatItems) for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { - - - //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid - if ( - (ui->contactNameMemo->text().trimmed() == c.second.getContact()) && - (c.second.getMemo().startsWith("{") == false) && - (c.second.getMemo().isEmpty() == false) && - (p.getPartnerAddress() == c.second.getAddress()) - - ) - { - + + if ((c.second.getContact() == ui->contactNameMemo->text().trimmed()) && (p.getPartnerAddress() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false) && (c.second.isOutgoing() == true)) + { + QStandardItem* Items = new QStandardItem(c.second.toChatLine()); Items->setData("Outgoing", Qt::UserRole +1); chat->appendRow(Items); - - ui->listChat->setModel(chat); - ui->listChat->setItemDelegate(new ListViewDelegate()); - - } - + ui->listChat->setModel(chat); - if ( - (ui->contactNameMemo->text().trimmed() == c.second.getContact()) && - (c.second.getMemo().startsWith("{") == false) && - (c.second.getMemo().isEmpty() == false) && - (p.getMyAddress() == c.second.getAddress()) + } + else{ + ui->listChat->setModel(chat); - ) + } + + if ((c.second.getContact() == ui->contactNameMemo->text().trimmed()) && ((p.getMyAddress() == c.second.getAddress()) && c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false) && (c.second.isOutgoing() == false)) { QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); Items1->setData("Incoming", Qt::UserRole +1); chat->appendRow(Items1); + ui->listChat->setModel(chat); + } + else{ - ui->listChat->setModel(chat); - ui->listChat->setItemDelegate(new ListViewDelegate()); - + ui->listChat->setModel(chat); + } - } } - +} void ChatModel::addCid(QString tx, QString cid) { @@ -231,8 +216,9 @@ Tx MainWindow::createTxFromChatPage() { // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat - tx.toAddrs.push_back(ToFields{addr, amt, memo}); + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + tx.toAddrs.push_back(ToFields{addr, amt, memo}); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index d6a7e25..17d3fd4 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -20,6 +20,7 @@ void ContactModel::renderContactList(QListView* view) view->setIconSize(QSize(60,70)); view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly); + view->show(); } diff --git a/src/controller.cpp b/src/controller.cpp index 5fdb7e6..fd1189f 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -149,10 +149,6 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) allRecepients.push_back(rec) ; } - int decider = qrand() % ((100 + 1)-1)+ 1;// random int between 1 and 100 - //50% chance of adding another zdust, shuffle. - - if(decider % 4 == 3) allRecepients.insert(std::begin(allRecepients), { dust.at(0), dust.at(1), @@ -164,21 +160,6 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) dust.at(7), dust.at(8) }) ; - // std::shuffle(allRecepients.begin(),allRecepients.end(),std::random_device()); - else - allRecepients.insert(std::begin(allRecepients), { - dust.at(0), - dust.at(1), - dust.at(2), - dust.at(3), - dust.at(4), - dust.at(5), - dust.at(6), - dust.at(7), - dust.at(8), - dust.at(9) - }); - // std::shuffle(allRecepients.begin(),allRecepients.end(),std::random_device()); } void Controller::noConnection() @@ -879,22 +860,17 @@ void Controller::refreshTransactions() { QString memo; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - +} QString cid; QString contact; for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - if (ui->contactNameMemo->text().trimmed() == c.getName()) { - - cid = c.getCid(); - }else {cid = "";} - - if (address == c.getPartnerAddress()){ + if (address == c.getPartnerAddress()){ contact = c.getName(); - }else{ contact = "";} - - + }else{ contact = "";} + } + ChatItem item = ChatItem( datetime, address, @@ -906,10 +882,7 @@ void Controller::refreshTransactions() { ); chatModel->addMessage(item); - - } - - } + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -922,7 +895,7 @@ void Controller::refreshTransactions() { addresses.push_back(item.address); - + address = addresses.join(","); } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 325f076..5b71245 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -914,6 +914,7 @@ void MainWindow::setupTransactionsTab() { ui->listChat->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listChat->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listChat->setMinimumSize(200,350); + ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->show(); ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu); // Table right click From 6a3b644a0a436a8d90d1105714c840f3ef325216 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 6 May 2020 15:40:55 +0200 Subject: [PATCH 068/253] first implementation of automated contact request detection - work in progress --- reuqestDialog.ui | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 reuqestDialog.ui diff --git a/reuqestDialog.ui b/reuqestDialog.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/reuqestDialog.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From 5ff2d1ba47261e37100f15be70a7faa4e2397f78 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 6 May 2020 15:41:40 +0200 Subject: [PATCH 069/253] first implementation of automated contact request detection - work in progress --- res/css/dark.css | 2 +- reuqestDialog.ui | 72 -------- silentdragon-lite.pro | 1 + src/addressbook.cpp | 2 + src/chatmodel.cpp | 113 +++++++++++- src/chatmodel.h | 44 ++++- src/connection.h | 1 + src/contactmodel.cpp | 11 +- src/contactrequest.ui | 2 +- src/controller.cpp | 48 +++-- src/mainwindow.cpp | 28 ++- src/mainwindow.h | 14 ++ src/mainwindow.ui | 21 ++- src/requestContactDialog.ui | 355 ++++++++++++++++++++++++++++++++++++ 14 files changed, 599 insertions(+), 115 deletions(-) delete mode 100644 reuqestDialog.ui create mode 100644 src/requestContactDialog.ui diff --git a/res/css/dark.css b/res/css/dark.css index 7846b25..6dc6cfe 100644 --- a/res/css/dark.css +++ b/res/css/dark.css @@ -1,5 +1,5 @@ -QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QTableView::item, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow +QWidget, QMainWindow, QMenuBar, QMenu, QDialog, QTabWidget, QTableView, QTableView::item, QScrollArea, QGroupBox, QPlainTextEdit, QLineEdit, QLabel, MainWindow, ChatModel, requestDialog { background-color: #303335; color: #ffffff; diff --git a/reuqestDialog.ui b/reuqestDialog.ui deleted file mode 100644 index fb923db..0000000 --- a/reuqestDialog.ui +++ /dev/null @@ -1,72 +0,0 @@ - - - - - Dialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - - diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 5e745f4..a3364d2 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -126,6 +126,7 @@ FORMS += \ src/mobileappconnector.ui \ src/createhushconfdialog.ui \ src/recurringdialog.ui \ + src/requestContactDialog.ui \ src/newrecurring.ui \ src/requestdialog.ui \ src/recurringmultiple.ui \ diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 1dd1a8f..a16d7c8 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -1,3 +1,5 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #include "addressbook.h" #include "ui_addressbook.h" #include "ui_mainwindow.h" diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b55dd5c..b9133b8 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -6,6 +6,7 @@ #include "controller.h" #include "mainwindow.h" #include "ui_mainwindow.h" +#include "ui_requestContactDialog.h" #include "addressbook.h" #include "ui_memodialog.h" #include "ui_contactrequest.h" @@ -83,6 +84,7 @@ void ChatModel::showMessages() { qDebug() << c.second.toChatLine(); } + } void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView &view) @@ -97,7 +99,10 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView &view) void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { - + QObject::connect(ui->pushContact, &QPushButton::clicked,[&] () + { + renderContactRequest(); + }); QStandardItemModel* chat = new QStandardItemModel(); @@ -136,15 +141,98 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setModel(chat); } - + + } + } + +void ChatModel::renderContactRequest(){ + + Ui_requestDialog requestContact; + QDialog dialog(main); + requestContact.setupUi(&dialog); + Settings::saveRestore(&dialog); + + { + QStandardItemModel* contactRequest = new QStandardItemModel(); + + + for (auto &c : this->chatItems) { + if ((c.second.getType() == "cont") && (c.second.isOutgoing() == false) && (c.second.getMemo().startsWith("{"))) { + + + + QStandardItem* Items = new QStandardItem(c.second.getAddress()); + contactRequest->appendRow(Items); + requestContact.requestContact->setModel(contactRequest); + // requestContact.requestContact->show(); + + + + } + } + } + // } + + + QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { + + for (auto &c : this->chatItems){ + QModelIndex index = requestContact.requestContact->currentIndex(); + QString label_contact = index.data(Qt::DisplayRole).toString(); + QStandardItemModel* contactMemo = new QStandardItemModel(); + + if (c.second.isOutgoing() == false) { + if (label_contact == c.second.getAddress()) { + if(c.second.getMemo().startsWith("{")){ + + }else{ + QStandardItem* Items = new QStandardItem(c.second.getMemo()); + contactMemo->appendRow(Items); + requestContact.requestMemo->setModel(contactMemo); + requestContact.requestMemo->show(); + + requestContact.requestZaddr->setText(c.second.getRequestZaddr()); + requestContact.requestCID->setText(c.second.getCid()); + requestContact.requestMyAddr->setText(c.second.getAddress()); + } + } + } + + } + }); + + + + QObject::connect(requestContact.pushButton, &QPushButton::clicked, [&] () { + + QString cid = requestContact.requestCID->text(); + auto addr = requestContact.requestZaddr->text().trimmed(); + QString newLabel = requestContact.requestLabel->text().trimmed(); + auto myAddr = requestContact.requestMyAddr->text().trimmed(); + + QString avatar = QString("res/") + requestContact.comboBoxAvatar->currentText() + QString(".png"); + + qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); + }); + + + dialog.exec(); } + + void ChatModel::addCid(QString tx, QString cid) { this->cidMap[tx] = cid; } +void ChatModel::addrequestZaddr(QString tx, QString requestZaddr) +{ + this->requestZaddrMap[tx] = requestZaddr; +} + QString ChatModel::getCidByTx(QString tx) { for(auto& pair : this->cidMap) @@ -160,11 +248,31 @@ QString ChatModel::getCidByTx(QString tx) return QString("0xdeadbeef"); } +QString ChatModel::getrequestZaddrByTx(QString tx) +{ + for(auto& pair : this->requestZaddrMap) + { + + } + + if(this->requestZaddrMap.count(tx) > 0) + { + return this->requestZaddrMap[tx]; + } + + return QString("0xdeadbeef"); +} + void ChatModel::killCidCache() { this->cidMap.clear(); } +void ChatModel::killrequestZaddrCache() +{ + this->requestZaddrMap.clear(); +} + QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) { @@ -183,6 +291,7 @@ QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, header = j.toJson(); qDebug() << "made header=" << header; return header; + } diff --git a/src/chatmodel.h b/src/chatmodel.h index cde16cb..945c27c 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -14,6 +14,7 @@ #include "camount.h" + class ListViewDelegate : public QAbstractItemDelegate { int d_radius; @@ -163,7 +164,9 @@ class ChatItem long _timestamp; QString _address; QString _contact; - QString _memo; + QString _memo; + QString _requestZaddr; + QString _type; QString _cid; QString _txid; bool _outgoing = false; @@ -171,24 +174,28 @@ class ChatItem public: ChatItem() {} - ChatItem(long timestamp, QString address, QString contact, QString memo, QString cid, QString txid) + ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid) { _timestamp = timestamp; _address = address; _contact = contact; _memo = memo; + _requestZaddr = requestZaddr; + _type = type; _cid = cid; _txid = txid; _outgoing = false; } - ChatItem(long timestamp, QString address, QString contact, QString memo, QString cid, QString txid, bool outgoing) + ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing) { _timestamp = timestamp; _address = address; _contact = contact; _memo = memo; + _requestZaddr = requestZaddr; + _type = type; _cid = cid; _txid = txid; _outgoing = outgoing; @@ -215,6 +222,15 @@ class ChatItem return _memo; } + QString getRequestZaddr() + { + return _requestZaddr; + } + QString getType() + { + return _type; + } + QString getCid() { return _cid; @@ -224,6 +240,7 @@ class ChatItem { return _txid; } + bool isOutgoing() { @@ -244,12 +261,22 @@ class ChatItem { _contact = contact; } - + void setMemo(QString memo) { _memo = memo; } + void setRequestZaddr(QString requestZaddr) + { + _requestZaddr = requestZaddr; + } + + void setType(QString type) + { + _type = type; + } + void setCid(QString cid) { _cid = cid; @@ -258,7 +285,7 @@ class ChatItem { _txid = txid; } - + void toggleOutgo() { _outgoing = true; @@ -291,6 +318,7 @@ class ChatModel Ui::MainWindow* ui; MainWindow* main; std::map cidMap; + std::map requestZaddrMap; public: ChatModel() {}; @@ -303,13 +331,19 @@ class ChatModel void setItems(std::vector items); void renderChatBox(Ui::MainWindow* ui, QListView &view); void renderChatBox(Ui::MainWindow* ui, QListView *view); + void renderContactRequest(); + void triggerRequest(); void showMessages(); void clear(); + //void renderContactRequest(Ui::MainWindow* ui, QListView *view); void addMessage(ChatItem item); void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); + void addrequestZaddr(QString tx, QString requestZaddr); QString getCidByTx(QString tx); + QString getrequestZaddrByTx(QString tx); void killCidCache(); + void killrequestZaddrCache(); }; diff --git a/src/connection.h b/src/connection.h index 5ed3a09..7130710 100644 --- a/src/connection.h +++ b/src/connection.h @@ -5,6 +5,7 @@ #include "ui_connection.h" #include "precompiled.h" + using json = nlohmann::json; class Controller; diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 17d3fd4..adeeb45 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -1,6 +1,9 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #include "contactmodel.h" #include "addressbook.h" #include "mainwindow.h" +#include "chatmodel.h" void ContactModel::renderContactList(QListView* view) { @@ -12,7 +15,7 @@ void ContactModel::renderContactList(QListView* view) auto theme = Settings::getInstance()->get_theme_name(); if ((theme == "dark" || theme == "midnight")) { - QString avatar = c.getAvatar(); + QString avatar = c.getAvatar(); QStandardItem* Items1 = new QStandardItem(QIcon(avatar) ,c.getName()); contact->appendRow(Items1); @@ -22,10 +25,8 @@ void ContactModel::renderContactList(QListView* view) view->setDragDropMode(QAbstractItemView::DropOnly); view->show(); + } + } - - - - } } \ No newline at end of file diff --git a/src/contactrequest.ui b/src/contactrequest.ui index e2939ee..d2ae8ef 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -11,7 +11,7 @@ - Dialog + Send a contact request diff --git a/src/controller.cpp b/src/controller.cpp index fd1189f..4566827 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #include "controller.h" #include "mainwindow.h" #include "addressbook.h" @@ -6,6 +9,7 @@ #include "camount.h" #include "websockets.h" #include "DataStore.h" + template<> DataStore* DataStore::instance = nullptr; template<> @@ -860,7 +864,8 @@ void Controller::refreshTransactions() { QString memo; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); -} + } + QString cid; QString contact; @@ -876,6 +881,8 @@ void Controller::refreshTransactions() { address, contact, memo, + QString(""), + QString(""), cid, // we have to set the cid here, its included in our Addressbook for this contact txid, true // is an outgoing message @@ -930,37 +937,40 @@ void Controller::refreshTransactions() { QString type; QString cid; + QString requestZaddr1; + QString requestZaddr; + if (memo.startsWith("{")) { type = memo.mid(75,4); cid = memo.mid(14,36); + requestZaddr1 = memo.right(82); + requestZaddr = requestZaddr1.left(78); - qDebug()<addCid(txid, cid); + chatModel->addrequestZaddr(txid, requestZaddr); } - if (type == "cont") - - { - - qDebug()<< "Als Request erkannt"; - - - } - - + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ cid = chatModel->getCidByTx(txid); } - - else{ cid = ""; } + + if (chatModel->getrequestZaddrByTx(txid) != QString("0xdeadbeef")){ + + requestZaddr = chatModel->getrequestZaddrByTx(txid); + + } + + else{ + requestZaddr = ""; + } QString contact; for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) @@ -968,23 +978,23 @@ void Controller::refreshTransactions() { if (address == c.getMyAddress()){ contact = c.getName(); - qDebug()<< "Addressbuch Addresse: " << c.getMyAddress(); - qDebug()<< "Addresse: " << address; }else{ contact = "";} - + } ChatItem item = ChatItem( datetime, address, contact, memo, + requestZaddr, + type, cid, // we have to set the cid here, its included in the headermemo txid, false ); chatModel->addMessage(item); -} + } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5b71245..eb7b244 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,3 +1,5 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #include "mainwindow.h" #include "addressbook.h" #include "viewalladdresses.h" @@ -15,6 +17,8 @@ #include "version.h" #include "connection.h" #include "ui_contactrequest.h" +#include "ui_requestContactDialog.h" +#include "chatmodel.h" #include "requestdialog.h" #include "websockets.h" #include @@ -1006,22 +1010,21 @@ void MainWindow::setupchatTab() { // Is request Contact checked? - if (ui->request->isChecked()) { + // if (ui->request->isChecked()) { QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); // qDebug() <request->isChecked()->text(); - }else{ + // }else{ - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + // QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); - } + // } QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); - -///////// Set selected Zaddr for Chat with Doubleklick +///////// Set selected Zaddr for Chat with Klick QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { @@ -1046,6 +1049,19 @@ void MainWindow::setupchatTab() { } + +/* +void MainWindow::setChatItem(ChatItem * item) +{ + this->currentChatItem = item; +} + +ChatItem* MainWindow::getChatItem() +{ + return this->currentChatItem; +}*/ + + ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); } diff --git a/src/mainwindow.h b/src/mainwindow.h index ee2e5ee..b077593 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -6,6 +6,7 @@ #include "logger.h" #include "recurring.h" + // Forward declare to break circular dependency. class Controller; class Settings; @@ -61,6 +62,10 @@ public: void updateLabels(); void updateTAddrCombo(bool checked); + // void setChatItem(ChatItem* item); + //void ChatItem* getChatItem(); + + // Disable recurring on mainnet void disableRecurring(); @@ -74,6 +79,8 @@ public: QLabel* statusIcon; QLabel* loadingLabel; QWidget* hushdtab; + //ChatItem* currentChatItem; + Logger* logger; @@ -83,8 +90,10 @@ public: public slots: void slot_change_theme(const QString& themeName); void slot_change_currency(const QString& currencyName); + private: + void closeEvent(QCloseEvent* event); void setupSendTab(); @@ -93,6 +102,7 @@ private: void setupBalancesTab(); void setuphushdTab(); void setupchatTab(); + void renderContactRequest(); void setLenDisplayLabel(QLabel* label); void updateContacts(); @@ -147,6 +157,9 @@ private: void restoreSavedStates(); bool eventFilter(QObject *object, QEvent *event); + + + bool uiPaymentsReady = false; QString pendingURIPayment; @@ -154,6 +167,7 @@ private: WormholeClient* wormhole = nullptr; Controller* rpc = nullptr; + QCompleter* labelCompleter = nullptr; QRegExpValidator* amtValidator = nullptr; QRegExpValidator* feesValidator = nullptr; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b5f3539..74739f7 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1414,9 +1414,9 @@ - 30 + 0 640 - 211 + 91 25 @@ -1427,7 +1427,7 @@ - Add conversation contact + Add contact false @@ -1493,6 +1493,19 @@ Is this message a contact request? + + + + 110 + 640 + 191 + 25 + + + + Incoming contact request + + @@ -1667,7 +1680,7 @@ AddressCombo QComboBox -
addresscombo.h
+
addresscombo.h
QRCodeLabel diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui new file mode 100644 index 0000000..b862cda --- /dev/null +++ b/src/requestContactDialog.ui @@ -0,0 +1,355 @@ + + + requestDialog + + + + 0 + 0 + 1011 + 503 + + + + Incoming contact request + + + + + 9 + 9 + 256 + 461 + + + + true + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + QAbstractItemView::SingleSelection + + + + + + 263 + 9 + 741 + 271 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + QListView::Adjust + + + 0 + + + false + + + true + + + + + + 276 + 296 + 101 + 17 + + + + Request from : + + + + + + 393 + 296 + 601 + 25 + + + + + + + 276 + 327 + 30 + 17 + + + + Cid : + + + + + + 393 + 327 + 601 + 25 + + + + + + + 276 + 358 + 71 + 17 + + + + My Zaddr : + + + + + + 393 + 358 + 601 + 25 + + + + + + + 276 + 389 + 68 + 17 + + + + Nickname + + + + + + 393 + 389 + 221 + 25 + + + + + + + 276 + 420 + 228 + 17 + + + + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + + + + + + 510 + 420 + 106 + 25 + + + + + Stag + + + + :/icons/res/Stag.png + + + + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Denio + + + + :/icons/res/Denio.png + + + + + + Duke + + + + :/icons/res/Duke.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + + + + Berg + + + + :/icons/res/Berg.png + + + + + + Sharpee + + + + :/icons/res/Sharpee.png + + + + + + Garfield + + + + :/icons/res/Garfield.png + + + + + + Snoopy + + + + :/icons/res/Snoopy.png + + + + + + Popey + + + + :/icons/res/Popey.png + + + + + + Pinguin + + + + :/icons/res/Pinguin.png + + + + + + Mickey + + + + :/icons/res/Mickey.png + + + + + + SDLogo + + + + :/icons/res/sdlogo2.png + + + + + + + + 300 + 470 + 80 + 25 + + + + + 100 + 0 + + + + Cancel + + + false + + + + + + 400 + 470 + 101 + 25 + + + + Add Contact + + + + + + From 6991743b5f41fb2107a684c2847083e18f923bb7 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 6 May 2020 16:54:15 +0200 Subject: [PATCH 070/253] new Button Design, only for darkmode atm --- application.qrc | 9 +++ res/add_contact.png | Bin 0 -> 1889 bytes res/add_contact.svg | 9 +++ res/addcontact.svg | 7 +++ res/notification.png | Bin 0 -> 1479 bytes res/notification.svg | 10 ++++ res/send-new-white.png | Bin 0 -> 1714 bytes res/send-new.svg | 19 +++++++ res/send.png | Bin 0 -> 4178 bytes res/send.svg | 6 ++ src/controller.cpp | 8 +-- src/mainwindow.cpp | 18 +----- src/mainwindow.ui | 121 +++++++++++++++++++++++++++++------------ 13 files changed, 151 insertions(+), 56 deletions(-) create mode 100644 res/add_contact.png create mode 100644 res/add_contact.svg create mode 100644 res/addcontact.svg create mode 100644 res/notification.png create mode 100644 res/notification.svg create mode 100644 res/send-new-white.png create mode 100644 res/send-new.svg create mode 100644 res/send.png create mode 100644 res/send.svg diff --git a/application.qrc b/application.qrc index 51a4cc4..c93d249 100644 --- a/application.qrc +++ b/application.qrc @@ -23,6 +23,15 @@ res/Pinguin.png res/Stag.png res/Elsa.png + res/send.png + res/send.svg + res/addcontact.svg + res/send-new.svg + res/add_contact.svg + res/notification.svg + res/send-new-white.png + res/add_contact.png + res/notification.png res/hushdlogo.gif diff --git a/res/add_contact.png b/res/add_contact.png new file mode 100644 index 0000000000000000000000000000000000000000..c00a055a21402dca0832a1bf5b8553ba5dde3601 GIT binary patch literal 1889 zcmZ9M3s4hx9>+J2C7T5ygf$@LkLoAg?QkXa%1U1d^DP zKx6=W?IDetpdKwgn%H_wtJr{HK&d#)X&DP@q^JkB#Vbw^5#|0XICs5dGQa+u6;o@$gQZX|C)IK}zj)`4{K9STLy)kc zykV8<3K7wjwZ2H%YSM5@ddQ<9YmH><{2CI!iJo22sGGu<7pm6jBH#hj!Dw4LE3_ap zQU@nJVR*0htNWG7(^>1b1V8R5k>0&iHq_2AZ*3^l42C&I|9<39w|95GGT^enuy^-~ z==Qh2Jd~kMc08E;rmF6XeQC#TO${ACk#c=wz>{ik{C9ENhxZJBzGl#OX>CM4oUv&2 z;wbT`$y=w}u(IMu`@Rg{k(~IC?SBXiu|12?G&RouW3B$Mq3y5*7jlo> z8o!zqc5SRTMc49p$ao{MVjS^+k+B5fj3sgFj7m z%=q@TX+FpuNDsLkmwGM15k8TMfYQ9Mxf>>1^)v@yf8!ufv z@pW6}jhoM()6jW4%eUlASAu)-%T0Mt0nJcfM|;ahKw%fFGIoJ09H4$QnebCR5Lvs` zYm}@J*e`GabH)BVz`>bnMbe-2Km2?rGxd!mjwP+F>t)-}O8oj2#Q$%Vt*tjQpuP5y z-m^IOXQjIR-*i>|VoOr83ZXpyLG>sEvmW7!aPL7{hF7(pwb5L*6ax=YzGtWsx zFoBNr6F~3aphhCjEaP(mfW(vwne_jWUJn<(a=o%yw}BAN1=x}}-l<9>-I$G7RD7Nc z=UOc!!ZhKSfVL+$Z8-FmU}fgw*epX#X-}425g4_v`TAwNH}9UD%POB}%@w<5UE;9T zd|>_D_`KF!8ZV$N%L{&3Yh`+CmDU8D%Sq%7-ZQ9(Y3;W1k_JPBTmO90=(2S-8CIUo z?X}e~M{2r$4aL|!p|(>?W4QJ4yr_J73C|*??cdOKI5e2u6KNY=%IDTgdB@VAvQS`% zHC-VMywsrV8_lj5$M>yaFJUEptgCaBb|w@1o_SL@|H|ch6>&!^S!EDY-F`Sd z+}r)npz2CdV@2sCgYK@KOdMMP$0Y#T?v53q*_(xD*ph;DEym~VlI5&1{Da|&J!a`_ zf^2kO2IWmmyM%@krz^%cl%A6Y*Xj9=3`(k3Y#1J z|1$#r-lssoPk(wG)4WK~_pg;sJnEtL=aUPkvp0L1p{T;MVkaa*396r&-V=h}6To2G zSrzY^Nr>v`xkl<8Y%S(FuIoNHCyi0k&;^jUM|sSoL<-Jy^41-2YCwvybnZfn_i8b4 z;#v%S#F8Y6P|qk$gjyyT_DCKa_wcDJ79{ME(cNIZc|4%^WrhIbgEZ}Yu%|Ecbiy+z zID#UX(4e$+KBEex&jsdq^0m#q3jrmZ7x(y6j{IKom-HUbH zt>>z9oE-np-l)b~SU%9s_e8wxK$_mg7QeH~)1)mcl_WVfF9i8}&8}ESUsGc^$cHyj z@6rE~eQ)MX^m*YIE;?hh3 z_M3EdH7p439%T8Q%)~x{KQV)*3pd^ + + + + + + diff --git a/res/addcontact.svg b/res/addcontact.svg new file mode 100644 index 0000000..1a71008 --- /dev/null +++ b/res/addcontact.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/res/notification.png b/res/notification.png new file mode 100644 index 0000000000000000000000000000000000000000..f746609c5cffa2681e15dfee53173638f8cf0848 GIT binary patch literal 1479 zcmeAS@N?(olHy`uVBq!ia0vp^j~EyjWjNS?tXuyxfD(+Yna<7up3cq+1x5L3nK`Kp z3>p(_C)#=(c91z5ADr#FswqsM@I=5|osKSxEYYq2#VcHEt!BjhQZ&i*2#S$mz24L; z-yO;>o*pY3!|M2f`N+wOo)=xc{=^4m2);g8Xn*f+^_{)UEm;#Y!){9~c)4w6&+#KA zX|6o`lp4xP7R&E7+T0WA>9yeLk6rEk>&pY@UHx@u{$lU5Q9K_yj~JgZ$bD4$Xr=G% z2YdWw(pV!^?bPK=Up5`-j|sP_dpxH+^1;kRK}G(Q~#Y&Aj^lWW2Ky#7;k0bRgOd|{Z%+MV(i+28VZS*46hrNHhv%!VN7u?P z=XdDZ<#mUFz5Rg4yiM1m_UvA~b9?>yE5Cm;a`6_`W+eWp2gVCqlDE4H!+#K5uy^@n zpa^GyM`STD3a^7Oqm#z$3ZNi+iKnkC`x90+J_+5#3#axmFfbqXba4!+xb^m~V_uS@ zfQzI0_x;7c8R8;tJW4MuKT@@1qJ(`qW6}xn+Y#Ao%m39(s<`s)f&8lj46K?iY^)j{ zibfg^j$9KH1-k+}csc`moKieml0=l8l|&W`ND3{KNUx~mIG_}D*wdaTEU*J8dRat3 z$-=jAnw7t4lHr@c&wbs-^c#;brv-;ULA*omk9{Y*J#zSbL0|a>q3Sq>Ih01`0d3T#mVO1pMQ=<^0PG>I(Y5PW=Bu?y%p5rw8b<}M)RN-jO+ z?HW!XwH+Vd3Ak#wDRv1M-jiL#aa6-aQ0driXAwp9BNBp2VDWcSi#RNGk97zbe*0PH zvZ3Re!0H{L9ZFB0NX%W9Ah=dBtgu_a^#re>mG90&U*ccr^UGQIx^@U(&EyihD3v6t zs}$jq-4QwmXv$7gx8<5(-jI+RLr17;NiE+S0cMUUr}mu-O?7} z+Rd?;L$HP8$~@(&x{l|aVuEv)9cU1kyEH*C@ks=SpbjtuB_3V;?!71Aa9E+ukGe&! zEXy?!AuI80<9E+J?I)%++I)#alfxDIv=n#fP;kMG4Pxj0@V*vx+WG9Zi7GekKrvAS zimRuf*gOr2qG`a0NzwsE-H`}BVBBq#0mg2!rHkO9|H(ZZ3+0ntIQ~i~JH0qAA?Rce zjIdvZZY>x34V7BzdIS}}5TWF!{&&ZY1_4}{5txghz)Y0?VEUY2bCvejirdsbzAO&& zm_bMQ0lODl!u|FpWeI`|I#}#t4#YF;3h1~ayO^WZ!_b3~YhqE4l8Dk$jic%=UV&ZwF#Dmj#c}hs(n}}r Sf1{rb67h8Pb6Mw<&;$U?F(3#4 literal 0 HcmV?d00001 diff --git a/res/notification.svg b/res/notification.svg new file mode 100644 index 0000000..3db8333 --- /dev/null +++ b/res/notification.svg @@ -0,0 +1,10 @@ + + + + + + + diff --git a/res/send-new-white.png b/res/send-new-white.png new file mode 100644 index 0000000000000000000000000000000000000000..4c7461c389fb00f80909fa9d0a79bbcfeb5d3d95 GIT binary patch literal 1714 zcmeAS@N?(olHy`uVBq!ia0y~yVAKI(84fm}NG*Hk4IrmA)7d$|)7e>}peR2rGbfdS zL1SX=L|c!;4l+mMgR@;%HH8Tjo(Pz$)6r#-CE69Bc!g`N)r^>5iYA#JK`}C{*PEK< zyF=N<(_>|0SRFqwA31r^^P;QQpZK5*!Pf^1?eE>KzO$FPC2L}4*lmdgFSpI?Iew%h z&6Q`LQbSqEV)?yBn|mTXy%s$Ev8%m*eR<%#tH18dU+jH0iswV;5#uukxsOU8t@OS9 zV2{5{8f&Dgow}Uq%cdj!G2u3KkLQ#}KA4$kJavvTpK$k2wXj(;M16WICRr@XvUa=&va?2JAu?-xYN+MG>HY(+~WM1{$IAO`(2=4z2UQa)< zbV4?BkIZKc$L2S`4*q{ozCA22>5ezo(S`%vk860C55_JCE1dH_`S{AY4FA#}c;)}_ z4o&zq`HPoxw+y50?E^^aB_n0&8dG(T4VSs>=);sVyNBj@O;(v=vw*Z z{0?2ayzVftw;%ABx9NJ+p52RgZm&Oo<@aw!F5aTrjKn|nz<6Ox@^*J&_z!{$_AZ|c z6yYrJh%5$1;dKyZbkdkz0Tg5}@$_|Nf5OVfC&9ien>mAlfn}Yii(^Q|t+%%f^NuQr zxE@qU{U2R6Ysv4_uIdjyuCLWgSPngZef_h|`TM`-6z^j=Hpl;&m)qL`|23K54u8X6N6!OSLAAit@# zqA`I}oMRe@5PQT5HjD#<*;=3&0Tm^RsSpD;45Sv!Y)#-4JJg!c2;_H&11;tdZ(;@V z72`O>pv=Y!PLh}kF<=uw+R&M*5lyU*R3jP+fF@2)kYwiwSBjY5A<+@87LmkusMK`> z3-6KFvl2QbIj)Ny6fzN5m))eArVtm-;(g)4-iK9JxtnJ=TF3lbAZl_%`!eG}A>$J* z-atJ@4~29Ln|<~Gl_?18A%s7Ig?B)Ooz9#%;=Mt@1f=>%kIxPkZbxNd{ewVZpdoPK zJz!zIgG`2}fx-?KjDUs+Z1&sI!{Fkz!C}IWcM*sR^AzDoVgWU|AW!IZeY+4J-^aq*DlF z$RZY?A=4BbfrhAhP2jo;^t{If{;Qz}g;aN#2klJY6xw4QQViq?teOerbX*D9;KJFG zr3N(5$y8J)kZIy9{%HY?0c(G6<8@fV!Y!b6kZGZi4jQwC3oeSu6wqYhhKfR&PAhyI zH#jU2&=JsL;a=#3&IBulh+;AYGzD~^qEM#O3Wp82nG2Z?!W3XKUATbuLli)nLRtB)Jtzcp=0YYG?-dQJn^l7j)NE+sngI+*#>+sN z1iJ_))-&utxtBma2J%3K&zga{N`N+l6@3QUl3*2~1X1)efm0M%K;Z}ZpP6l!m!Am} RyPO76=;`X`vd$@?2>?mlX@UR% literal 0 HcmV?d00001 diff --git a/res/send-new.svg b/res/send-new.svg new file mode 100644 index 0000000..ce2df0a --- /dev/null +++ b/res/send-new.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/res/send.png b/res/send.png new file mode 100644 index 0000000000000000000000000000000000000000..f0fce109a66c1332bbafc5c1abcb952c4d3f4ad2 GIT binary patch literal 4178 zcmV-Y5UuZtP)aoaT0cTXv9nYZ6R)C~o-)i&Tj%K31C4K z>kqy*8erFn4YswR)G~V@P6$)Rv)yHaP8#;3N{ZP;3T!J6z;$>45(mVyPsl`V8A5jj zQTm}UY1>H#ZXq6M!8?i|O%w1Atf0B!IPq^ja{Pj-3W{S(rAKymh^vwrX$qp0wo6anjVR+@Q$7Zk^ZU>%t}@#69K!Lg|idK5aA z3w4|-ktbYS6+Jf2vr#;p9FZqloSD7gSSHXjOT0F{Cl(6I6D``eewRl?9I(Xea&4TUllajlPmZC> zbA03Lp+xRxxs^Y}C_{8&yuN%RO4|MdD*velEiWiR{xg>%h>^VfbLcL*Rm73r$yLvc zAxW8NL4GN!ICTzTtFNy|XU?2K!xGk_rzgdse$y5qm1cvNe=c^C>w0(@s@3sAVmg|$ zaW~p?;xuY&zr_P@Z*NB@Po6}F4jn?Z7cTSA4Wr+b1f+~!>&2vw?u<)~n_%C*PzHSG z2#HTa5otS6!O?2eaTkt z44Xs2Fh+0Kin7Y8(A66)$dX;Ta)p1(w`|#hu3fvve=Rh2wMFne{I6Ge=dFhpZcYj( z^>21{;2*5sjMkMNK^L!HL$<7;p#dE{co5~}BC&+}h9ajwxSbi?RBYZ-!L(jNT` z0krO#Q$Zf&eYvg(``;@!q2!$h(dot}WY4faudAy=Wo2b3J3AX4KYqOPdr6y1?1IO` ze|i!`{5o-@aq;HAE9vN7S+)@+Y~7Ele!hqtHSEu;s;WBQ^wQGOJHG##HpLL3+V~q>6>~N{WelaNnMdj{AWwrI_)-B|eVSj$)$dOLy1qB7@=FOX(-~X|` z!C~l~V{$xF&R^phKd;fX`BPcHbs(B&mr4=#z=Sk3BdZwgs;YzSS37dWus_E^9EQGW z(k*j9# z=M@zdozTTRtO&S*;VNHQyU(a!uIRG>k3fXflAbLy&1V{ z27hi0U9Z=pW5Pkpw$5IR`B*D&y0mLL2ty z7`Q3)&6_u)*49?D-;bYzAyF#@1K$z!;WTfmP`UeIw$ilUiyih$OR^AMun!$Q+kiY_ z#{S#@JvTR(hn|&{g)U#V{E(H^oD~+j(NNC&PJjT9{o1dy_(@m9?M9S3vO)zxjv)C;@1<$8>XD@dw=%d)rEr5qR+k7DfhI({p!a7uQ z;gZ+=xdA#>&KN^4Dk|dTQ}zt+HlCle#OL5U(!7i9*7o@($>!x)xIM{NXTBgx4Vk+f zZ98(pYyR9Cbi8jj$fxYt&dO?0KzB6FYf*0x8oNV2J@5zeWB;j%yn02*98FVGlbJua z1|0`;=l(CBa>Sd#@bR(S%~U=-^d6*tyqRUdR2xXl{Kt^GX-vdjs+CP z&~Y$lET6KQRLkZ{d!w(;mRpgLd%9=m71s#`LP32Se z46Att%v?kSc;h2nxShPE1kPsB9rOnQqTz@Ca4BO`<8IBL8wP%>O`&IGWbo(QoVEOl zDq^4;AK~(k{B|-itxj-S((uE-IBx|iud8>;pId{DgE@TU$rT&7I-5A~c=&}!O|q1$ zPZ4d4k9oIs>Pp!1F?%Z<^5=ML+qTUNIv#uX?zLHQvu4+tTT#&Tg=B&s6E)h>c1|m1 z+MzCtQihANrcXW4^zKwL1@W-E_T@!K5XdB z2i1JXm_f(Kovg{H9I^0}EMmbw5&GHFmio>QCP83{_oj}1P&$<}3+7IrKJ9u{??y9H zO-m#adY^HcD~cXH9xwyne?i8hq^N8A&vs1a6uU0%4)BK$A9gDfn7RKbv2T0d@aRK; z`EF|}+lxfNhinu+W^C`nCh9Ufp_i1DI8<@7WusQ56AQj~*!(P8y804gboBrqHx{z> zVUxIxJak-)xqkh+ThM<2Sy;f-1Y*JW85-=^Q3q=T=k2d|l%#Kp0DsI*cr;7Vei6?iN9}`_}HLx?v*_V?EU&kv@j6d+iwVMQa z+t-(r6TQs$88d&WBTWqxh;7>q6)3DZH~!FTcKzTscw8VN8GP@sx$jB7uV1$DKO+0oc!9B^^Fi@fbe*VD)kypeu$~45Fj? zu`xx?TuksC@lE?Db^`Tz&BFy;E{RYsKemDDcVnVH2+l;>&jJQ z3#8Kh%2>sNMHI)*IHsK+mbjMeXnyqEP!}#KVErX^Q4h2eF-*uy(X05}yDh7`c$w^= zZo+~(MM%hfuH8pNu~|}rZ>-`OxiZaWTa^`srGzi@k<;C~A6{Y|F7dHq!{jW?-)$BA zTXAd1jpQRV=eqrC#3OFqO9N->3M2=AZbw@(9I+Q#IH*~DzLD%LT==|5_ivb_*dbEv zZEH~R;PY>$N3<7j*+VY$ahk@Sua4~QHhBIDGMXut9DE}cPbj_mj^+%nQz_(v9}}e& z?26HVSp5so!~T{O;Tu#u5ve&mbbL^g*nloVbGBD#csGTR1|p4QN%pTdQt_nhJb)7N ziV057s)fB&__hj{5HY5UDxUsO)qCOVrDX2gzlz!pnC?+{!bmuDA+(Bzhz#8XZFBF> zrUfZHW;lmWk`h+{6%X+WTA@t2fb9!Q{uRl>*N_DtDsTsT4j+EM!W#yu-1nt?S&^xV zN3?!@JoU>{A4dczylDV`h1B62t9ZIh6mQQ4#k2R5s>pR!#UnCF)hfVnm%V3$zG#p^-zexlob0mOi;U&;Tx-X zeCE?9XwP{)n6qEIXGco?YEokrk1rzl-e1lds1T!pKy#+#;YX(UBs1st)x6gfVm8?3 zO_e%)V-=6befk8d2}-T6D@ZVCkNPR}#%+@{{JASV@6*R?&Oa5V9;6`20%O@wfPY=e z@bLw}9;~fbKlSmn00oK0chb@_jgp2B*MbNymZZy{{9OIGf@D)_xn9sbaj#_I<68bK z;clVw8>?CU*hiBeR7k->l9TU)iXJU#_%oKc8N|_7`-Vr2^jR9#(|%vFOFs|awHqt? zMraTFjhdrUNZC|zx+meD`fTZ{c#<4n)+bV}06nS4n_oPj=qkpic{NOJS5@)!j#yCA zH*C(cimqrK-8Zeg{Gmtg`mx?9qLe`h16J`?Gy zeiNugJx8j$D`Yc&0B{?Y09tobGAf=4@t6F@#n62|n*2wZupJwq(ft|Ukp?S3Gr3Vd zQx9>>M5TJkLo!ikR{+iWZXNg9>qt4fcY}9X6!XRqbtK_Rw*w9XGERvoC}PKd5l zOLIH09w9`_JtC9xl)>p;to4J0Nf`9$;ow2I;C;}#AF(TfD&%n7|5t|M3*%4s=z}3E zI35y1E8)iEodGm=P9Vtb0W@ \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 4566827..0a0913a 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -874,7 +874,7 @@ void Controller::refreshTransactions() { if (address == c.getPartnerAddress()){ contact = c.getName(); }else{ contact = "";} - } + ChatItem item = ChatItem( datetime, @@ -889,7 +889,7 @@ void Controller::refreshTransactions() { ); chatModel->addMessage(item); - + } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -980,7 +980,7 @@ void Controller::refreshTransactions() { contact = c.getName(); }else{ contact = "";} - } + ChatItem item = ChatItem( datetime, address, @@ -994,7 +994,7 @@ void Controller::refreshTransactions() { ); chatModel->addMessage(item); - + } } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index eb7b244..8385b7a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1013,12 +1013,12 @@ void MainWindow::setupchatTab() { // if (ui->request->isChecked()) { - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); + // QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); // qDebug() <request->isChecked()->text(); // }else{ - // QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); // } @@ -1048,20 +1048,6 @@ void MainWindow::setupchatTab() { } - - -/* -void MainWindow::setChatItem(ChatItem * item) -{ - this->currentChatItem = item; -} - -ChatItem* MainWindow::getChatItem() -{ - return this->currentChatItem; -}*/ - - ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 74739f7..045d7e0 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1332,9 +1332,9 @@ 0 - 40 + 90 341 - 601 + 551 @@ -1354,7 +1354,7 @@ 0 - 20 + 60 341 20 @@ -1392,32 +1392,10 @@ - 720 - 640 - 114 - 25 - - - - - 100 - 0 - - - - Send - - - false - - - - - - 0 - 640 + 1170 + 560 91 - 25 + 81 @@ -1426,11 +1404,28 @@ 0 + + false + - Add contact + + + + + :/icons/res/send-new-white.png + + + + + 61 + 62 + + + + false - false + true @@ -1484,7 +1479,7 @@ 340 - 650 + 640 261 23 @@ -1493,17 +1488,71 @@ Is this message a contact request? + + + + 90 + 0 + 71 + 61 + + + + + 100 + 0 + + + + + + + + :/icons/res/add_contact.png:/icons/res/add_contact.png + + + + 43 + 49 + + + + true + + - 110 - 640 - 191 - 25 + 170 + 0 + 71 + 61 + + + 100 + 0 + + + + false + - Incoming contact request + + + + + :/icons/res/notification.png:/icons/res/notification.png + + + + 43 + 49 + + + + true From 494198995d1d84eb7befcdd92e4f8b6e6492ae76 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 6 May 2020 20:49:48 +0200 Subject: [PATCH 071/253] add notification and different themes to buttons --- src/chatmodel.cpp | 32 +++++++++++++++-------- src/mainwindow.cpp | 29 +++++++++++++++++++++ src/mainwindow.ui | 64 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 100 insertions(+), 25 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b9133b8..d800f95 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -105,8 +105,10 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) }); QStandardItemModel* chat = new QStandardItemModel(); - - + ui->lcdNumber->setStyleSheet("background-color: red"); + ui->lcdNumber->setPalette(Qt::red); + ui->lcdNumber->display("1"); + for (auto &c : this->chatItems) for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { @@ -157,23 +159,32 @@ void ChatModel::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); - for (auto &c : this->chatItems) { + for (auto &c : this->chatItems) + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { + if ((c.second.getType() == "cont") && (c.second.isOutgoing() == false) && (c.second.getMemo().startsWith("{"))) { - + + + + QStandardItem* Items = new QStandardItem(c.second.getAddress()); contactRequest->appendRow(Items); requestContact.requestContact->setModel(contactRequest); - // requestContact.requestContact->show(); + requestContact.requestContact->show(); - + } + + } + + } - } - // } - + + + // } QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { @@ -187,10 +198,11 @@ void ChatModel::renderContactRequest(){ if(c.second.getMemo().startsWith("{")){ }else{ - QStandardItem* Items = new QStandardItem(c.second.getMemo()); + QStandardItem* Items = new QStandardItem(c.second.getMemo()); contactMemo->appendRow(Items); requestContact.requestMemo->setModel(contactMemo); requestContact.requestMemo->show(); + requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestCID->setText(c.second.getCid()); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8385b7a..884a6a7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1018,6 +1018,35 @@ void MainWindow::setupchatTab() { // qDebug() <request->isChecked()->text(); // }else{ + /////////////Setting Icons for Chattab and different themes + + auto theme = Settings::getInstance()->get_theme_name(); + if (theme == "dark" || theme == "midnight") { + QPixmap send(":/icons/res/send-new-white.png"); + QIcon sendIcon(send); + ui->sendChatButton->setIcon(sendIcon); + + QPixmap notification(":/icons/res/notification.png"); + QIcon notificationIcon(notification); + ui->pushContact->setIcon(notificationIcon); + + QPixmap addContact(":/icons/res/add_contact.png"); + QIcon addContactIcon(addContact); + ui->safeContactRequest->setIcon(addContact); + + }else{ + QPixmap pixmap(":/icons/res/send-new.svg"); + QIcon sendIcon(pixmap); + ui->sendChatButton->setIcon(sendIcon); + + QPixmap notification(":/icons/res/notification.svg"); + QIcon notificationIcon(notification); + ui->pushContact->setIcon(notificationIcon); + + QPixmap addContact(":/icons/res/add_contact.svg"); + QIcon addContactIcon(addContact); + ui->safeContactRequest->setIcon(addContact); + } QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); // } diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 045d7e0..85cefa3 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1417,8 +1417,8 @@ - 61 - 62 + 41 + 49 @@ -1479,7 +1479,7 @@ 340 - 640 + 650 261 23 @@ -1491,10 +1491,10 @@ - 90 - 0 - 71 - 61 + 270 + 580 + 51 + 51 @@ -1507,8 +1507,9 @@ - - :/icons/res/add_contact.png:/icons/res/add_contact.png + + :/icons/res/add_contact.png + @@ -1523,10 +1524,10 @@ - 170 - 0 - 71 - 61 + 10 + 30 + 41 + 41 @@ -1547,14 +1548,47 @@ - 43 - 49 + 33 + 35 true + + + + 30 + 20 + 31 + 21 + + + + QFrame::NoFrame + + + 1 + + + QLCDNumber::Flat + + + 0.000000000000000 + + + lcdNumber + listContactWidget + label_39 + memoTxtChat + contactNameMemo + sendChatButton + contactNameMemo_3 + listChat + request + safeContactRequest + pushContact
From 310504285bc605b7276d808f472e98b58d9630d9 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 6 May 2020 22:55:23 +0200 Subject: [PATCH 072/253] add a new button to send contact request, some ui tweaks --- application.qrc | 4 +++ res/message-icon.svg | 9 ++++++ res/rahmen-message.png | Bin 0 -> 2541 bytes res/upload.png | Bin 0 -> 1369 bytes res/upload.svg | 8 +++++ src/chatmodel.cpp | 22 ++++++++++--- src/mainwindow.cpp | 51 ++++++++++++++++------------- src/mainwindow.h | 6 +++- src/mainwindow.ui | 71 +++++++++++++++++++++-------------------- 9 files changed, 108 insertions(+), 63 deletions(-) create mode 100644 res/message-icon.svg create mode 100644 res/rahmen-message.png create mode 100644 res/upload.png create mode 100644 res/upload.svg diff --git a/application.qrc b/application.qrc index c93d249..29a1765 100644 --- a/application.qrc +++ b/application.qrc @@ -32,6 +32,10 @@ res/send-new-white.png res/add_contact.png res/notification.png + res/rahmen-message.png + res/upload.png + res/upload.svg + res/message-icon.svg res/hushdlogo.gif diff --git a/res/message-icon.svg b/res/message-icon.svg new file mode 100644 index 0000000..fe61e44 --- /dev/null +++ b/res/message-icon.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/res/rahmen-message.png b/res/rahmen-message.png new file mode 100644 index 0000000000000000000000000000000000000000..3b486a4b1103542e6c20d7d879a5503405ceaf92 GIT binary patch literal 2541 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe)8TQZ%U13aCb6$*;-(=u~X z85lGs)=sqbIP4&EG(I@nRg14opzuUM=|%;uM=L@#oLU34x4cRydf9$qiK1s=p-2oj zU!6{vY|Na}(gIPIgZu*O?&_}Mnjh;u7rOSaAOBlX{=V=#pTMisWs$PU4a;t)SCwL0T;)q z2Y$!zd~#y4bK`^Mo0a%Bu%(xMUU~D-zBr(E(m}z>SMR<_FeFUd?hZ~y0t^fdKvP&4 z7!-gMBLf2m1A_yQ1x#Vsq#hhE`@+9s)h7wY2T^zL`k`wf)))*M@Y{-^Tmfz|Hb>%7 zj*vnafe>q8AR;74RE`>^qXC2~WkG{=G=PR{0IgpAF0a2axc=m-Q^7mt?|qE%Y`l-9OLu ztbm=NXaB?Y#yw07kMsW=~4kZ3{A)Ge_-|lInaW!;mSkve_*!*BdW(9=z+)lAD;3t=$QR$lP_Qb zY6BXugm3>x_BkN!0w9xFfF?G`0xe_j+y4+E4ph1Fa6ZUVs65z42auK@)4dxC4*!s@ z1M>X;GED!>1@ZzT&_(w_A=Cpj8f4&O{*(ev0g&q%8QOp{!WFCyAAwE-ItWd*(GHf5 zkLG`XGC&&}IrlIf_#s^nvI<$Xyh5{ggGBvdU_==FIVL~jfHsm%K(T*d?>eweXD|eM zRDj_@u>Ap+I7STDpLigokPHeh4u+an>=I{z#y|o|0Tg~i?+8;PquW!pV z@6*b=KbT{VYcm*mT?47;u?Jf9n7;v}{y{W@L>&W`KthD;@lU1>JoacYg0O7$2VDj- srGXB?p&J+)V0Q{E+zopr0NXbpzW@LL literal 0 HcmV?d00001 diff --git a/res/upload.png b/res/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..b6f3c1fc0fe0d3f6b4bef72ec66a3bcd4d3dc2b7 GIT binary patch literal 1369 zcmeAS@N?(olHy`uVBq!ia0vp^w;321WjNS?EI-MEKY*N;OlRi+PiJR^f};Gi%$!sP z291fe6Ky>XJIEZ356*Vg;wuv|5lX0FZ|9Y@G5m#q-=7-vfF7^GX*y9 z6gB+QC154!%A;(wxhK-o>tK1!UF8GUcUzqQWdHs7i@?uf%uGrjd5nE#SIn)*x@>0g zUf4a-GpzG`r@QYig^$YDMf>kth{uXmq+L0)03F=@2AtX zvGzaY|Gc}V<mW zgs+r-@IXL9FX-E>^SgK7s{Z}mXY+pfqN7F2cV#rC0HcL1$=lt9;Xep2*t>i(P=vF< zBeED6gV#Zr(Me-=1yGQ^#M9T6{Ru0Zh#KGI!)@XW49sDkE{-7;x8B~}$jfZV!{Rvi z_xs4cn5Oe}MQTA>T-;3aYxw$$-tV1XJZZ*>;)*rxZE6-919^N4k`_zMdT_+e(Bxoe zZ&F5+u=LRjEb3-m3pxFAM4W}^+|a#23w$Lv5^yGzEqPiL;$4K z8DgQD3DgN-t!)pWW^v?&Lrgz*>46ehiJ{gG4zQ^`TzX*5Qj43qF9-k~aBKyBC3hYH z)f@q-*=}IA(9jZOj&7H4Mh*waAa0<$W`j(+^8l#q7)Y5pP}xSXvQnVL0^yhzwz)v@ z7cAln9o2!ltq!_oT;SAmYW6D-lq#XF5?OuahD&9)s|uz6+S^Ip$Z5FY0LBVt4ml7k zAgy2q!5zE;(hz)vt%DbWlbDaNLGVV#BxW#fyuq*$f+0qMjHIz~z+{gDJfBkxOxed6 r?mzzzbOh8NXE|UlBE@s4HvF*8f8(*Ycx^~XAV|W~)z4*}Q$iB}e1!gF literal 0 HcmV?d00001 diff --git a/res/upload.svg b/res/upload.svg new file mode 100644 index 0000000..9f31b60 --- /dev/null +++ b/res/upload.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index d800f95..6c426be 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -155,7 +155,7 @@ void ChatModel::renderContactRequest(){ requestContact.setupUi(&dialog); Settings::saveRestore(&dialog); - { + /* { QStandardItemModel* contactRequest = new QStandardItemModel(); @@ -183,8 +183,7 @@ void ChatModel::renderContactRequest(){ } - - // } + QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { @@ -228,7 +227,7 @@ void ChatModel::renderContactRequest(){ qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); }); - + */ dialog.exec(); } @@ -476,7 +475,7 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); if (available < total) { - return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") + return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 3 confirmations before they can be spent") .arg(available.toDecimalhushString(), total.toDecimalhushString()); } @@ -601,6 +600,18 @@ Tx MainWindow::createTxForSafeContactRequest() { void MainWindow::ContactRequest() { + if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { + + // auto addr = ""; + // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), + tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), + QMessageBox::Ok, this); + + msg.exec(); + return; + } + Tx tx = createTxForSafeContactRequest(); QString error = doSendRequestTxValidations(tx); @@ -659,6 +670,7 @@ void MainWindow::ContactRequest() { // Force a UI update so we get the unconfirmed Tx // rpc->refresh(true); ui->memoTxtChat->clear(); + rpc->refresh(true); }, // Errored out diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 884a6a7..a691a56 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,4 +1,4 @@ -// Copyright 2019-2020 The Hush developers +// Copyright 2019-2020 The Hush developers // GPLv3 #include "mainwindow.h" #include "addressbook.h" @@ -44,7 +44,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); - ui->request->setChecked(false); + logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); ui->memoTxtChat->setAutoFillBackground(false); ui->memoTxtChat->setPlaceholderText("Send Message"); @@ -1005,22 +1005,10 @@ void MainWindow::setupTransactionsTab() { } void MainWindow::setupchatTab() { + + /////////////Setting Icons for Chattab and different themes -// Send button - - // Is request Contact checked? - - // if (ui->request->isChecked()) { - - - // QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); - - // qDebug() <request->isChecked()->text(); - // }else{ - - /////////////Setting Icons for Chattab and different themes - - auto theme = Settings::getInstance()->get_theme_name(); + auto theme = Settings::getInstance()->get_theme_name(); if (theme == "dark" || theme == "midnight") { QPixmap send(":/icons/res/send-new-white.png"); QIcon sendIcon(send); @@ -1032,8 +1020,15 @@ void MainWindow::setupchatTab() { QPixmap addContact(":/icons/res/add_contact.png"); QIcon addContactIcon(addContact); - ui->safeContactRequest->setIcon(addContact); + ui->safeContactRequest->setIcon(addContactIcon); + /*QPixmap rahmen(":/icons/res/rahmen-message.png"); + QIcon addRahmenIcon(rahmen); + ui->lcdNumber->setIcon(addRahmenIcon);*/ + + QPixmap sendContact(":/icons/res/upload.png"); + QIcon addSendContactIcon(sendContact); + ui->sendContact->setIcon(addSendContactIcon); }else{ QPixmap pixmap(":/icons/res/send-new.svg"); QIcon sendIcon(pixmap); @@ -1046,11 +1041,21 @@ void MainWindow::setupchatTab() { QPixmap addContact(":/icons/res/add_contact.svg"); QIcon addContactIcon(addContact); ui->safeContactRequest->setIcon(addContact); - } - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); - // } - + /*QPixmap rahmen(":/icons/res/message-icon.svg"); + QIcon addRahmenIcon(rahmen); + ui->lcdNumber->setIcon(addRahmenIcon);*/ + + QPixmap sendContact(":/icons/res/upload.svg"); + QIcon addSendContactIcon(sendContact); + ui->sendContact->setIcon(addSendContactIcon); + } + + + + + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + QObject::connect(ui->sendContact, &QPushButton::clicked, this, &MainWindow::ContactRequest); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); ///////// Set selected Zaddr for Chat with Klick @@ -1549,4 +1554,4 @@ MainWindow::~MainWindow() delete wsserver; delete wormhole; -} +} \ No newline at end of file diff --git a/src/mainwindow.h b/src/mainwindow.h index b077593..54f9dc8 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -92,10 +92,14 @@ public slots: void slot_change_currency(const QString& currencyName); -private: +private slots: + + +private: void closeEvent(QCloseEvent* event); + void setupSendTab(); void setupTransactionsTab(); void setupReceiveTab(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 85cefa3..6be3969 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1360,7 +1360,7 @@ - <html><head/><body><p align="center">Hushchat Contactlist</p></body></html> + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> @@ -1438,7 +1438,7 @@ - <html><head/><body><p align="center">Contact Name:</p></body></html> + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> @@ -1475,19 +1475,6 @@ true - - - - 340 - 650 - 261 - 23 - - - - Is this message a contact request? - - @@ -1578,6 +1565,39 @@ 0.000000000000000 + + + + 270 + 510 + 51 + 51 + + + + + 100 + 0 + + + + + + + + :/icons/res/add_contact.png + + + + + 43 + 49 + + + + true + + lcdNumber listContactWidget label_39 @@ -1586,9 +1606,9 @@ sendChatButton contactNameMemo_3 listChat - request safeContactRequest pushContact + sendContact
@@ -1799,22 +1819,5 @@ - - - request - stateChanged(int) - MainWindow - update() - - - 481 - 721 - - - 636 - 389 - - - - + From 9600242e7055542713c0441419037f96e91b338e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 7 May 2020 21:24:51 +0200 Subject: [PATCH 073/253] fix icon and background problem on mac/win --- silentdragon-lite.pro | 2 +- src/addressbook.cpp | 2 +- src/chatmodel.cpp | 2 +- src/contactmodel.cpp | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index a3364d2..5e32f1e 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -12,7 +12,7 @@ PRECOMPILED_HEADER = src/precompiled.h QT += widgets QT += websockets -QT += qml quick + TARGET = SilentDragonLite diff --git a/src/addressbook.cpp b/src/addressbook.cpp index a16d7c8..298b057 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -173,7 +173,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString cid = ab.cid->text(); - QString avatar = QString("res/") + ab.comboBoxAvatar->currentText() + QString(".png"); + QString avatar = QString(":/icons/res/") + ab.comboBoxAvatar->currentText() + QString(".png"); qDebug()<<"AVATAR NAME : " << avatar; if (addr.isEmpty() || newLabel.isEmpty()) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 6c426be..c8ab957 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -510,7 +510,7 @@ void::MainWindow::addContact() { QString newLabel = request.labelRequest->text().trimmed(); auto myAddr = request.myzaddr->text().trimmed(); - QString avatar = QString("res/") + request.comboBoxAvatar->currentText() + QString(".png"); + QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); if (addr.isEmpty() || newLabel.isEmpty()) { diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index adeeb45..41b7758 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -17,7 +17,8 @@ void ContactModel::renderContactList(QListView* view) QString avatar = c.getAvatar(); - QStandardItem* Items1 = new QStandardItem(QIcon(avatar) ,c.getName()); + QStandardItem* Items1 = new QStandardItem(c.getName()); + Items1->setData(QIcon(avatar),Qt::DecorationRole); contact->appendRow(Items1); view->setModel(contact); view->setIconSize(QSize(60,70)); From 8183b245c6c53ac9480194e4547ed373bd362b9f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 7 May 2020 21:57:47 +0200 Subject: [PATCH 074/253] add a first Button for a new HushChat Address on chattab --- src/addressbook.cpp | 7 ++++--- src/chatmodel.cpp | 10 ++++++---- src/mainwindow.cpp | 13 ++++++++++++- src/mainwindow.h | 2 ++ src/mainwindow.ui | 27 +++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 298b057..ce706d0 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -212,10 +212,11 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ////// We need a better popup here. AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid,avatar); - QMessageBox::critical( + + QMessageBox::information( parent, - QObject::tr("Add Successfully"), - QObject::tr("juhu").arg(newLabel), + QObject::tr("Added Contact"), + QObject::tr("successfully added your new contact").arg(newLabel), QMessageBox::Ok ); return; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c8ab957..34be5c0 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -535,12 +535,14 @@ void::MainWindow::addContact() { return; } - ////// We need a better popup here. + ///////Todo: Test if label allready exist! + + ////// Success, so show it AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::critical( + QMessageBox::information( this, - QObject::tr("Add Successfully"), - QObject::tr("juhu").arg(newLabel), + QObject::tr("Added Contact"), + QObject::tr("successfully added your new contact").arg(newLabel), QMessageBox::Ok ); return; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a691a56..ed4bb95 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1554,4 +1554,15 @@ MainWindow::~MainWindow() delete wsserver; delete wormhole; -} \ No newline at end of file +} +void MainWindow::on_givemeZaddr_clicked() +{ + + bool sapling = true; + rpc->createNewZaddr(sapling, [=] (json reply) { + QString hushchataddr = QString::fromStdString(reply.get()[0]); + QMessageBox::information(this, "Your new Hushchataddress",hushchataddr); + // ui->listReceiveAddresses->insertItem(0, hushchataddr); + // ui->listReceiveAddresses->setCurrentIndex(0); + }); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 54f9dc8..9e91245 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -95,6 +95,8 @@ public slots: private slots: + void on_givemeZaddr_clicked(); + private: void closeEvent(QCloseEvent* event); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 6be3969..2c1adc6 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1598,6 +1598,32 @@ true + + + + 80 + 10 + 211 + 41 + + + + New HushChat Address + + + + :/icons/res/message-icon.svg:/icons/res/message-icon.svg + + + + 33 + 29 + + + + true + + lcdNumber listContactWidget label_39 @@ -1609,6 +1635,7 @@ safeContactRequest pushContact sendContact + givemeZaddr
From 4305980b278f77c9d00608b2f6a7b5615e948f85 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 7 May 2020 22:03:25 +0200 Subject: [PATCH 075/253] add information box for contact request --- src/chatmodel.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 34be5c0..c3503b9 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -155,7 +155,7 @@ void ChatModel::renderContactRequest(){ requestContact.setupUi(&dialog); Settings::saveRestore(&dialog); - /* { + { QStandardItemModel* contactRequest = new QStandardItemModel(); @@ -222,12 +222,17 @@ void ChatModel::renderContactRequest(){ QString newLabel = requestContact.requestLabel->text().trimmed(); auto myAddr = requestContact.requestMyAddr->text().trimmed(); - QString avatar = QString("res/") + requestContact.comboBoxAvatar->currentText() + QString(".png"); + QString avatar = QString(":/icons/res/") + requestContact.comboBoxAvatar->currentText() + QString(".png"); qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); + + QMessageBox::information(main, "Added Contact","successfully added your new contact. You can now Chat with this contact"); + + + }); - */ + dialog.exec(); } From 4011c3950985355b220f7f17acd2e9534a0a84c9 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 7 May 2020 22:17:20 +0200 Subject: [PATCH 076/253] fix --- src/chatmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c3503b9..65d5c3e 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -160,7 +160,7 @@ void ChatModel::renderContactRequest(){ for (auto &c : this->chatItems) - for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { + { if ((c.second.getType() == "cont") && (c.second.isOutgoing() == false) && (c.second.getMemo().startsWith("{"))) { From b3d41bbb43783777e683aa98c9c994f369ae3d8b Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 7 May 2020 22:38:19 +0200 Subject: [PATCH 077/253] some ui tweaks --- src/chatmodel.cpp | 6 +- src/mainwindow.cpp | 12 +- src/mainwindow.ui | 283 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 248 insertions(+), 53 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 65d5c3e..98bb0f8 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -105,9 +105,9 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) }); QStandardItemModel* chat = new QStandardItemModel(); - ui->lcdNumber->setStyleSheet("background-color: red"); - ui->lcdNumber->setPalette(Qt::red); - ui->lcdNumber->display("1"); + // ui->lcdNumber->setStyleSheet("background-color: red"); + // ui->lcdNumber->setPalette(Qt::red); + // ui->lcdNumber->display("1"); for (auto &c : this->chatItems) for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ed4bb95..694178f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1022,9 +1022,9 @@ void MainWindow::setupchatTab() { QIcon addContactIcon(addContact); ui->safeContactRequest->setIcon(addContactIcon); - /*QPixmap rahmen(":/icons/res/rahmen-message.png"); - QIcon addRahmenIcon(rahmen); - ui->lcdNumber->setIcon(addRahmenIcon);*/ + QPixmap newAddr(":/icons/res/add_contact.png"); + QIcon addnewAddrIcon(newAddr); + ui->givemeZaddr->setIcon(addnewAddrIcon); QPixmap sendContact(":/icons/res/upload.png"); QIcon addSendContactIcon(sendContact); @@ -1042,9 +1042,9 @@ void MainWindow::setupchatTab() { QIcon addContactIcon(addContact); ui->safeContactRequest->setIcon(addContact); - /*QPixmap rahmen(":/icons/res/message-icon.svg"); - QIcon addRahmenIcon(rahmen); - ui->lcdNumber->setIcon(addRahmenIcon);*/ + QPixmap newAddr(":/icons/res/add_contact.svg"); + QIcon addnewAddrIcon(newAddr); + ui->givemeZaddr->setIcon(addnewAddrIcon); QPixmap sendContact(":/icons/res/upload.svg"); QIcon addSendContactIcon(sendContact); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 2c1adc6..08e1d4d 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1332,9 +1332,9 @@ 0 - 90 + 120 341 - 551 + 521 @@ -1354,7 +1354,7 @@ 0 - 60 + 100 341 20 @@ -1379,12 +1379,18 @@ - 450 + 460 20 161 20 + + + 75 + true + + <html><head/><body><p align="center"><br/></p></body></html> @@ -1543,28 +1549,6 @@ true - - - - 30 - 20 - 31 - 21 - - - - QFrame::NoFrame - - - 1 - - - QLCDNumber::Flat - - - 0.000000000000000 - - @@ -1601,41 +1585,252 @@ - 80 - 10 - 211 + 60 + 30 + 111 41 - New HushChat Address + New Addr - :/icons/res/message-icon.svg:/icons/res/message-icon.svg + :/icons/res/add_contact.png:/icons/res/add_contact.png 33 - 29 + 35 true - lcdNumber - listContactWidget - label_39 - memoTxtChat - contactNameMemo - sendChatButton - contactNameMemo_3 - listChat - safeContactRequest - pushContact - sendContact - givemeZaddr + + + + 40 + 20 + 21 + 16 + + + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 239 + 41 + 41 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 239 + 41 + 41 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + + + 190 + 190 + 190 + + + + + + + 190 + 190 + 190 + + + + + + + 239 + 41 + 41 + + + + + + + 190 + 190 + 190 + + + + + + + 204 + 0 + 0 + + + + + + + 204 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 12 + + + + Qt::LeftToRight + + + 1 + + + Qt::AutoText + + From 203588a59ba9c505342c35726dd306f676a92e09 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 8 May 2020 18:51:16 +0200 Subject: [PATCH 078/253] fix Addressbook --- src/addressbook.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index ce706d0..d00c3ae 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -10,7 +10,7 @@ AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) { - headers << tr("Label") << tr("Address") << tr("HushChatAddress") << tr("CID"); + headers << tr("Avatar")<< tr("Label") << tr("Address") << tr("HushChatAddress") << tr("CID"); this->parent = parent; loadData(); } From d599bf91902995441f74f803f0854be53f22a1ca Mon Sep 17 00:00:00 2001 From: maxisman Date: Fri, 8 May 2020 19:10:59 +0200 Subject: [PATCH 079/253] update// moved datastore to DataStore/DataStore.h --- src/{ => DataStore}/DataStore.h | 0 src/controller.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{ => DataStore}/DataStore.h (100%) diff --git a/src/DataStore.h b/src/DataStore/DataStore.h similarity index 100% rename from src/DataStore.h rename to src/DataStore/DataStore.h diff --git a/src/controller.cpp b/src/controller.cpp index 0a0913a..6ab187d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -8,7 +8,7 @@ #include "version.h" #include "camount.h" #include "websockets.h" -#include "DataStore.h" +#include "DataStore/DataStore.h" template<> DataStore* DataStore::instance = nullptr; From 2e8b46c863205799ce10180b8e1d58f88d1832a1 Mon Sep 17 00:00:00 2001 From: maxisman Date: Fri, 8 May 2020 19:39:16 +0200 Subject: [PATCH 080/253] update// changed datastore to factory pattern to get only the desired datastores --- src/DataStore/ChatDataStore.h | 64 ++++++++++++++++++++++++++++ src/DataStore/DataStore-deprecated.h | 58 +++++++++++++++++++++++++ src/DataStore/DataStore.h | 59 +++++-------------------- src/DataStore/SietchDataStore.h | 63 +++++++++++++++++++++++++++ src/controller.cpp | 6 +-- 5 files changed, 199 insertions(+), 51 deletions(-) create mode 100644 src/DataStore/ChatDataStore.h create mode 100644 src/DataStore/DataStore-deprecated.h create mode 100644 src/DataStore/SietchDataStore.h diff --git a/src/DataStore/ChatDataStore.h b/src/DataStore/ChatDataStore.h new file mode 100644 index 0000000..84291fc --- /dev/null +++ b/src/DataStore/ChatDataStore.h @@ -0,0 +1,64 @@ +#ifndef DATASTORE_H +#define DATASTORE_H + +using json = nlohmann::json; + +class ChatDataStore +{ + private: + static bool instanced; + static ChatDataStore* instance; + std::map data; + ChatDataStore() + { + + } + + public: + static ChatDataStore* getInstance() + { + if(!ChatDataStore::instanced) + { + ChatDataStore::instanced = true; + ChatDataStore::instance = new ChatDataStore(); + } + + return ChatDataStore::instance; + } + + void clear(); + void setData(QString key, ChatItem value); + ChatItem getData(QString key); + QString dump(); + + ~ChatDataStore() + { + ChatDataStore::instanced = false; + } +}; + +void ChatDataStore::clear() +{ + this->data.clear(); +} + + +void ChatDataStore:setData(QString key, ChatItem value) +{ + this->data[key] = value; +} + +ChatItem ChatDataStore::getData(QString key) +{ + return this->data[key]; +} + +QString ChatDataStore::dump() +{ + return ""; +} + +ChatDataStore* ChatDataStore::instance = nullptr; +bool ChatDataStore::instanced = false; + +#endif \ No newline at end of file diff --git a/src/DataStore/DataStore-deprecated.h b/src/DataStore/DataStore-deprecated.h new file mode 100644 index 0000000..19daa1b --- /dev/null +++ b/src/DataStore/DataStore-deprecated.h @@ -0,0 +1,58 @@ +#ifndef DATASTORE_H +#define DATASTORE_H + +#include +#include + +template +class DataStore +{ + private: + static bool instanced; + static DataStore* instance; + std::map data; + DataStore() + { + + } + + public: + static DataStore* getInstance() + { + if(!DataStore::instanced) + { + DataStore::instanced = true; + DataStore::instance = new DataStore(); + } + + return DataStore::instance; + } + + void clear(); + void setData(QString key, T value); + QString getData(QString key); + + ~DataStore() + { + DataStore::instanced = false; + } +}; + +template +void DataStore::clear() +{ + this->data.clear(); +} + +template +void DataStore::setData(QString key, T value) +{ + this->data[key] = value; +} + +template +QString DataStore::getData(QString key) +{ + return this->data[key]; +} +#endif \ No newline at end of file diff --git a/src/DataStore/DataStore.h b/src/DataStore/DataStore.h index 19daa1b..0aa8a09 100644 --- a/src/DataStore/DataStore.h +++ b/src/DataStore/DataStore.h @@ -1,58 +1,21 @@ #ifndef DATASTORE_H #define DATASTORE_H -#include -#include +#include "SietchDataStore.h" +#include "ChatDataStore.h" -template class DataStore { - private: - static bool instanced; - static DataStore* instance; - std::map data; - DataStore() - { +public: + static SietchDataStore* getSietchDataStore() + { + return SietchDataStore::getInstance(); + } - } - - public: - static DataStore* getInstance() - { - if(!DataStore::instanced) - { - DataStore::instanced = true; - DataStore::instance = new DataStore(); - } - - return DataStore::instance; - } - - void clear(); - void setData(QString key, T value); - QString getData(QString key); - - ~DataStore() - { - DataStore::instanced = false; - } -}; - -template -void DataStore::clear() -{ - this->data.clear(); + static ChatDataStore* getChatDataStore() + { + return ChatDataStore::getInstance(); + } } -template -void DataStore::setData(QString key, T value) -{ - this->data[key] = value; -} - -template -QString DataStore::getData(QString key) -{ - return this->data[key]; -} #endif \ No newline at end of file diff --git a/src/DataStore/SietchDataStore.h b/src/DataStore/SietchDataStore.h new file mode 100644 index 0000000..8739340 --- /dev/null +++ b/src/DataStore/SietchDataStore.h @@ -0,0 +1,63 @@ +#ifndef SietchDataStore_H +#define SietchDataStore_H + +using json = nlohmann::json; + +class SietchDataStore +{ + private: + static bool instanced; + static SietchDataStore* instance; + std::map data; + SietchDataStore() + { + + } + + public: + static SietchDataStore* getInstance() + { + if(!SietchDataStore::instanced) + { + SietchDataStore::instanced = true; + SietchDataStore::instance = new SietchDataStore(); + } + + return SietchDataStore::instance; + } + + void clear(); + void setData(QString key, QString value); + QString getData(QString key); + QString dump(); + + ~ChatDataStore() + { + ChatDataStore::instanced = false; + } +}; + +void SietchDataStore::clear() +{ + this->data.clear(); +} + +void SietchDataStore::setData(QString key, QString value) +{ + this->data[key] = value; +} + +QString SietchDataStore::getData(QString key) +{ + return this->data[key]; +} + +QString ChatDataStore::dump() +{ + return ""; +} + +ChatDataStore* ChatDataStore::instance = nullptr; +bool ChatDataStore::instanced = false; + +#endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 6ab187d..1228e55 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -97,7 +97,7 @@ void Controller::setConnection(Connection* c) { zrpc->createNewSietchZaddr( [=] (json reply) { QString zdust = QString::fromStdString(reply.get()[0]); - DataStore::getInstance()->setData("Sietch" + QString(i), zdust.toUtf8()); + DataStore::getSietchDataStore()->setData("Sietch" + QString(i), zdust.toUtf8()); }); } } @@ -120,7 +120,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) { zrpc->createNewSietchZaddr( [=] (json reply) { QString zdust = QString::fromStdString(reply.get()[0]); - DataStore::getInstance()->setData(QString("Sietch") + QString(i), zdust.toUtf8()); + DataStore::getSietchDataStore()->setData(QString("Sietch") + QString(i), zdust.toUtf8()); } ); } @@ -128,7 +128,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) // Using DataStore singelton, to store the data into the dusts, bing bada boom :D for(uint8_t i = 0; i < 10; i++) { - dust.at(i)["address"] = DataStore::getInstance()->getData(QString("Sietch" + QString(i))).toStdString(); + dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString(); } DataStore::getInstance()->clear(); // clears the datastore From d0562d2c652dfad6da658248307685b779e5c879 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Fri, 8 May 2020 20:01:57 +0200 Subject: [PATCH 081/253] update// added ChatDataStore and SietchDataStore with factory-pattern --- src/DataStore/ChatDataStore.h | 19 ++++++++++--------- src/DataStore/DataStore.h | 21 ++++++++++++--------- src/DataStore/SietchDataStore.h | 15 ++++++++------- src/controller.cpp | 6 +++--- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/DataStore/ChatDataStore.h b/src/DataStore/ChatDataStore.h index 84291fc..82651fd 100644 --- a/src/DataStore/ChatDataStore.h +++ b/src/DataStore/ChatDataStore.h @@ -1,5 +1,5 @@ -#ifndef DATASTORE_H -#define DATASTORE_H +#ifndef CHATDATASTORE_H +#define CHATDATASTORE_H using json = nlohmann::json; @@ -15,15 +15,15 @@ class ChatDataStore } public: - static ChatDataStore* getInstance() + static ChatDataStore* getInstance() { - if(!ChatDataStore::instanced) + if(!ChatDataStore::instanced) { - ChatDataStore::instanced = true; - ChatDataStore::instance = new ChatDataStore(); + ChatDataStore::instanced = true; + ChatDataStore::instance = new ChatDataStore(); } - return ChatDataStore::instance; + return ChatDataStore::instance; } void clear(); @@ -33,7 +33,8 @@ class ChatDataStore ~ChatDataStore() { - ChatDataStore::instanced = false; + ChatDataStore::instanced = false; + ChatDataStore::instance = nullptr; } }; @@ -43,7 +44,7 @@ void ChatDataStore::clear() } -void ChatDataStore:setData(QString key, ChatItem value) +void ChatDataStore::setData(QString key, ChatItem value) { this->data[key] = value; } diff --git a/src/DataStore/DataStore.h b/src/DataStore/DataStore.h index 0aa8a09..6c006b0 100644 --- a/src/DataStore/DataStore.h +++ b/src/DataStore/DataStore.h @@ -6,16 +6,19 @@ class DataStore { -public: - static SietchDataStore* getSietchDataStore() - { - return SietchDataStore::getInstance(); - } + public: + static SietchDataStore* getSietchDataStore(); + static ChatDataStore* getChatDataStore(); +}; - static ChatDataStore* getChatDataStore() - { - return ChatDataStore::getInstance(); - } +SietchDataStore* DataStore::getSietchDataStore() +{ + return SietchDataStore::getInstance(); +} + +ChatDataStore* DataStore::getChatDataStore() +{ + return ChatDataStore::getInstance(); } #endif \ No newline at end of file diff --git a/src/DataStore/SietchDataStore.h b/src/DataStore/SietchDataStore.h index 8739340..c94c76f 100644 --- a/src/DataStore/SietchDataStore.h +++ b/src/DataStore/SietchDataStore.h @@ -1,5 +1,5 @@ -#ifndef SietchDataStore_H -#define SietchDataStore_H +#ifndef SIETCHDATASTORE_H +#define SIETCHDATASTORE_H using json = nlohmann::json; @@ -31,9 +31,10 @@ class SietchDataStore QString getData(QString key); QString dump(); - ~ChatDataStore() + ~SietchDataStore() { - ChatDataStore::instanced = false; + SietchDataStore::instanced = false; + SietchDataStore::instance = nullptr; } }; @@ -52,12 +53,12 @@ QString SietchDataStore::getData(QString key) return this->data[key]; } -QString ChatDataStore::dump() +QString SietchDataStore::dump() { return ""; } -ChatDataStore* ChatDataStore::instance = nullptr; -bool ChatDataStore::instanced = false; +SietchDataStore* SietchDataStore::instance = nullptr; +bool SietchDataStore::instanced = false; #endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 1228e55..ac6b603 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -10,10 +10,10 @@ #include "websockets.h" #include "DataStore/DataStore.h" -template<> +/*template<> DataStore* DataStore::instance = nullptr; template<> -bool DataStore::instanced = false; +bool DataStore::instanced = false;*/ ChatModel *chatModel = new ChatModel(); ContactModel *contactModel = new ContactModel(); @@ -131,7 +131,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString(); } - DataStore::getInstance()->clear(); // clears the datastore + DataStore::getSietchDataStore()->clear(); // clears the datastore // Dust amt/memo, construct the JSON for(uint8_t i = 0; i < 10; i++) From 30ddc479ba80650bebd5147c8d973833bf4d3434 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Fri, 8 May 2020 21:16:40 +0200 Subject: [PATCH 082/253] update// reformated datastore and changed storage chatmodel to store with datastore --- silentdragon-lite.pro | 5 +++- src/DataStore/ChatDataStore.cpp | 42 +++++++++++++++++++++++++++++++ src/DataStore/ChatDataStore.h | 37 +++------------------------ src/DataStore/DataStore.cpp | 11 ++++++++ src/DataStore/DataStore.h | 10 -------- src/DataStore/SietchDataStore.cpp | 35 ++++++++++++++++++++++++++ src/DataStore/SietchDataStore.h | 35 +------------------------- src/chatmodel.cpp | 7 +++--- src/chatmodel.h | 2 -- src/controller.cpp | 7 +++--- src/controller.h | 1 - 11 files changed, 104 insertions(+), 88 deletions(-) create mode 100644 src/DataStore/ChatDataStore.cpp create mode 100644 src/DataStore/DataStore.cpp create mode 100644 src/DataStore/SietchDataStore.cpp diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 5e32f1e..c09eea7 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -71,7 +71,10 @@ SOURCES += \ src/chatbubbleme.cpp \ src/chatbubblepartner.cpp \ src/chatmodel.cpp \ - src/contactmodel.cpp + src/contactmodel.cpp \ + src/DataStore/DataStore.cpp \ + src/DataStore/ChatDataStore.cpp \ + src/DataStore/SietchDataStore.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp new file mode 100644 index 0000000..d3a79e4 --- /dev/null +++ b/src/DataStore/ChatDataStore.cpp @@ -0,0 +1,42 @@ +#include "ChatDataStore.h" + +ChatDataStore* ChatDataStore::getInstance() +{ + if(!ChatDataStore::instanced) + { + ChatDataStore::instanced = true; + ChatDataStore::instance = new ChatDataStore(); + } + + return ChatDataStore::instance; +} + +void ChatDataStore::clear() +{ + this->data.clear(); +} + + +void ChatDataStore::setData(QString key, ChatItem value) +{ + this->data[key] = value; +} + +ChatItem ChatDataStore::getData(QString key) +{ + return this->data[key]; +} + +QString ChatDataStore::dump() +{ + return ""; +} + +std::map ChatDataStore::getAllRawChatItems() +{ + return this->data; +} + + +ChatDataStore* ChatDataStore::instance = nullptr; +bool ChatDataStore::instanced = false; \ No newline at end of file diff --git a/src/DataStore/ChatDataStore.h b/src/DataStore/ChatDataStore.h index 82651fd..85fd4b9 100644 --- a/src/DataStore/ChatDataStore.h +++ b/src/DataStore/ChatDataStore.h @@ -1,6 +1,6 @@ #ifndef CHATDATASTORE_H #define CHATDATASTORE_H - +#include "../chatmodel.h" using json = nlohmann::json; class ChatDataStore @@ -15,20 +15,11 @@ class ChatDataStore } public: - static ChatDataStore* getInstance() - { - if(!ChatDataStore::instanced) - { - ChatDataStore::instanced = true; - ChatDataStore::instance = new ChatDataStore(); - } - - return ChatDataStore::instance; - } - + static ChatDataStore* getInstance(); void clear(); void setData(QString key, ChatItem value); ChatItem getData(QString key); + std::map getAllRawChatItems(); QString dump(); ~ChatDataStore() @@ -38,28 +29,6 @@ class ChatDataStore } }; -void ChatDataStore::clear() -{ - this->data.clear(); -} -void ChatDataStore::setData(QString key, ChatItem value) -{ - this->data[key] = value; -} - -ChatItem ChatDataStore::getData(QString key) -{ - return this->data[key]; -} - -QString ChatDataStore::dump() -{ - return ""; -} - -ChatDataStore* ChatDataStore::instance = nullptr; -bool ChatDataStore::instanced = false; - #endif \ No newline at end of file diff --git a/src/DataStore/DataStore.cpp b/src/DataStore/DataStore.cpp new file mode 100644 index 0000000..d16c255 --- /dev/null +++ b/src/DataStore/DataStore.cpp @@ -0,0 +1,11 @@ +#include "DataStore.h" + +SietchDataStore* DataStore::getSietchDataStore() +{ + return SietchDataStore::getInstance(); +} + +ChatDataStore* DataStore::getChatDataStore() +{ + return ChatDataStore::getInstance(); +} \ No newline at end of file diff --git a/src/DataStore/DataStore.h b/src/DataStore/DataStore.h index 6c006b0..6715c02 100644 --- a/src/DataStore/DataStore.h +++ b/src/DataStore/DataStore.h @@ -11,14 +11,4 @@ class DataStore static ChatDataStore* getChatDataStore(); }; -SietchDataStore* DataStore::getSietchDataStore() -{ - return SietchDataStore::getInstance(); -} - -ChatDataStore* DataStore::getChatDataStore() -{ - return ChatDataStore::getInstance(); -} - #endif \ No newline at end of file diff --git a/src/DataStore/SietchDataStore.cpp b/src/DataStore/SietchDataStore.cpp new file mode 100644 index 0000000..140ab3f --- /dev/null +++ b/src/DataStore/SietchDataStore.cpp @@ -0,0 +1,35 @@ +#include "SietchDataStore.h" + +SietchDataStore* SietchDataStore::getInstance() +{ + if(!SietchDataStore::instanced) + { + SietchDataStore::instanced = true; + SietchDataStore::instance = new SietchDataStore(); + } + + return SietchDataStore::instance; +} + +void SietchDataStore::clear() +{ + this->data.clear(); +} + +void SietchDataStore::setData(QString key, QString value) +{ + this->data[key] = value; +} + +QString SietchDataStore::getData(QString key) +{ + return this->data[key]; +} + +QString SietchDataStore::dump() +{ + return ""; +} + +SietchDataStore* SietchDataStore::instance = nullptr; +bool SietchDataStore::instanced = false; \ No newline at end of file diff --git a/src/DataStore/SietchDataStore.h b/src/DataStore/SietchDataStore.h index c94c76f..5b5b498 100644 --- a/src/DataStore/SietchDataStore.h +++ b/src/DataStore/SietchDataStore.h @@ -15,17 +15,7 @@ class SietchDataStore } public: - static SietchDataStore* getInstance() - { - if(!SietchDataStore::instanced) - { - SietchDataStore::instanced = true; - SietchDataStore::instance = new SietchDataStore(); - } - - return SietchDataStore::instance; - } - + static SietchDataStore* getInstance(); void clear(); void setData(QString key, QString value); QString getData(QString key); @@ -38,27 +28,4 @@ class SietchDataStore } }; -void SietchDataStore::clear() -{ - this->data.clear(); -} - -void SietchDataStore::setData(QString key, QString value) -{ - this->data[key] = value; -} - -QString SietchDataStore::getData(QString key) -{ - return this->data[key]; -} - -QString SietchDataStore::dump() -{ - return ""; -} - -SietchDataStore* SietchDataStore::instance = nullptr; -bool SietchDataStore::instanced = false; - #endif \ No newline at end of file diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 98bb0f8..078a56f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -13,6 +13,7 @@ #include "addressbook.h" #include #include +#include "DataStore/DataStore.h" using namespace std; @@ -109,7 +110,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) // ui->lcdNumber->setPalette(Qt::red); // ui->lcdNumber->display("1"); - for (auto &c : this->chatItems) + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems())//this->chatItems) for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid @@ -159,7 +160,7 @@ void ChatModel::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); - for (auto &c : this->chatItems) + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems())//this->chatItems) { if ((c.second.getType() == "cont") && (c.second.isOutgoing() == false) && (c.second.getMemo().startsWith("{"))) { @@ -187,7 +188,7 @@ void ChatModel::renderContactRequest(){ QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { - for (auto &c : this->chatItems){ + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){//this->chatItems){ QModelIndex index = requestContact.requestContact->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); diff --git a/src/chatmodel.h b/src/chatmodel.h index 945c27c..984ce56 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -13,8 +13,6 @@ #include "settings.h" #include "camount.h" - - class ListViewDelegate : public QAbstractItemDelegate { int d_radius; diff --git a/src/controller.cpp b/src/controller.cpp index ac6b603..b34d519 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -887,7 +887,8 @@ void Controller::refreshTransactions() { txid, true // is an outgoing message ); - chatModel->addMessage(item); + DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + //chatModel->addMessage(item); } @@ -992,8 +993,8 @@ void Controller::refreshTransactions() { txid, false ); - - chatModel->addMessage(item); + DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + //chatModel->addMessage(item); } } diff --git a/src/controller.h b/src/controller.h index bc56587..9977427 100644 --- a/src/controller.h +++ b/src/controller.h @@ -13,7 +13,6 @@ #include "connection.h" #include "chatmodel.h" #include "contactmodel.h" - using json = nlohmann::json; struct WatchedTx { From 5006a8c7d7069ccdbd3824ff65d2266606525742 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 8 May 2020 21:25:43 +0200 Subject: [PATCH 083/253] add incoming contact Request windows --- src/chatmodel.cpp | 17 +++++------------ src/chatmodel.h | 2 +- src/mainwindow.cpp | 1 + src/mainwindow.h | 1 + 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 078a56f..6f80f37 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -100,10 +100,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView &view) void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { - QObject::connect(ui->pushContact, &QPushButton::clicked,[&] () - { - renderContactRequest(); - }); + QStandardItemModel* chat = new QStandardItemModel(); // ui->lcdNumber->setStyleSheet("background-color: red"); @@ -149,17 +146,17 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) } -void ChatModel::renderContactRequest(){ +void MainWindow::renderContactRequest(){ Ui_requestDialog requestContact; - QDialog dialog(main); + QDialog dialog(this); requestContact.setupUi(&dialog); Settings::saveRestore(&dialog); { QStandardItemModel* contactRequest = new QStandardItemModel(); - + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems())//this->chatItems) { @@ -214,8 +211,6 @@ void ChatModel::renderContactRequest(){ } }); - - QObject::connect(requestContact.pushButton, &QPushButton::clicked, [&] () { QString cid = requestContact.requestCID->text(); @@ -228,7 +223,7 @@ void ChatModel::renderContactRequest(){ qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::information(main, "Added Contact","successfully added your new contact. You can now Chat with this contact"); + QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); @@ -238,8 +233,6 @@ void ChatModel::renderContactRequest(){ dialog.exec(); } - - void ChatModel::addCid(QString tx, QString cid) { this->cidMap[tx] = cid; diff --git a/src/chatmodel.h b/src/chatmodel.h index 984ce56..493e744 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -329,7 +329,7 @@ class ChatModel void setItems(std::vector items); void renderChatBox(Ui::MainWindow* ui, QListView &view); void renderChatBox(Ui::MainWindow* ui, QListView *view); - void renderContactRequest(); + // void renderContactRequest(); void triggerRequest(); void showMessages(); void clear(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 694178f..2957dbb 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1057,6 +1057,7 @@ void MainWindow::setupchatTab() { QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); QObject::connect(ui->sendContact, &QPushButton::clicked, this, &MainWindow::ContactRequest); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); + QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); ///////// Set selected Zaddr for Chat with Klick diff --git a/src/mainwindow.h b/src/mainwindow.h index 9e91245..ff4b76a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -62,6 +62,7 @@ public: void updateLabels(); void updateTAddrCombo(bool checked); + // void renderContactRequest(); // void setChatItem(ChatItem* item); //void ChatItem* getChatItem(); From eb263e5e0b87f3f2a618834ff376876984c1f700 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 8 May 2020 22:36:24 +0200 Subject: [PATCH 084/253] switch to datastore --- src/DataStore/ChatDataStore.cpp | 36 +++++++++++++ src/DataStore/ChatDataStore.h | 4 ++ src/chatmodel.cpp | 94 ++++++++++++++++++++------------- 3 files changed, 96 insertions(+), 38 deletions(-) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index d3a79e4..4dfc605 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -37,6 +37,42 @@ std::map ChatDataStore::getAllRawChatItems() return this->data; } +std::map ChatDataStore::getAllContactRequests() +{ + std::map filteredItems; + for(auto &c: this->data) + { + if ( + (c.second.getType() == "cont") && + (c.second.isOutgoing() == false) && + (c.second.getMemo().startsWith("{")) + ) + { + filteredItems[c.first] = c.second; + } + } + return filteredItems; +} + + +std::map ChatDataStore::getAllMemos() +{ + std::map filteredItems; + for(auto &c: this->data) + { + if ( + + (c.second.getMemo().startsWith("{") == false) && + (c.second.getMemo().isEmpty() == false) + + ) + { + filteredItems[c.first] = c.second; + } + } + return filteredItems; +} + ChatDataStore* ChatDataStore::instance = nullptr; bool ChatDataStore::instanced = false; \ No newline at end of file diff --git a/src/DataStore/ChatDataStore.h b/src/DataStore/ChatDataStore.h index 85fd4b9..444c704 100644 --- a/src/DataStore/ChatDataStore.h +++ b/src/DataStore/ChatDataStore.h @@ -8,6 +8,8 @@ class ChatDataStore private: static bool instanced; static ChatDataStore* instance; + Ui::MainWindow* ui; + MainWindow* main; std::map data; ChatDataStore() { @@ -20,6 +22,8 @@ class ChatDataStore void setData(QString key, ChatItem value); ChatItem getData(QString key); std::map getAllRawChatItems(); + std::map getAllContactRequests(); + std::map getAllMemos(); QString dump(); ~ChatDataStore() diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 6f80f37..41fbb2e 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -107,13 +107,20 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) // ui->lcdNumber->setPalette(Qt::red); // ui->lcdNumber->display("1"); - for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems())//this->chatItems) + + + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) - { + for (auto &c : DataStore::getChatDataStore()->getAllMemos()) + { //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid - if ((c.second.getContact() == ui->contactNameMemo->text().trimmed()) && (p.getPartnerAddress() == c.second.getAddress()) && (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false) && (c.second.isOutgoing() == true)) + if ( + (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && + (p.getPartnerAddress() == c.second.getAddress()) && + (c.second.isOutgoing() == true) + ) { QStandardItem* Items = new QStandardItem(c.second.toChatLine()); @@ -126,8 +133,13 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setModel(chat); } - - if ((c.second.getContact() == ui->contactNameMemo->text().trimmed()) && ((p.getMyAddress() == c.second.getAddress()) && c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false) && (c.second.isOutgoing() == false)) + + if ( + (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && + (p.getMyAddress() == c.second.getAddress()) && + (c.second.isOutgoing() == false) + ) + { QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); @@ -140,11 +152,13 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) ui->listChat->setModel(chat); } + + } + + +} - } - -} void MainWindow::renderContactRequest(){ @@ -153,35 +167,18 @@ void MainWindow::renderContactRequest(){ requestContact.setupUi(&dialog); Settings::saveRestore(&dialog); - { - QStandardItemModel* contactRequest = new QStandardItemModel(); + QStandardItemModel* contactRequest = new QStandardItemModel(); - - for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems())//this->chatItems) - { - - if ((c.second.getType() == "cont") && (c.second.isOutgoing() == false) && (c.second.getMemo().startsWith("{"))) { + { + for (auto &c : DataStore::getChatDataStore()->getAllContactRequests()) + { - - - - - - QStandardItem* Items = new QStandardItem(c.second.getAddress()); - contactRequest->appendRow(Items); - requestContact.requestContact->setModel(contactRequest); - requestContact.requestContact->show(); - - - } - - - } - - - } - - + QStandardItem* Items = new QStandardItem(c.second.getAddress()); + contactRequest->appendRow(Items); + requestContact.requestContact->setModel(contactRequest); + requestContact.requestContact->show(); + } + } QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { @@ -220,12 +217,33 @@ void MainWindow::renderContactRequest(){ QString avatar = QString(":/icons/res/") + requestContact.comboBoxAvatar->currentText() + QString(".png"); + if (addr.isEmpty() || newLabel.isEmpty()) + { + QMessageBox::critical( + this, + QObject::tr("Address or Label Error"), + QObject::tr("Address or Label cannot be empty"), + QMessageBox::Ok + ); + return; + } + + // Test if address is valid. + if (!Settings::isValidAddress(addr)) + { + QMessageBox::critical( + this, + QObject::tr("Address Format Error"), + QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), + QMessageBox::Ok + ); + return; + } + qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); - - + QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); }); From 26f02293797346fc8eddf2af9662b5bc3946a01a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 9 May 2020 11:40:22 +0200 Subject: [PATCH 085/253] update lib --- lib/Cargo.lock | 7 ++++--- lib/Cargo.toml | 2 +- src/controller.cpp | 6 ++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 96d8bdf..ea96eb7 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d3a66550ed8c6216b13002ce6e5b425367f30770)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=84b1b75f2c000215aeba7850321b0abe8e8fd58f)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d3a66550ed8c6216b13002ce6e5b425367f30770#d3a66550ed8c6216b13002ce6e5b425367f30770" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=84b1b75f2c000215aeba7850321b0abe8e8fd58f#84b1b75f2c000215aeba7850321b0abe8e8fd58f" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -1652,6 +1652,7 @@ dependencies = [ "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2630,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d3a66550ed8c6216b13002ce6e5b425367f30770)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=84b1b75f2c000215aeba7850321b0abe8e8fd58f)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index bd615ca..e2987c5 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d3a66550ed8c6216b13002ce6e5b425367f30770" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "84b1b75f2c000215aeba7850321b0abe8e8fd58f" } diff --git a/src/controller.cpp b/src/controller.cpp index b34d519..1192aff 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -853,9 +853,11 @@ void Controller::refreshTransactions() { for (auto o: it["outgoing_metadata"].get()) { QString address; - + + address = QString::fromStdString(o["address"]); - + + // qDebug()<< "Position :" << position; // Sent items are -ve CAmount amount = CAmount::fromqint64(-1* o["value"].get()); From b99a0b121092d5b9bb91ceacd4ba12af41fc3c7e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 9 May 2020 13:03:46 +0200 Subject: [PATCH 086/253] add position of txs --- src/controller.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 1192aff..2c213a0 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -856,8 +856,7 @@ void Controller::refreshTransactions() { address = QString::fromStdString(o["address"]); - - // qDebug()<< "Position :" << position; + // Sent items are -ve CAmount amount = CAmount::fromqint64(-1* o["value"].get()); @@ -885,9 +884,9 @@ void Controller::refreshTransactions() { memo, QString(""), QString(""), - cid, // we have to set the cid here, its included in our Addressbook for this contact + cid, txid, - true // is an outgoing message + true ); DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); //chatModel->addMessage(item); @@ -910,7 +909,6 @@ void Controller::refreshTransactions() { } - txdata.push_back(TransactionItem{ "send", datetime, address, txid,confirmations, items }); @@ -940,6 +938,7 @@ void Controller::refreshTransactions() { QString type; QString cid; + int position; QString requestZaddr1; QString requestZaddr; @@ -984,6 +983,7 @@ void Controller::refreshTransactions() { }else{ contact = "";} + position = it["position"].get(); ChatItem item = ChatItem( datetime, address, @@ -991,12 +991,13 @@ void Controller::refreshTransactions() { memo, requestZaddr, type, - cid, // we have to set the cid here, its included in the headermemo + cid, txid, false ); DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); - //chatModel->addMessage(item); + + qDebug() << "Position der Message : " << position; } } From 3998e83a1bbdd7d53c365aa82f17fba321bdf189 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 9 May 2020 13:27:32 +0200 Subject: [PATCH 087/253] add new checkpoint --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- src/chatmodel.cpp | 4 ---- src/controller.cpp | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index ea96eb7..416f981 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=84b1b75f2c000215aeba7850321b0abe8e8fd58f)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=37531e4a48fe130f00ed9eeccbba9863e1c8ab59)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=84b1b75f2c000215aeba7850321b0abe8e8fd58f#84b1b75f2c000215aeba7850321b0abe8e8fd58f" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=37531e4a48fe130f00ed9eeccbba9863e1c8ab59#37531e4a48fe130f00ed9eeccbba9863e1c8ab59" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=84b1b75f2c000215aeba7850321b0abe8e8fd58f)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=37531e4a48fe130f00ed9eeccbba9863e1c8ab59)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index e2987c5..27ba106 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "84b1b75f2c000215aeba7850321b0abe8e8fd58f" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "37531e4a48fe130f00ed9eeccbba9863e1c8ab59" } diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 41fbb2e..7ecbe8f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -158,8 +158,6 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) } - - void MainWindow::renderContactRequest(){ Ui_requestDialog requestContact; @@ -322,7 +320,6 @@ QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, } - // Create a Tx from the current state of the Chat page. Tx MainWindow::createTxFromChatPage() { Tx tx; @@ -468,7 +465,6 @@ void MainWindow::sendChatButton() { ); } - QString MainWindow::doSendChatTxValidations(Tx tx) { // Check to see if we have enough verified funds to send the Tx. diff --git a/src/controller.cpp b/src/controller.cpp index 2c213a0..ccc0805 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -889,7 +889,6 @@ void Controller::refreshTransactions() { true ); DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); - //chatModel->addMessage(item); } @@ -984,6 +983,7 @@ void Controller::refreshTransactions() { }else{ contact = "";} position = it["position"].get(); + ChatItem item = ChatItem( datetime, address, From 17bffcdfea728fa539cead106f890b0870132a0f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 9 May 2020 16:57:46 +0200 Subject: [PATCH 088/253] render contact in all themes --- src/contactmodel.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 41b7758..ad58ccb 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -12,8 +12,6 @@ void ContactModel::renderContactList(QListView* view) for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - auto theme = Settings::getInstance()->get_theme_name(); - if ((theme == "dark" || theme == "midnight")) { QString avatar = c.getAvatar(); @@ -25,8 +23,7 @@ void ContactModel::renderContactList(QListView* view) view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly); view->show(); - - } + } From 0f574122582e37c1ad34e39d080b8e52d49b289d Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sat, 9 May 2020 17:55:12 +0200 Subject: [PATCH 089/253] update// added new model derived from chatmodel and contactmodel, moved listchatdelegate to a seperated class file --- silentdragon-lite.pro | 5 +- src/Chat/Chat.h | 6 + src/Chat/Helper/ChatDelegator.h | 148 +++++++++++++ src/Model/ChatItem.cpp | 135 ++++++++++++ src/Model/ChatItem.h | 45 ++++ src/Model/ContactItem.cpp | 66 ++++++ src/Model/ContactItem.h | 32 +++ src/Model/ContactRequestChatItem.cpp | 1 + src/Model/ContactRequestChatItem.h | 11 + src/chatmodel.h | 297 +-------------------------- src/contactmodel.h | 78 +------ src/controller.cpp | 1 + src/controller.h | 2 + 13 files changed, 454 insertions(+), 373 deletions(-) create mode 100644 src/Chat/Chat.h create mode 100644 src/Chat/Helper/ChatDelegator.h create mode 100644 src/Model/ChatItem.cpp create mode 100644 src/Model/ChatItem.h create mode 100644 src/Model/ContactItem.cpp create mode 100644 src/Model/ContactItem.h create mode 100644 src/Model/ContactRequestChatItem.cpp create mode 100644 src/Model/ContactRequestChatItem.h diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index c09eea7..808527b 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -74,7 +74,10 @@ SOURCES += \ src/contactmodel.cpp \ src/DataStore/DataStore.cpp \ src/DataStore/ChatDataStore.cpp \ - src/DataStore/SietchDataStore.cpp + src/DataStore/SietchDataStore.cpp \ + src/Model/ChatItem.cpp \ + src/Model/ContactRequestChatItem.cpp \ + src/Model/ContactItem.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/Chat/Chat.h b/src/Chat/Chat.h new file mode 100644 index 0000000..0558d91 --- /dev/null +++ b/src/Chat/Chat.h @@ -0,0 +1,6 @@ +#ifndef CHAT_H +#define CHAT_H + + + +#endif \ No newline at end of file diff --git a/src/Chat/Helper/ChatDelegator.h b/src/Chat/Helper/ChatDelegator.h new file mode 100644 index 0000000..ef6a150 --- /dev/null +++ b/src/Chat/Helper/ChatDelegator.h @@ -0,0 +1,148 @@ +#ifndef CHATDELEGATOR_H +#define CHATDELEGATOR_H + +#include +#include +#include +#include + +class ListViewDelegate : public QAbstractItemDelegate +{ + int d_radius; + int d_toppadding; + int d_bottompadding; + int d_leftpadding; + int d_rightpadding; + int d_verticalmargin; + int d_horizontalmargin; + int d_pointerwidth; + int d_pointerheight; + float d_widthfraction; + public: + inline ListViewDelegate(QObject *parent = nullptr); + + protected: + inline void paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const; + inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; +}; + +inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(15), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) +{ + +} + +inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + QTextDocument bodydoc; + QTextOption textOption(bodydoc.defaultTextOption()); + textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + bodydoc.setDefaultTextOption(textOption); + bodydoc.setDefaultFont(QFont("Roboto", 12)); + QString bodytext(index.data(Qt::DisplayRole).toString()); + bodydoc.setHtml(bodytext); + qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; + bodydoc.setTextWidth(contentswidth); + qreal bodyheight = bodydoc.size().height(); + bool outgoing = index.data(Qt::UserRole + 1).toString() == "Outgoing"; + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + + // uncomment to see the area provided to paint this item + + //painter->drawRect(option.rect); + + painter->translate(option.rect.left() + d_horizontalmargin, option.rect.top() + ((index.row() == 0) ? d_verticalmargin : 0)); + + // background color for chat bubble + QColor bgcolor("#535353"); + if (outgoing) + bgcolor = "#eeeeee"; + + // create chat bubble + QPainterPath pointie; + + // left bottom + pointie.moveTo(0, bodyheight + d_toppadding + d_bottompadding); + + // right bottom + pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - d_radius, + bodyheight + d_toppadding + d_bottompadding); + pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, + bodyheight + d_toppadding + d_bottompadding - 2 * d_radius, + 2 * d_radius, 2 * d_radius, 270, 90); + + // right top + pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding, 0 + d_radius); + pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, 0, + 2 * d_radius, 2 * d_radius, 0, 90); + + // left top + pointie.lineTo(0 + d_pointerwidth + d_radius, 0); + pointie.arcTo(0 + d_pointerwidth, 0, 2 * d_radius, 2 * d_radius, 90, 90); + + // left bottom almost (here is the pointie) + pointie.lineTo(0 + d_pointerwidth, bodyheight + d_toppadding + d_bottompadding - d_pointerheight); + pointie.closeSubpath(); + + // rotate bubble for outgoing messages + if (outgoing) + { + painter->translate(option.rect.width() - pointie.boundingRect().width() - d_horizontalmargin - d_pointerwidth, 0); + painter->translate(pointie.boundingRect().center()); + painter->rotate(180); + painter->translate(-pointie.boundingRect().center()); + } + + // now paint it! + painter->setPen(QPen(bgcolor)); + painter->drawPath(pointie); + painter->fillPath(pointie, QBrush(bgcolor)); + + // rotate back or painter is going to paint the text rotated... + if (outgoing) + { + painter->translate(pointie.boundingRect().center()); + painter->rotate(-180); + painter->translate(-pointie.boundingRect().center()); + } + + // set text color used to draw message body + QAbstractTextDocumentLayout::PaintContext ctx; + if (outgoing) + ctx.palette.setColor(QPalette::Text, QColor("black")); + else + ctx.palette.setColor(QPalette::Text, QColor("white")); + + // draw body text + painter->translate((outgoing ? 0 : d_pointerwidth) + d_leftpadding, 0); + bodydoc.documentLayout()->draw(painter, ctx); + + painter->restore(); +} + +inline QSize ListViewDelegate::sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const +{ + QTextDocument bodydoc; + QTextOption textOption(bodydoc.defaultTextOption()); + textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + bodydoc.setDefaultTextOption(textOption); + bodydoc.setDefaultFont(QFont("Roboto", 12)); + QString bodytext(index.data(Qt::DisplayRole).toString()); + bodydoc.setHtml(bodytext); + + // the width of the contents are the (a fraction of the window width) minus (margins + padding + width of the bubble's tail) + qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; + + // set this available width on the text document + bodydoc.setTextWidth(contentswidth); + + QSize size(bodydoc.idealWidth() + d_horizontalmargin + d_pointerwidth + d_leftpadding + d_rightpadding, + bodydoc.size().height() + d_bottompadding + d_toppadding + d_verticalmargin + 1); // I dont remember why +1, haha, might not be necessary + + if (index.row() == 0) // have extra margin at top of first item + size += QSize(0, d_verticalmargin); + + return size; +} + +#endif \ No newline at end of file diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp new file mode 100644 index 0000000..39d4a68 --- /dev/null +++ b/src/Model/ChatItem.cpp @@ -0,0 +1,135 @@ +#include "ChatItem.h" + +ChatItem::ChatItem() {} + +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid) +{ + _timestamp = timestamp; + _address = address; + _contact = contact; + _memo = memo; + _requestZaddr = requestZaddr; + _type = type; + _cid = cid; + _txid = txid; + _outgoing = false; +} + +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing) +{ + _timestamp = timestamp; + _address = address; + _contact = contact; + _memo = memo; + _requestZaddr = requestZaddr; + _type = type; + _cid = cid; + _txid = txid; + _outgoing = outgoing; +} + +long ChatItem::getTimestamp() +{ + return _timestamp; +} + +QString ChatItem::getAddress() +{ + return _address; +} + +QString ChatItem::getContact() +{ + return _contact; +} + +QString ChatItem::getMemo() +{ + return _memo; +} + +QString ChatItem::getRequestZaddr() +{ + return _requestZaddr; +} +QString ChatItem::getType() +{ + return _type; +} + +QString ChatItem::getCid() +{ + return _cid; +} + +QString ChatItem::getTxid() +{ + return _txid; +} + +bool ChatItem::isOutgoing() +{ + return _outgoing; +} + +void ChatItem::setTimestamp(long timestamp) +{ + _timestamp = timestamp; +} + +void ChatItem::setAddress(QString address) +{ + _address = address; +} + +void ChatItem::setContact(QString contact) +{ + _contact = contact; +} + +void ChatItem::setMemo(QString memo) +{ + _memo = memo; +} + +void ChatItem::setRequestZaddr(QString requestZaddr) +{ + _requestZaddr = requestZaddr; +} + +void ChatItem::setType(QString type) +{ + _type = type; +} + +void ChatItem::setCid(QString cid) +{ + _cid = cid; +} +void ChatItem::setTxid(QString txid) +{ + _txid = txid; +} + +void ChatItem::toggleOutgo() +{ + _outgoing = true; +} + +QString ChatItem::toChatLine() +{ + QDateTime myDateTime; + myDateTime.setTime_t(_timestamp); + QString line = QString("[") + myDateTime.toString("d.M.yy hh:mm") + QString("] "); + line += QString("") + QString(_memo) + QString("\n\n"); + return line; +} + +ChatItem::~ChatItem() +{ + /*delete timestamp; + delete address; + delete contact; + delete memo; + delete outgoing;*/ +} \ No newline at end of file diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h new file mode 100644 index 0000000..467341f --- /dev/null +++ b/src/Model/ChatItem.h @@ -0,0 +1,45 @@ +#ifndef CHATITEM_H +#define CHATITEM_H + +#include + +class ChatItem +{ + private: + long _timestamp; + QString _address; + QString _contact; + QString _memo; + QString _requestZaddr; + QString _type; + QString _cid; + QString _txid; + bool _outgoing = false; + + public: + ChatItem(); + ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid); + ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing); + long getTimestamp(); + QString getAddress(); + QString getContact(); + QString getMemo(); + QString getRequestZaddr(); + QString getType(); + QString getCid(); + QString getTxid(); + bool isOutgoing(); + void setTimestamp(long timestamp); + void setAddress(QString address); + void setContact(QString contact); + void setMemo(QString memo); + void setRequestZaddr(QString requestZaddr); + void setType(QString type); + void setCid(QString cid); + void setTxid(QString txid); + void toggleOutgo(); + QString toChatLine(); + ~ChatItem(); +}; + +#endif \ No newline at end of file diff --git a/src/Model/ContactItem.cpp b/src/Model/ContactItem.cpp new file mode 100644 index 0000000..f338552 --- /dev/null +++ b/src/Model/ContactItem.cpp @@ -0,0 +1,66 @@ +#include "ContactItem.h" + +ContactItem::ContactItem() {} + +ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar) +{ + _name = name; + _myAddress = myAddress; + _partnerAddress = partnerAddress; + _cid = cid; + _avatar = avatar; +} + +QString ContactItem::getName() const +{ + return _name; +} + +QString ContactItem::getMyAddress() const +{ + return _myAddress; +} + +QString ContactItem::getPartnerAddress() const +{ + return _partnerAddress; +} + +QString ContactItem::getCid() const +{ + return _cid; +} + +QString ContactItem::getAvatar() const +{ + return _avatar; +} + +void ContactItem::setName(QString name) +{ + _name = name; +} + +void ContactItem::setMyAddress(QString myAddress) +{ + _myAddress = myAddress; +} + +void ContactItem::setPartnerAddress(QString partnerAddress) +{ + _partnerAddress = partnerAddress; +} + +void ContactItem::setcid(QString cid) +{ + _cid = cid; +} +void ContactItem::setAvatar(QString avatar) +{ + _avatar = avatar; +} + +QString ContactItem::toQTString() +{ + return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid + "|" + _avatar; +} \ No newline at end of file diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h new file mode 100644 index 0000000..a18d0f7 --- /dev/null +++ b/src/Model/ContactItem.h @@ -0,0 +1,32 @@ +#ifndef CONTACTITEM_H +#define CONTACTITEM_H + +#include +#include + +class ContactItem +{ +private: + QString _myAddress; + QString _partnerAddress; + QString _name; + QString _cid; + QString _avatar; + +public: + ContactItem(); + ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar); + QString getName() const; + QString getMyAddress() const; + QString getPartnerAddress() const; + QString getCid() const; + QString getAvatar() const; + void setName(QString name); + void setMyAddress(QString myAddress); + void setPartnerAddress(QString partnerAddress); + void setcid(QString cid); + void setAvatar(QString avatar); + QString toQTString(); +}; + +#endif \ No newline at end of file diff --git a/src/Model/ContactRequestChatItem.cpp b/src/Model/ContactRequestChatItem.cpp new file mode 100644 index 0000000..d6cd443 --- /dev/null +++ b/src/Model/ContactRequestChatItem.cpp @@ -0,0 +1 @@ +#include "ContactRequestChatItem.h" \ No newline at end of file diff --git a/src/Model/ContactRequestChatItem.h b/src/Model/ContactRequestChatItem.h new file mode 100644 index 0000000..d1720de --- /dev/null +++ b/src/Model/ContactRequestChatItem.h @@ -0,0 +1,11 @@ +#ifdef CONTACTREQUESTCHATITEM_H +#define CONTACTREQUESTCHATITEM_H + +#include "ChatItem.h" + +class ContactRequestChatItem : ChatItem +{ + +}; + +#endif \ No newline at end of file diff --git a/src/chatmodel.h b/src/chatmodel.h index 493e744..f39888d 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -12,301 +12,8 @@ #include "controller.h" #include "settings.h" #include "camount.h" - -class ListViewDelegate : public QAbstractItemDelegate -{ - int d_radius; - int d_toppadding; - int d_bottompadding; - int d_leftpadding; - int d_rightpadding; - int d_verticalmargin; - int d_horizontalmargin; - int d_pointerwidth; - int d_pointerheight; - float d_widthfraction; - public: - inline ListViewDelegate(QObject *parent = nullptr); - - protected: - inline void paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const; - inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; -}; - -inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(15), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) -{ - -} - -inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem const &option, QModelIndex const &index) const -{ - QTextDocument bodydoc; - QTextOption textOption(bodydoc.defaultTextOption()); - textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - bodydoc.setDefaultTextOption(textOption); - bodydoc.setDefaultFont(QFont("Roboto", 12)); - QString bodytext(index.data(Qt::DisplayRole).toString()); - bodydoc.setHtml(bodytext); - qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; - bodydoc.setTextWidth(contentswidth); - qreal bodyheight = bodydoc.size().height(); - bool outgoing = index.data(Qt::UserRole + 1).toString() == "Outgoing"; - painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - - // uncomment to see the area provided to paint this item - - //painter->drawRect(option.rect); - - painter->translate(option.rect.left() + d_horizontalmargin, option.rect.top() + ((index.row() == 0) ? d_verticalmargin : 0)); - - // background color for chat bubble - QColor bgcolor("#535353"); - if (outgoing) - bgcolor = "#eeeeee"; - - // create chat bubble - QPainterPath pointie; - - // left bottom - pointie.moveTo(0, bodyheight + d_toppadding + d_bottompadding); - - // right bottom - pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - d_radius, - bodyheight + d_toppadding + d_bottompadding); - pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, - bodyheight + d_toppadding + d_bottompadding - 2 * d_radius, - 2 * d_radius, 2 * d_radius, 270, 90); - - // right top - pointie.lineTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding, 0 + d_radius); - pointie.arcTo(0 + contentswidth + d_pointerwidth + d_leftpadding + d_rightpadding - 2 * d_radius, 0, - 2 * d_radius, 2 * d_radius, 0, 90); - - // left top - pointie.lineTo(0 + d_pointerwidth + d_radius, 0); - pointie.arcTo(0 + d_pointerwidth, 0, 2 * d_radius, 2 * d_radius, 90, 90); - - // left bottom almost (here is the pointie) - pointie.lineTo(0 + d_pointerwidth, bodyheight + d_toppadding + d_bottompadding - d_pointerheight); - pointie.closeSubpath(); - - // rotate bubble for outgoing messages - if (outgoing) - { - painter->translate(option.rect.width() - pointie.boundingRect().width() - d_horizontalmargin - d_pointerwidth, 0); - painter->translate(pointie.boundingRect().center()); - painter->rotate(180); - painter->translate(-pointie.boundingRect().center()); - } - - // now paint it! - painter->setPen(QPen(bgcolor)); - painter->drawPath(pointie); - painter->fillPath(pointie, QBrush(bgcolor)); - - // rotate back or painter is going to paint the text rotated... - if (outgoing) - { - painter->translate(pointie.boundingRect().center()); - painter->rotate(-180); - painter->translate(-pointie.boundingRect().center()); - } - - // set text color used to draw message body - QAbstractTextDocumentLayout::PaintContext ctx; - if (outgoing) - ctx.palette.setColor(QPalette::Text, QColor("black")); - else - ctx.palette.setColor(QPalette::Text, QColor("white")); - - // draw body text - painter->translate((outgoing ? 0 : d_pointerwidth) + d_leftpadding, 0); - bodydoc.documentLayout()->draw(painter, ctx); - - painter->restore(); -} - -inline QSize ListViewDelegate::sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const -{ - QTextDocument bodydoc; - QTextOption textOption(bodydoc.defaultTextOption()); - textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - bodydoc.setDefaultTextOption(textOption); - bodydoc.setDefaultFont(QFont("Roboto", 12)); - QString bodytext(index.data(Qt::DisplayRole).toString()); - bodydoc.setHtml(bodytext); - - // the width of the contents are the (a fraction of the window width) minus (margins + padding + width of the bubble's tail) - qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; - - // set this available width on the text document - bodydoc.setTextWidth(contentswidth); - - QSize size(bodydoc.idealWidth() + d_horizontalmargin + d_pointerwidth + d_leftpadding + d_rightpadding, - bodydoc.size().height() + d_bottompadding + d_toppadding + d_verticalmargin + 1); // I dont remember why +1, haha, might not be necessary - - if (index.row() == 0) // have extra margin at top of first item - size += QSize(0, d_verticalmargin); - - return size; -} - - - - - -class ChatItem -{ - private: - long _timestamp; - QString _address; - QString _contact; - QString _memo; - QString _requestZaddr; - QString _type; - QString _cid; - QString _txid; - bool _outgoing = false; - - public: - ChatItem() {} - - ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid) - { - _timestamp = timestamp; - _address = address; - _contact = contact; - _memo = memo; - _requestZaddr = requestZaddr; - _type = type; - _cid = cid; - _txid = txid; - _outgoing = false; - - } - - ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing) - { - _timestamp = timestamp; - _address = address; - _contact = contact; - _memo = memo; - _requestZaddr = requestZaddr; - _type = type; - _cid = cid; - _txid = txid; - _outgoing = outgoing; - - } - - long getTimestamp() - { - return _timestamp; - } - - QString getAddress() - { - return _address; - } - - QString getContact() - { - return _contact; - } - - QString getMemo() - { - return _memo; - } - - QString getRequestZaddr() - { - return _requestZaddr; - } - QString getType() - { - return _type; - } - - QString getCid() - { - return _cid; - } - - QString getTxid() - { - return _txid; - } - - - bool isOutgoing() - { - return _outgoing; - } - - void setTimestamp(long timestamp) - { - _timestamp = timestamp; - } - - void setAddress(QString address) - { - _address = address; - } - - void setContact(QString contact) - { - _contact = contact; - } - - void setMemo(QString memo) - { - _memo = memo; - } - - void setRequestZaddr(QString requestZaddr) - { - _requestZaddr = requestZaddr; - } - - void setType(QString type) - { - _type = type; - } - - void setCid(QString cid) - { - _cid = cid; - } - void setTxid(QString txid) - { - _txid = txid; - } - - void toggleOutgo() - { - _outgoing = true; - } - - QString toChatLine() - { - QDateTime myDateTime; - myDateTime.setTime_t(_timestamp); - QString line = QString("[") + myDateTime.toString("d.M.yy hh:mm") + QString("] ") ; - line += QString("") + QString(_memo) + QString("\n\n"); - return line; - } - - ~ChatItem() - { - /*delete timestamp; - delete address; - delete contact; - delete memo; - delete outgoing;*/ - } -}; +#include "Model/ChatItem.h" +#include "Chat/Helper/ChatDelegator.h" class ChatModel { diff --git a/src/contactmodel.h b/src/contactmodel.h index b643bdb..fcdf7a3 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -3,85 +3,9 @@ #ifndef CONTACTMODEL_H #define CONTACTMODEL_H -#include -#include +#include "Model/ContactItem.h" #include -class ContactItem -{ - private: - QString _myAddress; - QString _partnerAddress; - QString _name; - QString _cid; - QString _avatar; - - public: - ContactItem(); - ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar) - { - _name = name; - _myAddress = myAddress; - _partnerAddress = partnerAddress; - _cid = cid; - _avatar = avatar; - } - - QString getName() const - { - return _name; - } - - QString getMyAddress() const - { - return _myAddress; - } - - QString getPartnerAddress() const - { - return _partnerAddress; - } - - QString getCid() const - { - return _cid; - } - - QString getAvatar() const - { - return _avatar; - } - - void setName(QString name) - { - _name = name; - } - - void setMyAddress(QString myAddress) - { - _myAddress = myAddress; - } - - void setPartnerAddress(QString partnerAddress) - { - _partnerAddress = partnerAddress; - } - - void setcid(QString cid) - { - _cid = cid; - } - void setAvatar(QString avatar) - { - _avatar = avatar; - } - - QString toQTString() - { - return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid + "|"+ _avatar; - } - -}; class ContactModel { diff --git a/src/controller.cpp b/src/controller.cpp index ccc0805..9087867 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -8,6 +8,7 @@ #include "version.h" #include "camount.h" #include "websockets.h" +#include "Model/ChatItem.h" #include "DataStore/DataStore.h" /*template<> diff --git a/src/controller.h b/src/controller.h index 9977427..05e1f97 100644 --- a/src/controller.h +++ b/src/controller.h @@ -12,6 +12,8 @@ #include "liteinterface.h" #include "connection.h" #include "chatmodel.h" +#include "Model/ContactRequestChatItem.h" +#include "Model/ContactItem.h" #include "contactmodel.h" using json = nlohmann::json; From 7dfb9a192939fa2fce58a920fd93096fd702a3cb Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sat, 9 May 2020 18:14:04 +0200 Subject: [PATCH 090/253] update// moved generator to separated helper class --- silentdragon-lite.pro | 3 ++- src/Chat/Chat.h | 34 ++++++++++++++++++++++++++++++++++ src/chatmodel.h | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 808527b..5c7dd21 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -77,7 +77,8 @@ SOURCES += \ src/DataStore/SietchDataStore.cpp \ src/Model/ChatItem.cpp \ src/Model/ContactRequestChatItem.cpp \ - src/Model/ContactItem.cpp + src/Model/ContactItem.cpp \ + src/Chat/Helper/ChatIDGenerator.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/Chat/Chat.h b/src/Chat/Chat.h index 0558d91..969f98c 100644 --- a/src/Chat/Chat.h +++ b/src/Chat/Chat.h @@ -1,6 +1,40 @@ #ifndef CHAT_H #define CHAT_H +class Chat // Chat Controller +{ + private: + std::map chatItems; + QTableView* parent; + Ui::MainWindow* ui; + MainWindow* main; + std::map cidMap; + std::map requestZaddrMap; + public: + ChatModel() {}; + ChatModel(std::map chatItems); + ChatModel(std::vector chatItems); + QString generateChatItemID(ChatItem item); // helper + std::map getItems(); + void setItems(std::map items); + QString zaddr(); + void setItems(std::vector items); + void renderChatBox(Ui::MainWindow* ui, QListView &view); // action + void renderChatBox(Ui::MainWindow* ui, QListView *view); // action + // void renderContactRequest(); + void triggerRequest(); + void showMessages(); + void clear(); + //void renderContactRequest(Ui::MainWindow* ui, QListView *view); + void addMessage(ChatItem item); + void addMessage(QString timestamp, ChatItem item); + void addCid(QString tx, QString cid); + void addrequestZaddr(QString tx, QString requestZaddr); + QString getCidByTx(QString tx); + QString getrequestZaddrByTx(QString tx); + void killCidCache(); + void killrequestZaddrCache(); +}; #endif \ No newline at end of file diff --git a/src/chatmodel.h b/src/chatmodel.h index f39888d..d1a4147 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -14,6 +14,7 @@ #include "camount.h" #include "Model/ChatItem.h" #include "Chat/Helper/ChatDelegator.h" +#include "Chat/Helper/ChatIDGenerator.h" class ChatModel { From abdad2b09d9321abe026d544747e586fbdd52c40 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sat, 9 May 2020 21:19:59 +0200 Subject: [PATCH 091/253] update// updated contactmodel and added new generatorclass --- src/chatmodel.cpp | 11 +++++------ src/chatmodel.h | 2 +- src/contactmodel.cpp | 5 +---- src/controller.cpp | 11 ++++++----- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 7ecbe8f..67dd432 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -27,7 +27,7 @@ ChatModel::ChatModel(std::vector chatItems) this->setItems(chatItems); } -QString ChatModel::generateChatItemID(ChatItem item) +/*QString ChatModel::generateChatItemID(ChatItem item) { QString key = QString::number(item.getTimestamp()) + QString("-"); key += QString(QCryptographicHash::hash( @@ -39,7 +39,7 @@ QString ChatModel::generateChatItemID(ChatItem item) ).toUtf8() ,QCryptographicHash::Md5).toHex()); return key; -} +}*/ std::map ChatModel::getItems() { @@ -55,8 +55,7 @@ void ChatModel::setItems(std::vector items) { for(ChatItem c : items) { - this->chatItems[this->generateChatItemID(c)] = c; - + this->chatItems[ChatIDGenerator::getInstance()->generateID(c)] = c; //this->generateChatItemID(c)] = c; } } @@ -67,14 +66,14 @@ void ChatModel::clear() void ChatModel::addMessage(ChatItem item) { - QString key = this->generateChatItemID(item); + QString key = ChatIDGenerator::getInstance()->generateID(item); //this->generateChatItemID(item); // qDebug() << "inserting chatitem with id: " << key; this->chatItems[key] = item; } void ChatModel::addMessage(QString timestamp, ChatItem item) { - QString key = this->generateChatItemID(item); + QString key = ChatIDGenerator::getInstance()->generateID(item);//this->generateChatItemID(item); timestamp = "0"; this->chatItems[key] = item; } diff --git a/src/chatmodel.h b/src/chatmodel.h index d1a4147..b54c5ae 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -30,7 +30,7 @@ class ChatModel ChatModel() {}; ChatModel(std::map chatItems); ChatModel(std::vector chatItems); - QString generateChatItemID(ChatItem item); + //QString generateChatItemID(ChatItem item); std::map getItems(); void setItems(std::map items); QString zaddr(); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 41b7758..ad58ccb 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -12,8 +12,6 @@ void ContactModel::renderContactList(QListView* view) for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { - auto theme = Settings::getInstance()->get_theme_name(); - if ((theme == "dark" || theme == "midnight")) { QString avatar = c.getAvatar(); @@ -25,8 +23,7 @@ void ContactModel::renderContactList(QListView* view) view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly); view->show(); - - } + } diff --git a/src/controller.cpp b/src/controller.cpp index 9087867..9301fbd 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -826,7 +826,7 @@ void Controller::refreshBalances() }); } -void Controller::refreshTransactions() { +void Controller::refreshTransactions() { if (!zrpc->haveConnection()) return noConnection(); @@ -847,7 +847,7 @@ void Controller::refreshTransactions() { auto txid = QString::fromStdString(it["txid"]); auto datetime = it["datetime"].get(); - + // First, check if there's outgoing metadata if (!it["outgoing_metadata"].is_null()) { @@ -889,7 +889,8 @@ void Controller::refreshTransactions() { txid, true ); - DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + //DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } @@ -996,8 +997,8 @@ void Controller::refreshTransactions() { txid, false ); - DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); - + //DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); qDebug() << "Position der Message : " << position; } } From 48c592e9e91d0ac96d0b68851343c2bdede36b56 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 9 May 2020 21:46:05 +0200 Subject: [PATCH 092/253] update lib --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- src/controller.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 416f981..e198570 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=37531e4a48fe130f00ed9eeccbba9863e1c8ab59)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1da0f0e3210db704edec74de1bc318b4e22cb6c8)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=37531e4a48fe130f00ed9eeccbba9863e1c8ab59#37531e4a48fe130f00ed9eeccbba9863e1c8ab59" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=1da0f0e3210db704edec74de1bc318b4e22cb6c8#1da0f0e3210db704edec74de1bc318b4e22cb6c8" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=37531e4a48fe130f00ed9eeccbba9863e1c8ab59)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1da0f0e3210db704edec74de1bc318b4e22cb6c8)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 27ba106..bdf5a9b 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "37531e4a48fe130f00ed9eeccbba9863e1c8ab59" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "1da0f0e3210db704edec74de1bc318b4e22cb6c8" } diff --git a/src/controller.cpp b/src/controller.cpp index ccc0805..9a5118d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -937,7 +937,7 @@ void Controller::refreshTransactions() { QString type; QString cid; - int position; + // int position; QString requestZaddr1; QString requestZaddr; @@ -982,7 +982,7 @@ void Controller::refreshTransactions() { }else{ contact = "";} - position = it["position"].get(); + // position = it["position"].get(); ChatItem item = ChatItem( datetime, @@ -997,7 +997,7 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); - qDebug() << "Position der Message : " << position; + } } From 6c4ee63b729505a78c857ed0ebb105fba9e1a190 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sat, 9 May 2020 22:03:55 +0200 Subject: [PATCH 093/253] update// added idgenerator and resolved mergeconflicts --- src/Chat/Helper/ChatIDGenerator.cpp | 28 ++++++++++++++++++++++++++++ src/Chat/Helper/ChatIDGenerator.h | 18 ++++++++++++++++++ src/controller.cpp | 1 - 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/Chat/Helper/ChatIDGenerator.cpp create mode 100644 src/Chat/Helper/ChatIDGenerator.h diff --git a/src/Chat/Helper/ChatIDGenerator.cpp b/src/Chat/Helper/ChatIDGenerator.cpp new file mode 100644 index 0000000..2acea1b --- /dev/null +++ b/src/Chat/Helper/ChatIDGenerator.cpp @@ -0,0 +1,28 @@ +#include "ChatIDGenerator.h" + +ChatIDGenerator* ChatIDGenerator::getInstance() +{ + if(ChatIDGenerator::instance == nullptr) + ChatIDGenerator::instance = new ChatIDGenerator(); + + return ChatIDGenerator::instance; +} + +QString ChatIDGenerator::generateID(ChatItem item) +{ + QString key = QString::number(item.getTimestamp()) + QString("-"); + key += QString( + QCryptographicHash::hash( + QString( + QString::number(item.getTimestamp()) + + item.getAddress() + + item.getContact() + + item.getMemo() + ).toUtf8(), + QCryptographicHash::Md5 + ).toHex() + ); + return key; +} + +ChatIDGenerator* ChatIDGenerator::instance = nullptr; \ No newline at end of file diff --git a/src/Chat/Helper/ChatIDGenerator.h b/src/Chat/Helper/ChatIDGenerator.h new file mode 100644 index 0000000..d9f6e4a --- /dev/null +++ b/src/Chat/Helper/ChatIDGenerator.h @@ -0,0 +1,18 @@ +#ifndef CHATIDGENERATOR_H +#define CHATIDGENERATOR_H + +#include +#include +#include "../../Model/ChatItem.h" + +class ChatIDGenerator +{ + private: + static ChatIDGenerator* instance; + + public: + static ChatIDGenerator* getInstance(); + QString generateID(ChatItem item); +}; + +#endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 36bc6d1..ecc487a 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -999,7 +999,6 @@ void Controller::refreshTransactions() { ); //DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - } } From 7987a1fd86dda195e0c7a3198fb73e37dbaeaec5 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 10 May 2020 00:13:02 +0200 Subject: [PATCH 094/253] fix mac png problem --- src/mainwindow.cpp | 4 ++-- src/mainwindow.ui | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2957dbb..7a1f6c2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -908,9 +908,9 @@ void MainWindow::setupTransactionsTab() { // Set up context menu on transactions tab auto theme = Settings::getInstance()->get_theme_name(); if (theme == "dark" || theme == "midnight") { - ui->listChat->setStyleSheet("background-image: url(res/sdlogo.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover"); + ui->listChat->setStyleSheet("background-image: url(:/icons/res/sdlogo.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover"); } - if (theme == "default") {ui->listChat->setStyleSheet("background-image: url(res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} + if (theme == "default") {ui->listChat->setStyleSheet("background-image: url(:/icons/res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} ui->listChat->setResizeMode(QListView::Adjust); ui->listChat->setWordWrap(true); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 08e1d4d..3e82d7a 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -10,6 +10,43 @@ 779 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + SilentDragonLite From cd9b850a3522f516bf1e9a1dbbc48f1910c4f097 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 10 May 2020 00:59:40 +0200 Subject: [PATCH 095/253] parse hm as json --- src/controller.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index ecc487a..c11fe72 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -920,6 +920,7 @@ void Controller::refreshTransactions() { model->markAddressUsed(address); QString memo; + QString test; if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); } @@ -939,16 +940,16 @@ void Controller::refreshTransactions() { QString type; QString cid; - // int position; - QString requestZaddr1; + // int position; QString requestZaddr; if (memo.startsWith("{")) { - type = memo.mid(75,4); - cid = memo.mid(14,36); - requestZaddr1 = memo.right(82); - requestZaddr = requestZaddr1.left(78); + QJsonDocument doc = QJsonDocument::fromJson(memo.toUtf8()); + + cid = doc["cid"].toString(); + type = doc["t"].toString(); + requestZaddr = doc["z"].toString(); chatModel->addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); @@ -997,7 +998,7 @@ void Controller::refreshTransactions() { txid, false ); - //DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } } From d48a7c64befd210429b4268ddef914a3245f516c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 10 May 2020 01:13:56 +0200 Subject: [PATCH 096/253] rename hm json --- src/controller.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index c11fe72..e757190 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -889,7 +889,7 @@ void Controller::refreshTransactions() { txid, true ); - //DataStore::getChatDataStore()->setData(chatModel->generateChatItemID(item), item); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } @@ -945,11 +945,11 @@ void Controller::refreshTransactions() { if (memo.startsWith("{")) { - QJsonDocument doc = QJsonDocument::fromJson(memo.toUtf8()); + QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); - cid = doc["cid"].toString(); - type = doc["t"].toString(); - requestZaddr = doc["z"].toString(); + cid = headermemo["cid"].toString(); + type = headermemo["t"].toString(); + requestZaddr = headermemo["z"].toString(); chatModel->addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); From 3fef6d382567e2bd744ca4d3aba43b8455a92faa Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 10 May 2020 16:10:50 +0200 Subject: [PATCH 097/253] set dangerous bool to false --- src/connection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connection.cpp b/src/connection.cpp index 26d6d2b..bbc3bce 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -59,7 +59,7 @@ void ConnectionLoader::doAutoConnect() { qDebug() << "Doing autoconnect"; auto config = std::shared_ptr(new ConnectionConfig()); - config->dangerous = true; + config->dangerous = false; config->server = Settings::getInstance()->getSettings().server; // Initialize the library From 11e3bc5ede44a0bb23878a089a7a2bdc22a2919f Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sun, 10 May 2020 16:16:54 +0200 Subject: [PATCH 098/253] update// moved render function to chat.cpp --- silentdragon-lite.pro | 3 ++- src/Chat/Chat.h | 32 ++++++++++++++++++++------------ src/controller.cpp | 5 +++-- src/controller.h | 1 + 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 5c7dd21..da53d6d 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -78,7 +78,8 @@ SOURCES += \ src/Model/ChatItem.cpp \ src/Model/ContactRequestChatItem.cpp \ src/Model/ContactItem.cpp \ - src/Chat/Helper/ChatIDGenerator.cpp + src/Chat/Helper/ChatIDGenerator.cpp \ + src/Chat/Chat.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/Chat/Chat.h b/src/Chat/Chat.h index 969f98c..526aa36 100644 --- a/src/Chat/Chat.h +++ b/src/Chat/Chat.h @@ -1,28 +1,36 @@ #ifndef CHAT_H #define CHAT_H +#include +#include +#include +#include +#include +#include +#include +#include "precompiled.h" +#include "mainwindow.h" +#include "controller.h" +#include "settings.h" +#include "camount.h" + +#include "../Model/ChatItem.h" + + class Chat // Chat Controller { private: - std::map chatItems; QTableView* parent; Ui::MainWindow* ui; MainWindow* main; std::map cidMap; std::map requestZaddrMap; public: - ChatModel() {}; - ChatModel(std::map chatItems); - ChatModel(std::vector chatItems); - QString generateChatItemID(ChatItem item); // helper - std::map getItems(); - void setItems(std::map items); - QString zaddr(); - void setItems(std::vector items); - void renderChatBox(Ui::MainWindow* ui, QListView &view); // action + Chat(); + //QString zaddr(); void renderChatBox(Ui::MainWindow* ui, QListView *view); // action // void renderContactRequest(); - void triggerRequest(); + /*void triggerRequest(); void showMessages(); void clear(); //void renderContactRequest(Ui::MainWindow* ui, QListView *view); @@ -33,7 +41,7 @@ class Chat // Chat Controller QString getCidByTx(QString tx); QString getrequestZaddrByTx(QString tx); void killCidCache(); - void killrequestZaddrCache(); + void killrequestZaddrCache();*/ }; diff --git a/src/controller.cpp b/src/controller.cpp index e757190..730e906 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -16,6 +16,7 @@ DataStore* DataStore::instance = nullptr; template<> bool DataStore::instanced = false;*/ ChatModel *chatModel = new ChatModel(); +Chat *chat = new Chat(); ContactModel *contactModel = new ContactModel(); using json = nlohmann::json; @@ -1022,7 +1023,7 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); - chatModel->renderChatBox(ui, ui->listChat); + chat->renderChatBox(ui, ui->listChat); refreshContacts( ui->listContactWidget @@ -1032,7 +1033,7 @@ void Controller::refreshTransactions() { void Controller::refreshChat(QListView *listWidget) { - chatModel->renderChatBox(ui, listWidget); + chat->renderChatBox(ui, listWidget); } diff --git a/src/controller.h b/src/controller.h index 05e1f97..cfd3bbb 100644 --- a/src/controller.h +++ b/src/controller.h @@ -12,6 +12,7 @@ #include "liteinterface.h" #include "connection.h" #include "chatmodel.h" +#include "Chat/Chat.h" #include "Model/ContactRequestChatItem.h" #include "Model/ContactItem.h" #include "contactmodel.h" From 7e491b3a2534bf88f9b80d71c994b9b0531e1b96 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sun, 10 May 2020 19:15:04 +0200 Subject: [PATCH 099/253] update// addec chat.cpp --- src/Chat/Chat.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/Chat/Chat.cpp diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp new file mode 100644 index 0000000..c2719ee --- /dev/null +++ b/src/Chat/Chat.cpp @@ -0,0 +1,53 @@ +#include "Chat.h" +#include "../addressbook.h" +#include "../DataStore/DataStore.h" +Chat::Chat() {} + +void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) +{ + QStandardItemModel *chat = new QStandardItemModel(); + // ui->lcdNumber->setStyleSheet("background-color: red"); + // ui->lcdNumber->setPalette(Qt::red); + // ui->lcdNumber->display("1"); + + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) + { + for (auto &c : DataStore::getChatDataStore()->getAllMemos()) + { + //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid + + if ( + (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && + (p.getPartnerAddress() == c.second.getAddress()) && + (c.second.isOutgoing() == true)) + { + + QStandardItem *Items = new QStandardItem(c.second.toChatLine()); + Items->setData("Outgoing", Qt::UserRole + 1); + chat->appendRow(Items); + ui->listChat->setModel(chat); + } + else + { + ui->listChat->setModel(chat); + } + + if ( + (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && + (p.getMyAddress() == c.second.getAddress()) && + (c.second.isOutgoing() == false)) + + { + QStandardItem *Items1 = new QStandardItem(c.second.toChatLine()); + Items1->setData("Incoming", Qt::UserRole + 1); + chat->appendRow(Items1); + ui->listChat->setModel(chat); + } + else + { + + ui->listChat->setModel(chat); + } + } + } +} \ No newline at end of file From b9526c1f3514f4a7abd2ec0b8979392c5781141d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 14 May 2020 12:50:05 +0200 Subject: [PATCH 100/253] fix a problem with two chatrender functions due to refractor --- src/Chat/Chat.cpp | 4 +-- src/chatmodel.cpp | 74 ++-------------------------------------------- src/chatmodel.h | 5 ---- src/controller.cpp | 13 +++++--- 4 files changed, 13 insertions(+), 83 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index c2719ee..7038fe1 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -17,7 +17,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid if ( - (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && + (p.getName() == ui->contactNameMemo->text().trimmed()) && (p.getPartnerAddress() == c.second.getAddress()) && (c.second.isOutgoing() == true)) { @@ -33,7 +33,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) } if ( - (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && + (p.getName() == ui->contactNameMemo->text().trimmed()) && (p.getMyAddress() == c.second.getAddress()) && (c.second.isOutgoing() == false)) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 67dd432..01aed54 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -86,77 +86,7 @@ void ChatModel::showMessages() } } - -void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView &view) -{ - /*for(auto &c : this->chatItems) - { - //view.getItems().add(QString("[Timestamp] : lorem ipsum ....")); - }*/ - qDebug() << "not implemented yet"; - //todo render items to view -} - -void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) -{ - - - QStandardItemModel* chat = new QStandardItemModel(); - // ui->lcdNumber->setStyleSheet("background-color: red"); - // ui->lcdNumber->setPalette(Qt::red); - // ui->lcdNumber->display("1"); - - - - - for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) - for (auto &c : DataStore::getChatDataStore()->getAllMemos()) - { - //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid - - - if ( - (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && - (p.getPartnerAddress() == c.second.getAddress()) && - (c.second.isOutgoing() == true) - ) - { - - QStandardItem* Items = new QStandardItem(c.second.toChatLine()); - Items->setData("Outgoing", Qt::UserRole +1); - chat->appendRow(Items); - ui->listChat->setModel(chat); - - } - else{ - ui->listChat->setModel(chat); - - } - - if ( - (c.second.getContact() == ui->contactNameMemo->text().trimmed()) && - (p.getMyAddress() == c.second.getAddress()) && - (c.second.isOutgoing() == false) - ) - - { - - QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); - Items1->setData("Incoming", Qt::UserRole +1); - chat->appendRow(Items1); - ui->listChat->setModel(chat); - - } - else{ - - ui->listChat->setModel(chat); - } - - } - - -} - + void MainWindow::renderContactRequest(){ Ui_requestDialog requestContact; @@ -167,7 +97,7 @@ void MainWindow::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); { - for (auto &c : DataStore::getChatDataStore()->getAllContactRequests()) + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()) { QStandardItem* Items = new QStandardItem(c.second.getAddress()); diff --git a/src/chatmodel.h b/src/chatmodel.h index b54c5ae..04493b8 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -30,18 +30,13 @@ class ChatModel ChatModel() {}; ChatModel(std::map chatItems); ChatModel(std::vector chatItems); - //QString generateChatItemID(ChatItem item); std::map getItems(); void setItems(std::map items); QString zaddr(); void setItems(std::vector items); - void renderChatBox(Ui::MainWindow* ui, QListView &view); - void renderChatBox(Ui::MainWindow* ui, QListView *view); - // void renderContactRequest(); void triggerRequest(); void showMessages(); void clear(); - //void renderContactRequest(Ui::MainWindow* ui, QListView *view); void addMessage(ChatItem item); void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); diff --git a/src/controller.cpp b/src/controller.cpp index 730e906..35403c1 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -877,7 +877,7 @@ void Controller::refreshTransactions() { if (address == c.getPartnerAddress()){ contact = c.getName(); }else{ contact = "";} - + } ChatItem item = ChatItem( datetime, @@ -890,14 +890,17 @@ void Controller::refreshTransactions() { txid, true ); + qDebug()<<"Kontaktname : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - } + // } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } + { QList addresses; @@ -986,6 +989,7 @@ void Controller::refreshTransactions() { }else{ contact = "";} + } // position = it["position"].get(); ChatItem item = ChatItem( @@ -999,9 +1003,10 @@ void Controller::refreshTransactions() { txid, false ); - + qDebug()<<"Kontaktname : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - } + // } } } From 96a073cacf8737c87182b85418bcc8210d66f027 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 14 May 2020 13:26:24 +0200 Subject: [PATCH 101/253] dont scan transactions to often --- src/addressbook.cpp | 2 +- src/controller.cpp | 36 +++++++++--------------------------- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index d00c3ae..d17726c 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -156,7 +156,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) ab.addr_chat->setText(myAddr); }); model.updateUi(); //todo fix updating gui after adding - rpc->refresh(true); + //rpc->refresh(true); // If there is a target then make it the addr for the "Add to" button if (target != nullptr && Settings::isValidAddress(target->text())) diff --git a/src/controller.cpp b/src/controller.cpp index 35403c1..3c370f1 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -867,22 +867,14 @@ void Controller::refreshTransactions() { QString memo; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - } + - QString cid; - QString contact; - - for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - { - if (address == c.getPartnerAddress()){ - contact = c.getName(); - }else{ contact = "";} - } + QString cid; ChatItem item = ChatItem( datetime, address, - contact, + QString(""), memo, QString(""), QString(""), @@ -890,12 +882,11 @@ void Controller::refreshTransactions() { txid, true ); - qDebug()<<"Kontaktname : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - // } + } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -947,7 +938,7 @@ void Controller::refreshTransactions() { // int position; QString requestZaddr; - if (memo.startsWith("{")) { + if ((memo.startsWith("{")) && (!it["memo"].is_null())) { QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); @@ -958,7 +949,7 @@ void Controller::refreshTransactions() { chatModel->addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); - } + // } if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ @@ -980,22 +971,13 @@ void Controller::refreshTransactions() { requestZaddr = ""; } - QString contact; - for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - { - if (address == c.getMyAddress()){ - contact = c.getName(); - - }else{ contact = "";} - - } // position = it["position"].get(); ChatItem item = ChatItem( datetime, address, - contact, + QString(""), memo, requestZaddr, type, @@ -1003,10 +985,10 @@ void Controller::refreshTransactions() { txid, false ); - qDebug()<<"Kontaktname : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - // } + } } } From 7fe11f4985c0a8ec6ff8871f5d4ca295131946bc Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 14 May 2020 13:55:25 +0200 Subject: [PATCH 102/253] fix some typos/reformat --- src/controller.cpp | 1902 +++++++++++++++++++++----------------------- 1 file changed, 886 insertions(+), 1016 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 3c370f1..8023cbc 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -2,58 +2,67 @@ // GPLv3 #include "controller.h" + #include "mainwindow.h" + #include "addressbook.h" + #include "settings.h" + #include "version.h" + #include "camount.h" + #include "websockets.h" + #include "Model/ChatItem.h" + #include "DataStore/DataStore.h" /*template<> DataStore* DataStore::instance = nullptr; template<> bool DataStore::instanced = false;*/ -ChatModel *chatModel = new ChatModel(); -Chat *chat = new Chat(); -ContactModel *contactModel = new ContactModel(); +ChatModel * chatModel = new ChatModel(); +Chat * chat = new Chat(); +ContactModel * contactModel = new ContactModel(); using json = nlohmann::json; -Controller::Controller(MainWindow* main) -{ +Controller::Controller(MainWindow * main) { auto cl = new ConnectionLoader(main, this); // Execute the load connection async, so we can set up the rest of RPC properly. - QTimer::singleShot(1, [=]() { cl->loadConnection(); }); + QTimer::singleShot(1, [ = ]() { + cl - > loadConnection(); + }); - this->main = main; - this->ui = main->ui; + this - > main = main; + this - > ui = main - > ui; // Setup balances table model - balancesTableModel = new BalancesTableModel(main->ui->balancesTable); - main->ui->balancesTable->setModel(balancesTableModel); + balancesTableModel = new BalancesTableModel(main - > ui - > balancesTable); + main - > ui - > balancesTable - > setModel(balancesTableModel); // Setup transactions table model - transactionsTableModel = new TxTableModel(ui->transactionsTable); - main->ui->transactionsTable->setModel(transactionsTableModel); - + transactionsTableModel = new TxTableModel(ui - > transactionsTable); + main - > ui - > transactionsTable - > setModel(transactionsTableModel); + // Set up timer to refresh Price priceTimer = new QTimer(main); - QObject::connect(priceTimer, &QTimer::timeout, [=]() { - if (Settings::getInstance()->getAllowFetchPrices()) - refreshZECPrice(); - + QObject::connect(priceTimer, & QTimer::timeout, [ = ]() { + if (Settings::getInstance() - > getAllowFetchPrices()) + refreshZECPrice(); + }); - priceTimer->start(Settings::priceRefreshSpeed); // Every 5 Min + priceTimer - > start(Settings::priceRefreshSpeed); // Every 5 Min // Set up a timer to refresh the UI every few seconds timer = new QTimer(main); - QObject::connect(timer, &QTimer::timeout, [=]() { + QObject::connect(timer, & QTimer::timeout, [ = ]() { refresh(); }); - timer->start(Settings::updateSpeed); + timer - > start(Settings::updateSpeed); // Create the data model model = new DataModel(); @@ -62,8 +71,7 @@ Controller::Controller(MainWindow* main) zrpc = new LiteInterface(); } -Controller::~Controller() -{ +Controller::~Controller() { delete timer; delete txTimer; delete transactionsTableModel; @@ -71,22 +79,21 @@ Controller::~Controller() delete model; delete zrpc; } - + // Called when a connection to hushd is available. -void Controller::setConnection(Connection* c) -{ - if (c == nullptr) +void Controller::setConnection(Connection * c) { + if (c == nullptr) return; - this->zrpc->setConnection(c); - ui->statusBar->showMessage(""); + this - > zrpc - > setConnection(c); + ui - > statusBar - > showMessage(""); // If we're allowed to get the Hush Price, get the prices - if (Settings::getInstance()->getAllowFetchPrices()) + if (Settings::getInstance() - > getAllowFetchPrices()) refreshZECPrice(); // If we're allowed to check for updates, check for a new release - if (Settings::getInstance()->getCheckForUpdates()) + if (Settings::getInstance() - > getCheckForUpdates()) checkForUpdate(); // Force update, because this might be coming from a settings update @@ -95,458 +102,417 @@ void Controller::setConnection(Connection* c) // Create Sietch zdust addr at startup. // Using DataStore singelton, to store the data outside of lambda, bing bada boom :D - for(uint8_t i = 0; i < 10; i++) - { - zrpc->createNewSietchZaddr( [=] (json reply) { - QString zdust = QString::fromStdString(reply.get()[0]); - DataStore::getSietchDataStore()->setData("Sietch" + QString(i), zdust.toUtf8()); + for (uint8_t i = 0; i < 10; i++) { + zrpc - > createNewSietchZaddr([ = ](json reply) { + QString zdust = QString::fromStdString(reply.get < json::array_t > ()[0]); + DataStore::getSietchDataStore() - > setData("Sietch" + QString(i), zdust.toUtf8()); }); } } // Build the RPC JSON Parameters for this tx -void Controller::fillTxJsonParams(json& allRecepients, Tx tx) -{ +void Controller::fillTxJsonParams(json & allRecepients, Tx tx) { Q_ASSERT(allRecepients.is_array()); // Construct the JSON params json rec = json::object(); //creating the JSON dust parameters in a std::vector to iterate over there during tx - std::vector dust(10); + std::vector < json > dust(10); dust.resize(10, json::object()); // Create Sietch zdust addr again to not use it twice. // Using DataStore singelton, to store the data outside of lambda, bing bada boom :D - for(uint8_t i = 0; i < 10; i++) - { - zrpc->createNewSietchZaddr( [=] (json reply) { - QString zdust = QString::fromStdString(reply.get()[0]); - DataStore::getSietchDataStore()->setData(QString("Sietch") + QString(i), zdust.toUtf8()); - } ); + for (uint8_t i = 0; i < 10; i++) { + zrpc - > createNewSietchZaddr([ = ](json reply) { + QString zdust = QString::fromStdString(reply.get < json::array_t > ()[0]); + DataStore::getSietchDataStore() - > setData(QString("Sietch") + QString(i), zdust.toUtf8()); + }); } // Set sietch zdust addr to json. // Using DataStore singelton, to store the data into the dusts, bing bada boom :D - for(uint8_t i = 0; i < 10; i++) - { - dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString(); + for (uint8_t i = 0; i < 10; i++) { + dust.at(i)["address"] = DataStore::getSietchDataStore() - > getData(QString("Sietch" + QString(i))).toStdString(); } - DataStore::getSietchDataStore()->clear(); // clears the datastore + DataStore::getSietchDataStore() - > clear(); // clears the datastore // Dust amt/memo, construct the JSON - for(uint8_t i = 0; i < 10; i++) - { + for (uint8_t i = 0; i < 10; i++) { dust.at(i)["amount"] = 0; dust.at(i)["memo"] = ""; - + } - + // For each addr/amt/memo, construct the JSON and also build the confirm dialog box - for (int i=0; i < tx.toAddrs.size(); i++) - { + for (int i = 0; i < tx.toAddrs.size(); i++) { auto toAddr = tx.toAddrs[i]; rec["address"] = toAddr.addr.toStdString(); - rec["amount"] = toAddr.amount.toqint64(); + rec["amount"] = toAddr.amount.toqint64(); if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty()) rec["memo"] = toAddr.memo.toStdString(); - allRecepients.push_back(rec) ; + allRecepients.push_back(rec); } - allRecepients.insert(std::begin(allRecepients), { - dust.at(0), - dust.at(1), - dust.at(2), - dust.at(3), - dust.at(4), - dust.at(5), - dust.at(6), - dust.at(7), - dust.at(8) - }) ; + allRecepients.insert(std::begin(allRecepients), { + dust.at(0), + dust.at(1), + dust.at(2), + dust.at(3), + dust.at(4), + dust.at(5), + dust.at(6), + dust.at(7), + dust.at(8) + }); } -void Controller::noConnection() -{ - QIcon i = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); - main->statusIcon->setPixmap(i.pixmap(16, 16)); - main->statusIcon->setToolTip(""); - main->statusLabel->setText(QObject::tr("No Connection")); - main->statusLabel->setToolTip(""); - main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000); +void Controller::noConnection() { + QIcon i = QApplication::style() - > standardIcon(QStyle::SP_MessageBoxCritical); + main - > statusIcon - > setPixmap(i.pixmap(16, 16)); + main - > statusIcon - > setToolTip(""); + main - > statusLabel - > setText(QObject::tr("No Connection")); + main - > statusLabel - > setToolTip(""); + main - > ui - > statusBar - > showMessage(QObject::tr("No Connection"), 1000); // Clear balances table. - QMap emptyBalances; - QList emptyOutputs; - QList emptyAddresses; - balancesTableModel->setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs); + QMap < QString, CAmount > emptyBalances; + QList < UnspentOutput > emptyOutputs; + QList < QString > emptyAddresses; + balancesTableModel - > setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs); // Clear Transactions table. - QList emptyTxs; - transactionsTableModel->replaceData(emptyTxs); + QList < TransactionItem > emptyTxs; + transactionsTableModel - > replaceData(emptyTxs); // Clear balances - ui->balSheilded->setText(""); - ui->balTransparent->setText(""); - ui->balTotal->setText(""); + ui - > balSheilded - > setText(""); + ui - > balTransparent - > setText(""); + ui - > balTotal - > setText(""); - ui->balSheilded->setToolTip(""); - ui->balTransparent->setToolTip(""); - ui->balTotal->setToolTip(""); + ui - > balSheilded - > setToolTip(""); + ui - > balTransparent - > setToolTip(""); + ui - > balTotal - > setToolTip(""); } /// This will refresh all the balance data from hushd -void Controller::refresh(bool force) -{ - if (!zrpc->haveConnection()) +void Controller::refresh(bool force) { + if (!zrpc - > haveConnection()) return noConnection(); getInfoThenRefresh(force); } -void Controller::processInfo(const json& info) -{ +void Controller::processInfo(const json & info) { // Testnet? QString chainName; - if (!info["chain_name"].is_null()) - { - chainName = QString::fromStdString(info["chain_name"].get()); - Settings::getInstance()->setTestnet(chainName == "test"); + if (!info["chain_name"].is_null()) { + chainName = QString::fromStdString(info["chain_name"].get < json::string_t > ()); + Settings::getInstance() - > setTestnet(chainName == "test"); } - QString version = QString::fromStdString(info["version"].get()); - Settings::getInstance()->sethushdVersion(version); + QString version = QString::fromStdString(info["version"].get < json::string_t > ()); + Settings::getInstance() - > sethushdVersion(version); // Recurring pamynets are testnet only - if (!Settings::getInstance()->isTestnet()) - main->disableRecurring(); + if (!Settings::getInstance() - > isTestnet()) + main - > disableRecurring(); } -void Controller::getInfoThenRefresh(bool force) -{ - if (!zrpc->haveConnection()) +void Controller::getInfoThenRefresh(bool force) { + if (!zrpc - > haveConnection()) return noConnection(); static bool prevCallSucceeded = false; - zrpc->fetchInfo([=] (const json& reply) { - prevCallSucceeded = true; - int curBlock = reply["latest_block_height"].get(); - int longestchain = reply["longestchain"].get(); - int notarized = reply["notarized"].get(); - int difficulty = reply["difficulty"].get(); - int blocks_until_halving= 340000 - curBlock; - int halving_days = (blocks_until_halving * 150) / (60*60*24) ; - bool doUpdate = force || (model->getLatestBlock() != curBlock); - model->setLatestBlock(curBlock); + zrpc - > fetchInfo([ = ](const json & reply) { + prevCallSucceeded = true; + int curBlock = reply["latest_block_height"].get < json::number_integer_t > (); + int longestchain = reply["longestchain"].get < json::number_integer_t > (); + int notarized = reply["notarized"].get < json::number_integer_t > (); + int difficulty = reply["difficulty"].get < json::number_integer_t > (); + int blocks_until_halving = 340000 - curBlock; + int halving_days = (blocks_until_halving * 150) / (60 * 60 * 24); + bool doUpdate = force || (model - > getLatestBlock() != curBlock); + model - > setLatestBlock(curBlock); if ( - Settings::getInstance()->get_currency_name() == "EUR" || - Settings::getInstance()->get_currency_name() == "CHF" || - Settings::getInstance()->get_currency_name() == "RUB" - ) - { - ui->blockHeight->setText( + Settings::getInstance() - > get_currency_name() == "EUR" || + Settings::getInstance() - > get_currency_name() == "CHF" || + Settings::getInstance() - > get_currency_name() == "RUB" + ) { + ui - > blockHeight - > setText( "Block: " + QLocale(QLocale::German).toString(curBlock) ); - ui->last_notarized->setText( + ui - > last_notarized - > setText( "Block: " + QLocale(QLocale::German).toString(notarized) ); - ui->longestchain->setText( + ui - > longestchain - > setText( "Block: " + QLocale(QLocale::German).toString(longestchain) ); - ui->difficulty->setText( + ui - > difficulty - > setText( QLocale(QLocale::German).toString(difficulty) ); - ui->halvingTime->setText( - (QLocale(QLocale::German).toString(blocks_until_halving)) + - " Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days" ) + ui - > halvingTime - > setText( + (QLocale(QLocale::German).toString(blocks_until_halving)) + + " Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days") ); - } - else - { - ui->blockHeight->setText( + } else { + ui - > blockHeight - > setText( "Block: " + QLocale(QLocale::English).toString(curBlock) ); - ui->last_notarized->setText( + ui - > last_notarized - > setText( "Block: " + QLocale(QLocale::English).toString(notarized) ); - ui->longestchain->setText( + ui - > longestchain - > setText( "Block: " + QLocale(QLocale::English).toString(longestchain) ); - ui->difficulty->setText( + ui - > difficulty - > setText( QLocale(QLocale::English).toString(difficulty) ); - ui->halvingTime->setText( - (QLocale(QLocale::English).toString(blocks_until_halving)) + - " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days" ) + ui - > halvingTime - > setText( + (QLocale(QLocale::English).toString(blocks_until_halving)) + + " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days") ); } - ui->Version->setText( - QString::fromStdString(reply["version"].get()) - ); - ui->Vendor->setText( - QString::fromStdString(reply["vendor"].get()) + ui - > Version - > setText( + QString::fromStdString(reply["version"].get < json::string_t > ()) ); - main->logger->write( - QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") + ui - > Vendor - > setText( + QString::fromStdString(reply["vendor"].get < json::string_t > ()) + ); + main - > logger - > write( + QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") ); // Connected, so display checkmark. - auto tooltip = Settings::getInstance()->getSettings().server + "\n" + - QString::fromStdString(zrpc->getConnection()->getInfo().dump()); + auto tooltip = Settings::getInstance() - > getSettings().server + "\n" + + QString::fromStdString(zrpc - > getConnection() - > getInfo().dump()); QIcon i(":/icons/res/connected.gif"); - QString chainName = Settings::getInstance()->isTestnet() ? "test" : "main"; - main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")"); + QString chainName = Settings::getInstance() - > isTestnet() ? "test" : "main"; + main - > statusLabel - > setText(chainName + "(" + QString::number(curBlock) + ")"); // use currency ComboBox as input - if (Settings::getInstance()->get_currency_name() == "USD") - { - double price = Settings::getInstance()->getZECPrice(); - double volume = Settings::getInstance()->getUSDVolume(); - double cap = Settings::getInstance()->getUSDCAP(); - main->statusLabel->setText( - " HUSH/USD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) + if (Settings::getInstance() - > get_currency_name() == "USD") { + double price = Settings::getInstance() - > getZECPrice(); + double volume = Settings::getInstance() - > getUSDVolume(); + double cap = Settings::getInstance() - > getUSDCAP(); + main - > statusLabel - > setText( + " HUSH/USD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "EUR") - { - double price = Settings::getInstance()->getEURPrice(); - double volume = Settings::getInstance()->getEURVolume(); - double cap = Settings::getInstance()->getEURCAP(); - main->statusLabel->setText( - "HUSH/EUR "+(QLocale(QLocale::German).toString(price,'f', 2))+ " €" - ); - ui->volumeExchange->setText( - QLocale(QLocale::German).toString(volume,'f', 2)+ " €" + } else if (Settings::getInstance() - > get_currency_name() == "EUR") { + double price = Settings::getInstance() - > getEURPrice(); + double volume = Settings::getInstance() - > getEURVolume(); + double cap = Settings::getInstance() - > getEURCAP(); + main - > statusLabel - > setText( + "HUSH/EUR " + (QLocale(QLocale::German).toString(price, 'f', 2)) + " €" ); - ui->marketcapTab->setText( - QLocale(QLocale::German).toString(cap,'f', 2)+ " €" + ui - > volumeExchange - > setText( + QLocale(QLocale::German).toString(volume, 'f', 2) + " €" + ); + ui - > marketcapTab - > setText( + QLocale(QLocale::German).toString(cap, 'f', 2) + " €" ); - } - else if (Settings::getInstance()->get_currency_name() == "BTC") - { - double price = Settings::getInstance()->getBTCPrice(); - double volume = Settings::getInstance()->getBTCVolume(); - double cap = Settings::getInstance()->getBTCCAP(); - main->statusLabel->setText( - " HUSH/BTC=BTC " + (QLocale(QLocale::English).toString(price, 'f',8)) + } else if (Settings::getInstance() - > get_currency_name() == "BTC") { + double price = Settings::getInstance() - > getBTCPrice(); + double volume = Settings::getInstance() - > getBTCVolume(); + double cap = Settings::getInstance() - > getBTCCAP(); + main - > statusLabel - > setText( + " HUSH/BTC=BTC " + (QLocale(QLocale::English).toString(price, 'f', 8)) ); - ui->volumeExchange->setText( - " BTC " + (QLocale(QLocale::English).toString(volume, 'f',8)) + ui - > volumeExchange - > setText( + " BTC " + (QLocale(QLocale::English).toString(volume, 'f', 8)) ); - ui->marketcapTab->setText( - " BTC " + (QLocale(QLocale::English).toString(cap, 'f',8)) + ui - > marketcapTab - > setText( + " BTC " + (QLocale(QLocale::English).toString(cap, 'f', 8)) ); - } - else if (Settings::getInstance()->get_currency_name() == "CNY") - { - double price = Settings::getInstance()->getCNYPrice(); - double volume = Settings::getInstance()->getCNYVolume(); - double cap = Settings::getInstance()->getCNYCAP(); - main->statusLabel->setText( - " HUSH/CNY=¥ /元 " + (QLocale(QLocale::Chinese).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "CNY") { + double price = Settings::getInstance() - > getCNYPrice(); + double volume = Settings::getInstance() - > getCNYVolume(); + double cap = Settings::getInstance() - > getCNYCAP(); + main - > statusLabel - > setText( + " HUSH/CNY=¥ /元 " + (QLocale(QLocale::Chinese).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " ¥ /元 " + (QLocale(QLocale::Chinese).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " ¥ /元 " + (QLocale(QLocale::Chinese).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " ¥ /元 " + (QLocale(QLocale::Chinese).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " ¥ /元 " + (QLocale(QLocale::Chinese).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "RUB") - { - double price = Settings::getInstance()->getRUBPrice(); - double volume = Settings::getInstance()->getRUBVolume(); - double cap = Settings::getInstance()->getRUBCAP(); - main->statusLabel->setText( - " HUSH/RUB=₽ " + (QLocale(QLocale::German).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "RUB") { + double price = Settings::getInstance() - > getRUBPrice(); + double volume = Settings::getInstance() - > getRUBVolume(); + double cap = Settings::getInstance() - > getRUBCAP(); + main - > statusLabel - > setText( + " HUSH/RUB=₽ " + (QLocale(QLocale::German).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " ₽ " + (QLocale(QLocale::German).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " ₽ " + (QLocale(QLocale::German).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " ₽ " + (QLocale(QLocale::German).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " ₽ " + (QLocale(QLocale::German).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "CAD") - { - double price = Settings::getInstance()->getCADPrice(); - double volume = Settings::getInstance()->getCADVolume(); - double cap = Settings::getInstance()->getCADCAP(); - main->statusLabel->setText( - " HUSH/CAD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "CAD") { + double price = Settings::getInstance() - > getCADPrice(); + double volume = Settings::getInstance() - > getCADVolume(); + double cap = Settings::getInstance() - > getCADCAP(); + main - > statusLabel - > setText( + " HUSH/CAD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "SGD") - { - double price = Settings::getInstance()->getSGDPrice(); - double volume = Settings::getInstance()->getSGDVolume(); - double cap = Settings::getInstance()->getSGDCAP(); - main->statusLabel->setText( - " HUSH/SGD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "SGD") { + double price = Settings::getInstance() - > getSGDPrice(); + double volume = Settings::getInstance() - > getSGDVolume(); + double cap = Settings::getInstance() - > getSGDCAP(); + main - > statusLabel - > setText( + " HUSH/SGD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "CHF") - { - double price = Settings::getInstance()->getCHFPrice(); - double volume = Settings::getInstance()->getCHFVolume(); - double cap = Settings::getInstance()->getCHFCAP(); - main->statusLabel->setText( - " HUSH/CHF= " + (QLocale(QLocale::German).toString(price,'f', 2))+ " CHF" + } else if (Settings::getInstance() - > get_currency_name() == "CHF") { + double price = Settings::getInstance() - > getCHFPrice(); + double volume = Settings::getInstance() - > getCHFVolume(); + double cap = Settings::getInstance() - > getCHFCAP(); + main - > statusLabel - > setText( + " HUSH/CHF= " + (QLocale(QLocale::German).toString(price, 'f', 2)) + " CHF" ); - ui->volumeExchange->setText( - QLocale(QLocale::German).toString(volume,'f', 2)+ " CHF" + ui - > volumeExchange - > setText( + QLocale(QLocale::German).toString(volume, 'f', 2) + " CHF" ); - ui->marketcapTab->setText( - QLocale(QLocale::German).toString(cap,'f', 2)+ " CHF" + ui - > marketcapTab - > setText( + QLocale(QLocale::German).toString(cap, 'f', 2) + " CHF" ); - } - else if (Settings::getInstance()->get_currency_name() == "INR") - { - double price = Settings::getInstance()->getINRPrice(); - double volume = Settings::getInstance()->getINRVolume(); - double cap = Settings::getInstance()->getINRCAP(); - main->statusLabel->setText( - " HUSH/INR=₹ " + (QLocale(QLocale::English).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "INR") { + double price = Settings::getInstance() - > getINRPrice(); + double volume = Settings::getInstance() - > getINRVolume(); + double cap = Settings::getInstance() - > getINRCAP(); + main - > statusLabel - > setText( + " HUSH/INR=₹ " + (QLocale(QLocale::English).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " ₹ " + (QLocale(QLocale::English).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " ₹ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " ₹ " + (QLocale(QLocale::English).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " ₹ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "GBP") - { - double price = Settings::getInstance()->getGBPPrice(); - double volume = Settings::getInstance()->getGBPVolume(); - double cap = Settings::getInstance()->getGBPCAP(); - main->statusLabel->setText( - " HUSH/GBP=£ " + (QLocale(QLocale::English).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "GBP") { + double price = Settings::getInstance() - > getGBPPrice(); + double volume = Settings::getInstance() - > getGBPVolume(); + double cap = Settings::getInstance() - > getGBPCAP(); + main - > statusLabel - > setText( + " HUSH/GBP=£ " + (QLocale(QLocale::English).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " £ " + (QLocale(QLocale::English).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " £ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " £ " + (QLocale(QLocale::English).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " £ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) ); - } - else if (Settings::getInstance()->get_currency_name() == "AUD") - { - double price = Settings::getInstance()->getAUDPrice(); - double volume = Settings::getInstance()->getAUDVolume(); - double cap = Settings::getInstance()->getAUDCAP(); - main->statusLabel->setText( - " HUSH/AUD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) + } else if (Settings::getInstance() - > get_currency_name() == "AUD") { + double price = Settings::getInstance() - > getAUDPrice(); + double volume = Settings::getInstance() - > getAUDVolume(); + double cap = Settings::getInstance() - > getAUDCAP(); + main - > statusLabel - > setText( + " HUSH/AUD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) ); - ui->volumeExchange->setText( - " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) + ui - > volumeExchange - > setText( + " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) ); - ui->marketcapTab->setText( - " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) + ui - > marketcapTab - > setText( + " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) ); - - } - else - { - main->statusLabel->setText( - " HUSH/USD=$" + QString::number(Settings::getInstance()->getZECPrice(),'f',2 ) + + } else { + main - > statusLabel - > setText( + " HUSH/USD=$" + QString::number(Settings::getInstance() - > getZECPrice(), 'f', 2) ); - ui->volumeExchange->setText( - " $ " + QString::number((double) Settings::getInstance()->getUSDVolume() ,'f',2) + ui - > volumeExchange - > setText( + " $ " + QString::number((double) Settings::getInstance() - > getUSDVolume(), 'f', 2) ); - ui->marketcapTab->setText( - " $ " + QString::number((double) Settings::getInstance()->getUSDCAP() ,'f',2) + ui - > marketcapTab - > setText( + " $ " + QString::number((double) Settings::getInstance() - > getUSDCAP(), 'f', 2) ); } - main->statusLabel->setToolTip(tooltip); - main->statusIcon->setPixmap(i.pixmap(16, 16)); - main->statusIcon->setToolTip(tooltip); + main - > statusLabel - > setToolTip(tooltip); + main - > statusIcon - > setPixmap(i.pixmap(16, 16)); + main - > statusIcon - > setToolTip(tooltip); // See if recurring payments needs anything - Recurring::getInstance()->processPending(main); + Recurring::getInstance() - > processPending(main); // Check if the wallet is locked/encrypted - zrpc->fetchWalletEncryptionStatus([=] (const json& reply) { - bool isEncrypted = reply["encrypted"].get(); - bool isLocked = reply["locked"].get(); - model->setEncryptionStatus(isEncrypted, isLocked); + zrpc - > fetchWalletEncryptionStatus([ = ](const json & reply) { + bool isEncrypted = reply["encrypted"].get < json::boolean_t > (); + bool isLocked = reply["locked"].get < json::boolean_t > (); + model - > setEncryptionStatus(isEncrypted, isLocked); }); - // Get the total supply and render it with thousand decimal - zrpc->fetchSupply([=] (const json& reply) { - int supply = reply["supply"].get(); - int zfunds = reply["zfunds"].get(); - int total = reply["total"].get(); + // Get the total supply and render it with thousand decimal + zrpc - > fetchSupply([ = ](const json & reply) { + int supply = reply["supply"].get < json::number_integer_t > (); + int zfunds = reply["zfunds"].get < json::number_integer_t > (); + int total = reply["total"].get < json::number_integer_t > (); if ( - Settings::getInstance()->get_currency_name() == "EUR" || - Settings::getInstance()->get_currency_name() == "CHF" || - Settings::getInstance()->get_currency_name() == "RUB" - ) - { - ui->supply_taddr->setText((QLocale(QLocale::German).toString(supply)+ " Hush")); - ui->supply_zaddr->setText((QLocale(QLocale::German).toString(zfunds)+ " Hush")); - ui->supply_total->setText((QLocale(QLocale::German).toString(total)+ " Hush")); - } - else - { - ui->supply_taddr->setText("Hush " + (QLocale(QLocale::English).toString(supply))); - ui->supply_zaddr->setText("Hush " +(QLocale(QLocale::English).toString(zfunds))); - ui->supply_total->setText("Hush " +(QLocale(QLocale::English).toString(total))); + Settings::getInstance() - > get_currency_name() == "EUR" || + Settings::getInstance() - > get_currency_name() == "CHF" || + Settings::getInstance() - > get_currency_name() == "RUB" + ) { + ui - > supply_taddr - > setText((QLocale(QLocale::German).toString(supply) + " Hush")); + ui - > supply_zaddr - > setText((QLocale(QLocale::German).toString(zfunds) + " Hush")); + ui - > supply_total - > setText((QLocale(QLocale::German).toString(total) + " Hush")); + } else { + ui - > supply_taddr - > setText("Hush " + (QLocale(QLocale::English).toString(supply))); + ui - > supply_zaddr - > setText("Hush " + (QLocale(QLocale::English).toString(zfunds))); + ui - > supply_total - > setText("Hush " + (QLocale(QLocale::English).toString(total))); } }); - if ( doUpdate ) - { + if (doUpdate) { // Something changed, so refresh everything. - refreshBalances(); - refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() + refreshBalances(); + refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() refreshTransactions(); } - }, [=](QString err) { + }, [ = ](QString err) { // hushd has probably disappeared. - this->noConnection(); + this - > noConnection(); // Prevent multiple dialog boxes, because these are called async static bool shown = false; if (!shown && prevCallSucceeded) // show error only first time - { + { shown = true; QMessageBox::critical( - main, - QObject::tr("Connection Error"), - QObject::tr("There was an error connecting to hushd. The error was") + ": \n\n"+ err, + main, + QObject::tr("Connection Error"), + QObject::tr("There was an error connecting to hushd. The error was") + ": \n\n" + err, QMessageBox::StandardButton::Ok ); shown = false; @@ -556,528 +522,498 @@ void Controller::getInfoThenRefresh(bool force) }); } -void Controller::refreshAddresses() -{ - if (!zrpc->haveConnection()) +void Controller::refreshAddresses() { + if (!zrpc - > haveConnection()) return noConnection(); - - auto newzaddresses = new QList(); - auto newtaddresses = new QList(); - zrpc->fetchAddresses([=] (json reply) { - auto zaddrs = reply["z_addresses"].get(); - for (auto& it : zaddrs) - { - auto addr = QString::fromStdString(it.get()); - newzaddresses->push_back(addr); + + auto newzaddresses = new QList < QString > (); + auto newtaddresses = new QList < QString > (); + zrpc - > fetchAddresses([ = ](json reply) { + auto zaddrs = reply["z_addresses"].get < json::array_t > (); + for (auto & it: zaddrs) { + auto addr = QString::fromStdString(it.get < json::string_t > ()); + newzaddresses - > push_back(addr); } - model->replaceZaddresses(newzaddresses); - auto taddrs = reply["t_addresses"].get(); - for (auto& it : taddrs) - { - auto addr = QString::fromStdString(it.get()); + model - > replaceZaddresses(newzaddresses); + auto taddrs = reply["t_addresses"].get < json::array_t > (); + for (auto & it: taddrs) { + auto addr = QString::fromStdString(it.get < json::string_t > ()); if (Settings::isTAddress(addr)) - newtaddresses->push_back(addr); + newtaddresses - > push_back(addr); } - model->replaceTaddresses(newtaddresses); + model - > replaceTaddresses(newtaddresses); // Refresh the sent and received txs from all these z-addresses refreshTransactions(); }); - + } // Function to create the data model and update the views, used below. -void Controller::updateUI(bool anyUnconfirmed) -{ - ui->unconfirmedWarning->setVisible(anyUnconfirmed); +void Controller::updateUI(bool anyUnconfirmed) { + ui - > unconfirmedWarning - > setVisible(anyUnconfirmed); // Update balances model data, which will update the table too - balancesTableModel->setNewData( - model->getAllZAddresses(), - model->getAllTAddresses(), - model->getAllBalances(), - model->getUTXOs() + balancesTableModel - > setNewData( + model - > getAllZAddresses(), + model - > getAllTAddresses(), + model - > getAllBalances(), + model - > getUTXOs() ); }; // Function to process reply of the listunspent and z_listunspent API calls, used below. -void Controller::processUnspent(const json& reply, QMap* balancesMap, QList* unspentOutputs) { - auto processFn = [=](const json& array) { - for (auto& it : array) - { - QString qsAddr = QString::fromStdString(it["address"]); - int block = it["created_in_block"].get(); - QString txid = QString::fromStdString(it["created_in_txid"]); - CAmount amount = CAmount::fromqint64(it["value"].get()); +void Controller::processUnspent(const json & reply, QMap < QString, CAmount > * balancesMap, QList < UnspentOutput > * unspentOutputs) { + auto processFn = [ = ](const json & array) { + for (auto & it: array) { + QString qsAddr = QString::fromStdString(it["address"]); + int block = it["created_in_block"].get < json::number_unsigned_t > (); + QString txid = QString::fromStdString(it["created_in_txid"]); + CAmount amount = CAmount::fromqint64(it["value"].get < json::number_unsigned_t > ()); - bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations - bool pending = !it["unconfirmed_spent"].is_null(); + bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations + bool pending = !it["unconfirmed_spent"].is_null(); - unspentOutputs->push_back( - UnspentOutput{ qsAddr, txid, amount, block, spendable, pending } + unspentOutputs - > push_back( + UnspentOutput { + qsAddr, + txid, + amount, + block, + spendable, + pending + } ); - if (spendable) - { - (*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] + - CAmount::fromqint64(it["value"].get()); + if (spendable) { + ( * balancesMap)[qsAddr] = ( * balancesMap)[qsAddr] + + CAmount::fromqint64(it["value"].get < json::number_unsigned_t > ()); } } }; - processFn(reply["unspent_notes"].get()); - processFn(reply["utxos"].get()); - processFn(reply["pending_notes"].get()); - processFn(reply["pending_utxos"].get()); + processFn(reply["unspent_notes"].get < json::array_t > ()); + processFn(reply["utxos"].get < json::array_t > ()); + processFn(reply["pending_notes"].get < json::array_t > ()); + processFn(reply["pending_utxos"].get < json::array_t > ()); }; -void Controller::updateUIBalances() -{ - CAmount balT = getModel()->getBalT(); - CAmount balZ = getModel()->getBalZ(); - CAmount balVerified = getModel()->getBalVerified(); +void Controller::updateUIBalances() { + CAmount balT = getModel() - > getBalT(); + CAmount balZ = getModel() - > getBalZ(); + CAmount balVerified = getModel() - > getBalVerified(); // Reduce the BalanceZ by the pending outgoing amount. We're adding // here because totalPending is already negative for outgoing txns. - balZ = balZ + getModel()->getTotalPending(); + balZ = balZ + getModel() - > getTotalPending(); - CAmount balTotal = balT + balZ; + CAmount balTotal = balT + balZ; CAmount balAvailable = balT + balVerified; - if (balZ < 0) + if (balZ < 0) balZ = CAmount::fromqint64(0); // Balances table - ui->balSheilded->setText(balZ.toDecimalhushString()); - ui->balVerified->setText(balVerified.toDecimalhushString()); - ui->balTransparent->setText(balT.toDecimalhushString()); - ui->balTotal->setText(balTotal.toDecimalhushString()); + ui - > balSheilded - > setText(balZ.toDecimalhushString()); + ui - > balVerified - > setText(balVerified.toDecimalhushString()); + ui - > balTransparent - > setText(balT.toDecimalhushString()); + ui - > balTotal - > setText(balTotal.toDecimalhushString()); - if (Settings::getInstance()->get_currency_name() == "USD") - { - ui->balSheilded->setToolTip(balZ.toDecimalUSDString()); - ui->balVerified->setToolTip(balVerified.toDecimalUSDString()); - ui->balTransparent->setToolTip(balT.toDecimalUSDString()); - ui->balTotal->setToolTip(balTotal.toDecimalUSDString()); + if (Settings::getInstance() - > get_currency_name() == "USD") { + ui - > balSheilded - > setToolTip(balZ.toDecimalUSDString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalUSDString()); + ui - > balTransparent - > setToolTip(balT.toDecimalUSDString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalUSDString()); - } - else if (Settings::getInstance()->get_currency_name() == "EUR") - { - ui->balSheilded->setToolTip(balZ.toDecimalEURString()); - ui->balVerified->setToolTip(balVerified.toDecimalEURString()); - ui->balTransparent->setToolTip(balT.toDecimalEURString()); - ui->balTotal->setToolTip(balTotal.toDecimalEURString()); + } else if (Settings::getInstance() - > get_currency_name() == "EUR") { + ui - > balSheilded - > setToolTip(balZ.toDecimalEURString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalEURString()); + ui - > balTransparent - > setToolTip(balT.toDecimalEURString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalEURString()); - } - else if (Settings::getInstance()->get_currency_name() == "BTC") - { - ui->balSheilded->setToolTip(balZ.toDecimalBTCString()); - ui->balVerified->setToolTip(balVerified.toDecimalBTCString()); - ui->balTransparent->setToolTip(balT.toDecimalBTCString()); - ui->balTotal->setToolTip(balTotal.toDecimalBTCString()); - - } - else if (Settings::getInstance()->get_currency_name() == "CNY") - { - ui->balSheilded->setToolTip(balZ.toDecimalCNYString()); - ui->balVerified->setToolTip(balVerified.toDecimalCNYString()); - ui->balTransparent->setToolTip(balT.toDecimalCNYString()); - ui->balTotal->setToolTip(balTotal.toDecimalCNYString()); + } else if (Settings::getInstance() - > get_currency_name() == "BTC") { + ui - > balSheilded - > setToolTip(balZ.toDecimalBTCString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalBTCString()); + ui - > balTransparent - > setToolTip(balT.toDecimalBTCString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalBTCString()); - } - else if (Settings::getInstance()->get_currency_name() == "RUB") - { - ui->balSheilded->setToolTip(balZ.toDecimalRUBString()); - ui->balVerified->setToolTip(balVerified.toDecimalRUBString()); - ui->balTransparent->setToolTip(balT.toDecimalRUBString()); - ui->balTotal->setToolTip(balTotal.toDecimalRUBString()); + } else if (Settings::getInstance() - > get_currency_name() == "CNY") { + ui - > balSheilded - > setToolTip(balZ.toDecimalCNYString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalCNYString()); + ui - > balTransparent - > setToolTip(balT.toDecimalCNYString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalCNYString()); - } - else if (Settings::getInstance()->get_currency_name() == "CAD") - { - ui->balSheilded->setToolTip(balZ.toDecimalCADString()); - ui->balVerified->setToolTip(balVerified.toDecimalCADString()); - ui->balTransparent->setToolTip(balT.toDecimalCADString()); - ui->balTotal->setToolTip(balTotal.toDecimalCADString()); + } else if (Settings::getInstance() - > get_currency_name() == "RUB") { + ui - > balSheilded - > setToolTip(balZ.toDecimalRUBString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalRUBString()); + ui - > balTransparent - > setToolTip(balT.toDecimalRUBString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalRUBString()); - } - else if (Settings::getInstance()->get_currency_name() == "SGD") - { - ui->balSheilded->setToolTip(balZ.toDecimalSGDString()); - ui->balVerified->setToolTip(balVerified.toDecimalSGDString()); - ui->balTransparent->setToolTip(balT.toDecimalSGDString()); - ui->balTotal->setToolTip(balTotal.toDecimalSGDString()); + } else if (Settings::getInstance() - > get_currency_name() == "CAD") { + ui - > balSheilded - > setToolTip(balZ.toDecimalCADString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalCADString()); + ui - > balTransparent - > setToolTip(balT.toDecimalCADString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalCADString()); - } - else if (Settings::getInstance()->get_currency_name() == "CHF") - { - ui->balSheilded->setToolTip(balZ.toDecimalCHFString()); - ui->balVerified->setToolTip(balVerified.toDecimalCHFString()); - ui->balTransparent->setToolTip(balT.toDecimalCHFString()); - ui->balTotal->setToolTip(balTotal.toDecimalCHFString()); + } else if (Settings::getInstance() - > get_currency_name() == "SGD") { + ui - > balSheilded - > setToolTip(balZ.toDecimalSGDString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalSGDString()); + ui - > balTransparent - > setToolTip(balT.toDecimalSGDString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalSGDString()); - } - else if (Settings::getInstance()->get_currency_name() == "INR") - { - ui->balSheilded->setToolTip(balZ.toDecimalINRString()); - ui->balVerified->setToolTip(balVerified.toDecimalINRString()); - ui->balTransparent->setToolTip(balT.toDecimalINRString()); - ui->balTotal->setToolTip(balTotal.toDecimalINRString()); + } else if (Settings::getInstance() - > get_currency_name() == "CHF") { + ui - > balSheilded - > setToolTip(balZ.toDecimalCHFString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalCHFString()); + ui - > balTransparent - > setToolTip(balT.toDecimalCHFString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalCHFString()); - } - else if (Settings::getInstance()->get_currency_name() == "GBP") - { - ui->balSheilded ->setToolTip(balZ.toDecimalGBPString()); - ui->balVerified ->setToolTip(balVerified.toDecimalGBPString()); - ui->balTransparent->setToolTip(balT.toDecimalGBPString()); - ui->balTotal ->setToolTip(balTotal.toDecimalGBPString()); + } else if (Settings::getInstance() - > get_currency_name() == "INR") { + ui - > balSheilded - > setToolTip(balZ.toDecimalINRString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalINRString()); + ui - > balTransparent - > setToolTip(balT.toDecimalINRString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalINRString()); - } - else if (Settings::getInstance()->get_currency_name() == "AUD") - { - ui->balSheilded ->setToolTip(balZ.toDecimalAUDString()); - ui->balVerified ->setToolTip(balVerified.toDecimalAUDString()); - ui->balTransparent->setToolTip(balT.toDecimalAUDString()); - ui->balTotal ->setToolTip(balTotal.toDecimalAUDString()); + } else if (Settings::getInstance() - > get_currency_name() == "GBP") { + ui - > balSheilded - > setToolTip(balZ.toDecimalGBPString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalGBPString()); + ui - > balTransparent - > setToolTip(balT.toDecimalGBPString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalGBPString()); + + } else if (Settings::getInstance() - > get_currency_name() == "AUD") { + ui - > balSheilded - > setToolTip(balZ.toDecimalAUDString()); + ui - > balVerified - > setToolTip(balVerified.toDecimalAUDString()); + ui - > balTransparent - > setToolTip(balT.toDecimalAUDString()); + ui - > balTotal - > setToolTip(balTotal.toDecimalAUDString()); } // Send tab - ui->txtAvailablehush->setText(balAvailable.toDecimalhushString()); + ui - > txtAvailablehush - > setText(balAvailable.toDecimalhushString()); - if (Settings::getInstance()->get_currency_name() == "USD") - ui->txtAvailableUSD->setText(balAvailable.toDecimalUSDString()); + if (Settings::getInstance() - > get_currency_name() == "USD") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalUSDString()); - else if (Settings::getInstance()->get_currency_name() == "EUR") - ui->txtAvailableUSD->setText(balAvailable.toDecimalEURString()); + else if (Settings::getInstance() - > get_currency_name() == "EUR") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalEURString()); - else if (Settings::getInstance()->get_currency_name() == "BTC") - ui->txtAvailableUSD->setText(balAvailable.toDecimalBTCString()); + else if (Settings::getInstance() - > get_currency_name() == "BTC") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalBTCString()); - else if (Settings::getInstance()->get_currency_name() == "CNY") - ui->txtAvailableUSD->setText(balAvailable.toDecimalCNYString()); + else if (Settings::getInstance() - > get_currency_name() == "CNY") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalCNYString()); - else if (Settings::getInstance()->get_currency_name() == "RUB") - ui->txtAvailableUSD->setText(balAvailable.toDecimalRUBString()); + else if (Settings::getInstance() - > get_currency_name() == "RUB") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalRUBString()); - else if (Settings::getInstance()->get_currency_name() == "CAD") - ui->txtAvailableUSD->setText(balAvailable.toDecimalCADString()); + else if (Settings::getInstance() - > get_currency_name() == "CAD") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalCADString()); - else if (Settings::getInstance()->get_currency_name() == "SGD") - ui->txtAvailableUSD->setText(balAvailable.toDecimalSGDString()); + else if (Settings::getInstance() - > get_currency_name() == "SGD") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalSGDString()); - else if (Settings::getInstance()->get_currency_name() == "CHF") - ui->txtAvailableUSD->setText(balAvailable.toDecimalCHFString()); + else if (Settings::getInstance() - > get_currency_name() == "CHF") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalCHFString()); - else if (Settings::getInstance()->get_currency_name() == "INR") - ui->txtAvailableUSD->setText(balAvailable.toDecimalINRString()); + else if (Settings::getInstance() - > get_currency_name() == "INR") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalINRString()); - else if (Settings::getInstance()->get_currency_name() == "GBP") - ui->txtAvailableUSD->setText(balAvailable.toDecimalGBPString()); + else if (Settings::getInstance() - > get_currency_name() == "GBP") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalGBPString()); - else if (Settings::getInstance()->get_currency_name() == "AUD") - ui->txtAvailableUSD->setText(balAvailable.toDecimalAUDString()); + else if (Settings::getInstance() - > get_currency_name() == "AUD") + ui - > txtAvailableUSD - > setText(balAvailable.toDecimalAUDString()); } -void Controller::refreshBalances() -{ - if (!zrpc->haveConnection()) +void Controller::refreshBalances() { + if (!zrpc - > haveConnection()) return noConnection(); // 1. Get the Balances - zrpc->fetchBalance([=] (json reply) { - CAmount balT = CAmount::fromqint64(reply["tbalance"].get()); - CAmount balZ = CAmount::fromqint64(reply["zbalance"].get()); - CAmount balVerified = CAmount::fromqint64(reply["verified_zbalance"].get()); - - model->setBalT(balT); - model->setBalZ(balZ); - model->setBalVerified(balVerified); + zrpc - > fetchBalance([ = ](json reply) { + CAmount balT = CAmount::fromqint64(reply["tbalance"].get < json::number_unsigned_t > ()); + CAmount balZ = CAmount::fromqint64(reply["zbalance"].get < json::number_unsigned_t > ()); + CAmount balVerified = CAmount::fromqint64(reply["verified_zbalance"].get < json::number_unsigned_t > ()); + + model - > setBalT(balT); + model - > setBalZ(balZ); + model - > setBalVerified(balVerified); // This is for the websockets - AppDataModel::getInstance()->setBalances(balT, balZ); - + AppDataModel::getInstance() - > setBalances(balT, balZ); + // This is for the datamodel CAmount balAvailable = balT + balVerified; - model->setAvailableBalance(balAvailable); + model - > setAvailableBalance(balAvailable); updateUIBalances(); }); // 2. Get the UTXOs // First, create a new UTXO list. It will be replacing the existing list when everything is processed. - auto newUnspentOutputs = new QList(); - auto newBalances = new QMap(); + auto newUnspentOutputs = new QList < UnspentOutput > (); + auto newBalances = new QMap < QString, CAmount > (); // Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI - zrpc->fetchUnspent([=] (json reply) { + zrpc - > fetchUnspent([ = ](json reply) { processUnspent(reply, newBalances, newUnspentOutputs); // Swap out the balances and UTXOs - model->replaceBalances(newBalances); - model->replaceUTXOs(newUnspentOutputs); + model - > replaceBalances(newBalances); + model - > replaceUTXOs(newUnspentOutputs); // Find if any output is not spendable or is pending bool anyUnconfirmed = std::find_if( - newUnspentOutputs->constBegin(), - newUnspentOutputs->constEnd(), - [=](const UnspentOutput& u) -> bool { - return !u.spendable || u.pending; + newUnspentOutputs - > constBegin(), + newUnspentOutputs - > constEnd(), + [ = ](const UnspentOutput & u) - > bool { + return !u.spendable || u.pending; } - ) != newUnspentOutputs->constEnd(); + ) != newUnspentOutputs - > constEnd(); updateUI(anyUnconfirmed); - main->balancesReady(); + main - > balancesReady(); }); } -void Controller::refreshTransactions() { - if (!zrpc->haveConnection()) +void Controller::refreshTransactions() { + if (!zrpc - > haveConnection()) return noConnection(); - zrpc->fetchTransactions([=] (json reply) { - QList txdata; + zrpc - > fetchTransactions([ = ](json reply) { + QList < TransactionItem > txdata; - for (auto& it : reply.get()) { + for (auto & it: reply.get < json::array_t > ()) { QString address; CAmount total_amount; - QList items; + QList < TransactionItemDetail > items; long confirmations; - if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get()) { + if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get < json::boolean_t > ()) { confirmations = 0; } else { - confirmations = model->getLatestBlock() - it["block_height"].get() + 1; + confirmations = model - > getLatestBlock() - it["block_height"].get < json::number_integer_t > () + 1; } - + auto txid = QString::fromStdString(it["txid"]); - auto datetime = it["datetime"].get(); - + auto datetime = it["datetime"].get < json::number_integer_t > (); + // First, check if there's outgoing metadata if (!it["outgoing_metadata"].is_null()) { - - for (auto o: it["outgoing_metadata"].get()) { - - QString address; - + + for (auto o: it["outgoing_metadata"].get < json::array_t > ()) { + + QString address; address = QString::fromStdString(o["address"]); - + // Sent items are -ve - CAmount amount = CAmount::fromqint64(-1* o["value"].get()); - - // Check for Memos - + CAmount amount = CAmount::fromqint64(-1 * o["value"].get < json::number_unsigned_t > ()); + + // Check for Memos + QString memo; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - - QString cid; + QString cid; ChatItem item = ChatItem( - datetime, - address, - QString(""), - memo, - QString(""), - QString(""), - cid, - txid, - true - ); - qDebug()<<"Memo : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - - } - - items.push_back(TransactionItemDetail{address, amount, memo}); + DataStore::getChatDataStore() - > setData(ChatIDGenerator::getInstance() - > generateID(item), item); + + } + + items.push_back(TransactionItemDetail { + address, + amount, + memo + }); total_amount = total_amount + amount; } - { - QList addresses; - for (auto item : items) { - // Concat all the addresses - - - addresses.push_back(item.address); - address = addresses.join(","); + QList < QString > addresses; + for (auto item: items) { + // Concat all the addresses + + addresses.push_back(item.address); + address = addresses.join(","); } - - } - - txdata.push_back(TransactionItem{ - "send", datetime, address, txid,confirmations, items + + } + + txdata.push_back(TransactionItem { + "send", + datetime, + address, + txid, + confirmations, + items }); - + } else { // Incoming Transaction address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); - model->markAddressUsed(address); + model - > markAddressUsed(address); QString memo; - QString test; if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); } - items.push_back(TransactionItemDetail{ + items.push_back(TransactionItemDetail { address, - CAmount::fromqint64(it["amount"].get()), + CAmount::fromqint64(it["amount"].get < json::number_integer_t > ()), memo }); - - TransactionItem tx{ - "Receive", datetime, address, txid,confirmations, items + TransactionItem tx { + "Receive", + datetime, + address, + txid, + confirmations, + items }; txdata.push_back(tx); - - QString type; - QString cid; - // int position; - QString requestZaddr; - if ((memo.startsWith("{")) && (!it["memo"].is_null())) { + QString type; + QString cid; + int position; + QString requestZaddr; - QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); + if (!it["memo"].is_null()) { - cid = headermemo["cid"].toString(); - type = headermemo["t"].toString(); - requestZaddr = headermemo["z"].toString(); + if (memo.startsWith("{")) { - chatModel->addCid(txid, cid); - chatModel->addrequestZaddr(txid, requestZaddr); + QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); - // } - - if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ + cid = headermemo["cid"].toString(); + type = headermemo["t"].toString(); + requestZaddr = headermemo["z"].toString(); - cid = chatModel->getCidByTx(txid); + chatModel - > addCid(txid, cid); + chatModel - > addrequestZaddr(txid, requestZaddr); - } - else{ - - cid = ""; } - - if (chatModel->getrequestZaddrByTx(txid) != QString("0xdeadbeef")){ - requestZaddr = chatModel->getrequestZaddrByTx(txid); + if (chatModel - > getCidByTx(txid) != QString("0xdeadbeef")) { - } - - else{ - requestZaddr = ""; - } - - - // position = it["position"].get(); + cid = chatModel - > getCidByTx(txid); + } else { + cid = ""; + } + + if (chatModel - > getrequestZaddrByTx(txid) != QString("0xdeadbeef")) { + + requestZaddr = chatModel - > getrequestZaddrByTx(txid); + } else { + requestZaddr = ""; + } + position = it["position"].get < json::number_integer_t > (); ChatItem item = ChatItem( - datetime, - address, - QString(""), - memo, - requestZaddr, - type, - cid, - txid, - false - ); - qDebug()<<"CID : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - } + datetime, + address, + QString(""), + memo, + requestZaddr, + type, + cid, + txid, + false + ); + qDebug() << "Position : " << position; + + DataStore::getChatDataStore() - > setData(ChatIDGenerator::getInstance() - > generateID(item), item); + } } - + } // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds CAmount totalPending; - for (auto txitem : txdata) { + for (auto txitem: txdata) { if (txitem.confirmations == 0) { for (auto item: txitem.items) { totalPending = totalPending + item.amount; } } } - getModel()->setTotalPending(totalPending); + getModel() - > setTotalPending(totalPending); // Update UI Balance updateUIBalances(); - // Update model data, which updates the table view - transactionsTableModel->replaceData(txdata); - chat->renderChatBox(ui, ui->listChat); + // Update model data, which updates the table view + transactionsTableModel - > replaceData(txdata); + chat - > renderChatBox(ui, ui - > listChat); refreshContacts( - ui->listContactWidget - + ui - > listContactWidget + ); - }); + }); } -void Controller::refreshChat(QListView *listWidget) -{ - chat->renderChatBox(ui, listWidget); - +void Controller::refreshChat(QListView * listWidget) { + chat - > renderChatBox(ui, listWidget); + } -void Controller::refreshContacts(QListView *listWidget) -{ - contactModel->renderContactList(listWidget); +void Controller::refreshContacts(QListView * listWidget) { + contactModel - > renderContactList(listWidget); } // If the wallet is encrpyted and locked, we need to unlock it -void Controller::unlockIfEncrypted(std::function cb, std::function error) -{ - auto encStatus = getModel()->getEncryptionStatus(); - if (encStatus.first && encStatus.second) - { +void Controller::unlockIfEncrypted(std:: function < void(void) > cb, std:: function < void(void) > error) { + auto encStatus = getModel() - > getEncryptionStatus(); + if (encStatus.first && encStatus.second) { // Wallet is encrypted and locked. Ask for the password and unlock. QString password = QInputDialog::getText( - main, - main->tr("Wallet Password"), - main->tr("Your wallet is encrypted.\nPlease enter your wallet password"), + main, + main - > tr("Wallet Password"), + main - > tr("Your wallet is encrypted.\nPlease enter your wallet password"), QLineEdit::Password ); - if (password.isEmpty()) - { + if (password.isEmpty()) { QMessageBox::critical( - main, - main->tr("Wallet Decryption Failed"), - main->tr("Please enter a valid password"), + main, + main - > tr("Wallet Decryption Failed"), + main - > tr("Please enter a valid password"), QMessageBox::Ok ); error(); return; } - zrpc->unlockWallet(password, [=](json reply) { - if (isJsonResultSuccess(reply)) - { + zrpc - > unlockWallet(password, [ = ](json reply) { + if (isJsonResultSuccess(reply)) { cb(); // Refresh the wallet so the encryption status is now in sync. refresh(true); - } - else - { + } else { QMessageBox::critical( - main, - main->tr("Wallet Decryption Failed"), - QString::fromStdString(reply["error"].get()), + main, + main - > tr("Wallet Decryption Failed"), + QString::fromStdString(reply["error"].get < json::string_t > ()), QMessageBox::Ok ); error(); } }); - } - else - { + } else { // Not locked, so just call the function cb(); } @@ -1087,86 +1023,75 @@ void Controller::unlockIfEncrypted(std::function cb, std::functionstatusBar->showMessage(Settings::txidStatusMessage + " " + txid); +void Controller::executeStandardUITransaction(Tx tx) { + executeTransaction(tx, [ = ](QString txid) { + ui - > statusBar - > showMessage(Settings::txidStatusMessage + " " + txid); }, - [=] (QString opid, QString errStr) { - ui->statusBar->showMessage( + [ = ](QString opid, QString errStr) { + ui - > statusBar - > showMessage( QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000 ); if (!opid.isEmpty()) - errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; + errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; QMessageBox::critical( - main, - QObject::tr("Transaction Error"), - errStr, + main, + QObject::tr("Transaction Error"), + errStr, QMessageBox::Ok - ); + ); } ); } - // Execute a transaction! -void Controller::executeTransaction(Tx tx, - const std::function submitted, - const std::function error) -{ - unlockIfEncrypted([=] () { +void Controller::executeTransaction(Tx tx, + const std:: function < void(QString txid) > submitted, + const std:: function < void(QString txid, QString errStr) > error) { + unlockIfEncrypted([ = ]() { // First, create the json params json params = json::array(); fillTxJsonParams(params, tx); std::cout << std::setw(2) << params << std::endl; - zrpc->sendTransaction(QString::fromStdString(params.dump()), [=](const json& reply) { - if (reply.find("txid") == reply.end()) - { - error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump())); - } - else - { - QString txid = QString::fromStdString(reply["txid"].get()); - submitted(txid); - } - }, - [=](QString errStr) { - error("", errStr); - }); - }, [=]() { - error("", main->tr("Failed to unlock wallet")); + zrpc - > sendTransaction(QString::fromStdString(params.dump()), [ = ](const json & reply) { + if (reply.find("txid") == reply.end()) { + error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump())); + } else { + QString txid = QString::fromStdString(reply["txid"].get < json::string_t > ()); + submitted(txid); + } + }, + [ = ](QString errStr) { + error("", errStr); + }); + }, [ = ]() { + error("", main - > tr("Failed to unlock wallet")); }); } - -void Controller::checkForUpdate(bool silent) -{ - if (!zrpc->haveConnection()) +void Controller::checkForUpdate(bool silent) { + if (!zrpc - > haveConnection()) return noConnection(); QUrl cmcURL("https://api.github.com/repos/MyHush/SilentDragonLite/releases"); QNetworkRequest req; req.setUrl(cmcURL); - - QNetworkAccessManager *manager = new QNetworkAccessManager(this->main); - QNetworkReply *reply = manager->get(req); - QObject::connect(reply, &QNetworkReply::finished, [=] { - reply->deleteLater(); - manager->deleteLater(); + QNetworkAccessManager * manager = new QNetworkAccessManager(this - > main); + QNetworkReply * reply = manager - > get(req); - try - { - if (reply->error() == QNetworkReply::NoError) - { - auto releases = QJsonDocument::fromJson(reply->readAll()).array(); + QObject::connect(reply, & QNetworkReply::finished, [ = ] { + reply - > deleteLater(); + manager - > deleteLater(); + + try { + if (reply - > error() == QNetworkReply::NoError) { + auto releases = QJsonDocument::fromJson(reply - > readAll()).array(); QVersionNumber maxVersion(0, 0, 0); - for (QJsonValue rel : releases) - { + for (QJsonValue rel: releases) { if (!rel.toObject().contains("tag_name")) continue; @@ -1174,8 +1099,7 @@ void Controller::checkForUpdate(bool silent) if (tag.startsWith("v")) tag = tag.right(tag.length() - 1); - if (!tag.isEmpty()) - { + if (!tag.isEmpty()) { auto v = QVersionNumber::fromString(tag); if (v > maxVersion) maxVersion = v; @@ -1183,418 +1107,367 @@ void Controller::checkForUpdate(bool silent) } auto currentVersion = QVersionNumber::fromString(APP_VERSION); - + // Get the max version that the user has hidden updates for QSettings s; auto maxHiddenVersion = QVersionNumber::fromString( - s.value("update/lastversion", "0.0.0" - ).toString()); + s.value("update/lastversion", "0.0.0").toString()); qDebug() << "Version check: Current " << currentVersion << ", Available " << maxVersion; - if (maxVersion > currentVersion && (!silent || maxVersion > maxHiddenVersion)) - { - auto ans = QMessageBox::information(main, QObject::tr("Update Available"), + if (maxVersion > currentVersion && (!silent || maxVersion > maxHiddenVersion)) { + auto ans = QMessageBox::information(main, QObject::tr("Update Available"), QObject::tr("A new release v%1 is available! You have v%2.\n\nWould you like to visit the releases page?") - .arg(maxVersion.toString()) - .arg(currentVersion.toString()), + .arg(maxVersion.toString()) + .arg(currentVersion.toString()), QMessageBox::Yes, QMessageBox::Cancel); - if (ans == QMessageBox::Yes) - { + if (ans == QMessageBox::Yes) { QDesktopServices::openUrl(QUrl("https://github.com/MyHush/SilentDragonLite/releases")); - } - else - { + } else { // If the user selects cancel, don't bother them again for this version s.setValue("update/lastversion", maxVersion.toString()); } - } - else - { - if (!silent) - { - QMessageBox::information(main, QObject::tr("No updates available"), + } else { + if (!silent) { + QMessageBox::information(main, QObject::tr("No updates available"), QObject::tr("You already have the latest release v%1") - .arg(currentVersion.toString())); + .arg(currentVersion.toString())); } - } + } } - } - catch (...) - { + } catch (...) { // If anything at all goes wrong, just set the price to 0 and move on. qDebug() << QString("Caught something nasty"); - } + } }); } // Get the hush->USD price from coinmarketcap using their API -void Controller::refreshZECPrice() -{ - if (!zrpc->haveConnection()) +void Controller::refreshZECPrice() { + if (!zrpc - > haveConnection()) return noConnection(); - // TODO: use/render all this data + // TODO: use/render all this data QUrl cmcURL("https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur%2Ceth%2Cgbp%2Ccny%2Cjpy%2Crub%2Ccad%2Csgd%2Cchf%2Cinr%2Caud%2Cinr&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true"); - + QNetworkRequest req; req.setUrl(cmcURL); - QNetworkAccessManager *manager = new QNetworkAccessManager(this->main); - QNetworkReply *reply = manager->get(req); - QObject::connect(reply, &QNetworkReply::finished, [=] { - reply->deleteLater(); - manager->deleteLater(); + QNetworkAccessManager * manager = new QNetworkAccessManager(this - > main); + QNetworkReply * reply = manager - > get(req); + QObject::connect(reply, & QNetworkReply::finished, [ = ] { + reply - > deleteLater(); + manager - > deleteLater(); - try - { - if (reply->error() != QNetworkReply::NoError) - { - auto parsed = json::parse(reply->readAll(), nullptr, false); - if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) + 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(); + qDebug() << reply - > errorString(); - Settings::getInstance()->setZECPrice(0); - Settings::getInstance()->setEURPrice(0); - Settings::getInstance()->setBTCPrice(0); - Settings::getInstance()->setCNYPrice(0); - Settings::getInstance()->setRUBPrice(0); - Settings::getInstance()->setCADPrice(0); - Settings::getInstance()->setSGDPrice(0); - Settings::getInstance()->setCHFPrice(0); - Settings::getInstance()->setGBPPrice(0); - Settings::getInstance()->setAUDPrice(0); - Settings::getInstance()->setINRPrice(0); - Settings::getInstance()->setUSDVolume(0); - Settings::getInstance()->setEURVolume(0); - Settings::getInstance()->setBTCVolume(0); - Settings::getInstance()->setCNYVolume(0); - Settings::getInstance()->setRUBVolume(0); - Settings::getInstance()->setCADVolume(0); - Settings::getInstance()->setINRVolume(0); - Settings::getInstance()->setSGDVolume(0); - Settings::getInstance()->setCHFVolume(0); - Settings::getInstance()->setGBPVolume(0); - Settings::getInstance()->setAUDVolume(0); - Settings::getInstance()->setUSDCAP(0); - Settings::getInstance()->setEURCAP(0); - Settings::getInstance()->setBTCCAP(0); - Settings::getInstance()->setCNYCAP(0); - Settings::getInstance()->setRUBCAP(0); - Settings::getInstance()->setCADCAP(0); - Settings::getInstance()->setINRCAP(0); - Settings::getInstance()->setSGDCAP(0); - Settings::getInstance()->setCHFCAP(0); - Settings::getInstance()->setGBPCAP(0); - Settings::getInstance()->setAUDCAP(0); + Settings::getInstance() - > setZECPrice(0); + Settings::getInstance() - > setEURPrice(0); + Settings::getInstance() - > setBTCPrice(0); + Settings::getInstance() - > setCNYPrice(0); + Settings::getInstance() - > setRUBPrice(0); + Settings::getInstance() - > setCADPrice(0); + Settings::getInstance() - > setSGDPrice(0); + Settings::getInstance() - > setCHFPrice(0); + Settings::getInstance() - > setGBPPrice(0); + Settings::getInstance() - > setAUDPrice(0); + Settings::getInstance() - > setINRPrice(0); + Settings::getInstance() - > setUSDVolume(0); + Settings::getInstance() - > setEURVolume(0); + Settings::getInstance() - > setBTCVolume(0); + Settings::getInstance() - > setCNYVolume(0); + Settings::getInstance() - > setRUBVolume(0); + Settings::getInstance() - > setCADVolume(0); + Settings::getInstance() - > setINRVolume(0); + Settings::getInstance() - > setSGDVolume(0); + Settings::getInstance() - > setCHFVolume(0); + Settings::getInstance() - > setGBPVolume(0); + Settings::getInstance() - > setAUDVolume(0); + Settings::getInstance() - > setUSDCAP(0); + Settings::getInstance() - > setEURCAP(0); + Settings::getInstance() - > setBTCCAP(0); + Settings::getInstance() - > setCNYCAP(0); + Settings::getInstance() - > setRUBCAP(0); + Settings::getInstance() - > setCADCAP(0); + Settings::getInstance() - > setINRCAP(0); + Settings::getInstance() - > setSGDCAP(0); + Settings::getInstance() - > setCHFCAP(0); + Settings::getInstance() - > setGBPCAP(0); + Settings::getInstance() - > setAUDCAP(0); return; } qDebug() << "No network errors"; - auto all = reply->readAll(); + auto all = reply - > readAll(); auto parsed = json::parse(all, nullptr, false); - if (parsed.is_discarded()) - { - Settings::getInstance()->setZECPrice(0); - Settings::getInstance()->setEURPrice(0); - Settings::getInstance()->setBTCPrice(0); - Settings::getInstance()->setCNYPrice(0); - Settings::getInstance()->setRUBPrice(0); - Settings::getInstance()->setCADPrice(0); - Settings::getInstance()->setSGDPrice(0); - Settings::getInstance()->setCHFPrice(0); - Settings::getInstance()->setGBPPrice(0); - Settings::getInstance()->setAUDPrice(0); - Settings::getInstance()->setINRPrice(0); - Settings::getInstance()->setUSDVolume(0); - Settings::getInstance()->setEURVolume(0); - Settings::getInstance()->setBTCVolume(0); - Settings::getInstance()->setCNYVolume(0); - Settings::getInstance()->setRUBVolume(0); - Settings::getInstance()->setCADVolume(0); - Settings::getInstance()->setINRVolume(0); - Settings::getInstance()->setSGDVolume(0); - Settings::getInstance()->setCHFVolume(0); - Settings::getInstance()->setGBPVolume(0); - Settings::getInstance()->setAUDVolume(0); - Settings::getInstance()->setUSDCAP(0); - Settings::getInstance()->setEURCAP(0); - Settings::getInstance()->setBTCCAP(0); - Settings::getInstance()->setCNYCAP(0); - Settings::getInstance()->setRUBCAP(0); - Settings::getInstance()->setCADCAP(0); - Settings::getInstance()->setINRCAP(0); - Settings::getInstance()->setSGDCAP(0); - Settings::getInstance()->setCHFCAP(0); - Settings::getInstance()->setGBPCAP(0); - Settings::getInstance()->setAUDCAP(0); + if (parsed.is_discarded()) { + Settings::getInstance() - > setZECPrice(0); + Settings::getInstance() - > setEURPrice(0); + Settings::getInstance() - > setBTCPrice(0); + Settings::getInstance() - > setCNYPrice(0); + Settings::getInstance() - > setRUBPrice(0); + Settings::getInstance() - > setCADPrice(0); + Settings::getInstance() - > setSGDPrice(0); + Settings::getInstance() - > setCHFPrice(0); + Settings::getInstance() - > setGBPPrice(0); + Settings::getInstance() - > setAUDPrice(0); + Settings::getInstance() - > setINRPrice(0); + Settings::getInstance() - > setUSDVolume(0); + Settings::getInstance() - > setEURVolume(0); + Settings::getInstance() - > setBTCVolume(0); + Settings::getInstance() - > setCNYVolume(0); + Settings::getInstance() - > setRUBVolume(0); + Settings::getInstance() - > setCADVolume(0); + Settings::getInstance() - > setINRVolume(0); + Settings::getInstance() - > setSGDVolume(0); + Settings::getInstance() - > setCHFVolume(0); + Settings::getInstance() - > setGBPVolume(0); + Settings::getInstance() - > setAUDVolume(0); + Settings::getInstance() - > setUSDCAP(0); + Settings::getInstance() - > setEURCAP(0); + Settings::getInstance() - > setBTCCAP(0); + Settings::getInstance() - > setCNYCAP(0); + Settings::getInstance() - > setRUBCAP(0); + Settings::getInstance() - > setCADCAP(0); + Settings::getInstance() - > setINRCAP(0); + Settings::getInstance() - > setSGDCAP(0); + Settings::getInstance() - > setCHFCAP(0); + Settings::getInstance() - > setGBPCAP(0); + Settings::getInstance() - > setAUDCAP(0); return; } qDebug() << "Parsed JSON"; - const json& item = parsed.get(); - const json& hush = item["hush"].get(); + const json & item = parsed.get < json::object_t > (); + const json & hush = item["hush"].get < json::object_t > (); - if (hush["usd"] >= 0) - { + if (hush["usd"] >= 0) { qDebug() << "Found hush key in price json"; - qDebug() << "HUSH = $" << QString::number((double)hush["usd"]); - Settings::getInstance()->setZECPrice( hush["usd"] ); + qDebug() << "HUSH = $" << QString::number((double) hush["usd"]); + Settings::getInstance() - > setZECPrice(hush["usd"]); } - if (hush["eur"] >= 0) - { - qDebug() << "HUSH = €" << QString::number((double)hush["eur"]); - Settings::getInstance()->setEURPrice(hush["eur"]); + if (hush["eur"] >= 0) { + qDebug() << "HUSH = €" << QString::number((double) hush["eur"]); + Settings::getInstance() - > setEURPrice(hush["eur"]); } - if (hush["btc"] >= 0) - { - qDebug() << "HUSH = BTC" << QString::number((double)hush["btc"]); - Settings::getInstance()->setBTCPrice( hush["btc"]); + if (hush["btc"] >= 0) { + qDebug() << "HUSH = BTC" << QString::number((double) hush["btc"]); + Settings::getInstance() - > setBTCPrice(hush["btc"]); } - if (hush["cny"] >= 0) - { - qDebug() << "HUSH = CNY" << QString::number((double)hush["cny"]); - Settings::getInstance()->setCNYPrice( hush["cny"]); + if (hush["cny"] >= 0) { + qDebug() << "HUSH = CNY" << QString::number((double) hush["cny"]); + Settings::getInstance() - > setCNYPrice(hush["cny"]); } - if (hush["rub"] >= 0) - { - qDebug() << "HUSH = RUB" << QString::number((double)hush["rub"]); - Settings::getInstance()->setRUBPrice( hush["rub"]); + if (hush["rub"] >= 0) { + qDebug() << "HUSH = RUB" << QString::number((double) hush["rub"]); + Settings::getInstance() - > setRUBPrice(hush["rub"]); } - if (hush["cad"] >= 0) - { - qDebug() << "HUSH = CAD" << QString::number((double)hush["cad"]); - Settings::getInstance()->setCADPrice( hush["cad"]); + if (hush["cad"] >= 0) { + qDebug() << "HUSH = CAD" << QString::number((double) hush["cad"]); + Settings::getInstance() - > setCADPrice(hush["cad"]); } - if (hush["sgd"] >= 0) - { - qDebug() << "HUSH = SGD" << QString::number((double)hush["sgd"]); - Settings::getInstance()->setSGDPrice( hush["sgd"]); + if (hush["sgd"] >= 0) { + qDebug() << "HUSH = SGD" << QString::number((double) hush["sgd"]); + Settings::getInstance() - > setSGDPrice(hush["sgd"]); } - if (hush["chf"] >= 0) - { - qDebug() << "HUSH = CHF" << QString::number((double)hush["chf"]); - Settings::getInstance()->setCHFPrice( hush["chf"]); + if (hush["chf"] >= 0) { + qDebug() << "HUSH = CHF" << QString::number((double) hush["chf"]); + Settings::getInstance() - > setCHFPrice(hush["chf"]); } - if (hush["inr"] >= 0) - { - qDebug() << "HUSH = INR" << QString::number((double)hush["inr"]); - Settings::getInstance()->setINRPrice( hush["inr"]); + if (hush["inr"] >= 0) { + qDebug() << "HUSH = INR" << QString::number((double) hush["inr"]); + Settings::getInstance() - > setINRPrice(hush["inr"]); } - if (hush["gbp"] >= 0) - { - qDebug() << "HUSH = GBP" << QString::number((double)hush["gbp"]); - Settings::getInstance()->setGBPPrice( hush["gbp"]); + if (hush["gbp"] >= 0) { + qDebug() << "HUSH = GBP" << QString::number((double) hush["gbp"]); + Settings::getInstance() - > setGBPPrice(hush["gbp"]); } - if (hush["aud"] >= 0) - { - qDebug() << "HUSH = AUD" << QString::number((double)hush["aud"]); - Settings::getInstance()->setAUDPrice( hush["aud"]); + if (hush["aud"] >= 0) { + qDebug() << "HUSH = AUD" << QString::number((double) hush["aud"]); + Settings::getInstance() - > setAUDPrice(hush["aud"]); } - if (hush["btc_24h_vol"] >= 0) - { - qDebug() << "HUSH = usd_24h_vol" << QString::number((double)hush["usd_24h_vol"]); - Settings::getInstance()->setUSDVolume( hush["usd_24h_vol"]); + if (hush["btc_24h_vol"] >= 0) { + qDebug() << "HUSH = usd_24h_vol" << QString::number((double) hush["usd_24h_vol"]); + Settings::getInstance() - > setUSDVolume(hush["usd_24h_vol"]); } - if (hush["btc_24h_vol"] >= 0) - { - qDebug() << "HUSH = euro_24h_vol" << QString::number((double)hush["eur_24h_vol"]); - Settings::getInstance()->setEURVolume( hush["eur_24h_vol"]); + if (hush["btc_24h_vol"] >= 0) { + qDebug() << "HUSH = euro_24h_vol" << QString::number((double) hush["eur_24h_vol"]); + Settings::getInstance() - > setEURVolume(hush["eur_24h_vol"]); } - if (hush["btc_24h_vol"] >= 0) - { - qDebug() << "HUSH = btc_24h_vol" << QString::number((double)hush["btc_24h_vol"]); - Settings::getInstance()->setBTCVolume( hush["btc_24h_vol"]); - } - - if (hush["cny_24h_vol"] >= 0) - { - qDebug() << "HUSH = cny_24h_vol" << QString::number((double)hush["cny_24h_vol"]); - Settings::getInstance()->setCNYVolume( hush["cny_24h_vol"]); + if (hush["btc_24h_vol"] >= 0) { + qDebug() << "HUSH = btc_24h_vol" << QString::number((double) hush["btc_24h_vol"]); + Settings::getInstance() - > setBTCVolume(hush["btc_24h_vol"]); } - if (hush["rub_24h_vol"] >= 0) - { - qDebug() << "HUSH = rub_24h_vol" << QString::number((double)hush["rub_24h_vol"]); - Settings::getInstance()->setRUBVolume( hush["rub_24h_vol"]); - } - - if (hush["cad_24h_vol"] >= 0) - { - qDebug() << "HUSH = cad_24h_vol" << QString::number((double)hush["cad_24h_vol"]); - Settings::getInstance()->setCADVolume( hush["cad_24h_vol"]); + if (hush["cny_24h_vol"] >= 0) { + qDebug() << "HUSH = cny_24h_vol" << QString::number((double) hush["cny_24h_vol"]); + Settings::getInstance() - > setCNYVolume(hush["cny_24h_vol"]); } - if (hush["sgd_24h_vol"] >= 0) - { - qDebug() << "HUSH = sgd_24h_vol" << QString::number((double)hush["sgd_24h_vol"]); - Settings::getInstance()->setSGDVolume( hush["sgd_24h_vol"]); + if (hush["rub_24h_vol"] >= 0) { + qDebug() << "HUSH = rub_24h_vol" << QString::number((double) hush["rub_24h_vol"]); + Settings::getInstance() - > setRUBVolume(hush["rub_24h_vol"]); } - if (hush["chf_24h_vol"] >= 0) - { - qDebug() << "HUSH = chf_24h_vol" << QString::number((double)hush["chf_24h_vol"]); - Settings::getInstance()->setCHFVolume( hush["chf_24h_vol"]); + if (hush["cad_24h_vol"] >= 0) { + qDebug() << "HUSH = cad_24h_vol" << QString::number((double) hush["cad_24h_vol"]); + Settings::getInstance() - > setCADVolume(hush["cad_24h_vol"]); } - if (hush["inr_24h_vol"] >= 0) - { - qDebug() << "HUSH = inr_24h_vol" << QString::number((double)hush["inr_24h_vol"]); - Settings::getInstance()->setINRVolume( hush["inr_24h_vol"]); + if (hush["sgd_24h_vol"] >= 0) { + qDebug() << "HUSH = sgd_24h_vol" << QString::number((double) hush["sgd_24h_vol"]); + Settings::getInstance() - > setSGDVolume(hush["sgd_24h_vol"]); } - if (hush["gbp_24h_vol"] >= 0) - { - qDebug() << "HUSH = gbp_24h_vol" << QString::number((double)hush["gbp_24h_vol"]); - Settings::getInstance()->setGBPVolume( hush["gbp_24h_vol"]); + if (hush["chf_24h_vol"] >= 0) { + qDebug() << "HUSH = chf_24h_vol" << QString::number((double) hush["chf_24h_vol"]); + Settings::getInstance() - > setCHFVolume(hush["chf_24h_vol"]); } - if (hush["aud_24h_vol"] >= 0) - { - qDebug() << "HUSH = aud_24h_vol" << QString::number((double)hush["aud_24h_vol"]); - Settings::getInstance()->setAUDVolume( hush["aud_24h_vol"]); + if (hush["inr_24h_vol"] >= 0) { + qDebug() << "HUSH = inr_24h_vol" << QString::number((double) hush["inr_24h_vol"]); + Settings::getInstance() - > setINRVolume(hush["inr_24h_vol"]); } - if (hush["usd_market_cap"] >= 0) - { - qDebug() << "HUSH = usd_market_cap" << QString::number((double)hush["usd_market_cap"]); - Settings::getInstance()->setUSDCAP( hush["usd_market_cap"]); + if (hush["gbp_24h_vol"] >= 0) { + qDebug() << "HUSH = gbp_24h_vol" << QString::number((double) hush["gbp_24h_vol"]); + Settings::getInstance() - > setGBPVolume(hush["gbp_24h_vol"]); } - if (hush["eur_market_cap"] >= 0) - { - qDebug() << "HUSH = eur_market_cap" << QString::number((double)hush["eur_market_cap"]); - Settings::getInstance()->setEURCAP( hush["eur_market_cap"]); + if (hush["aud_24h_vol"] >= 0) { + qDebug() << "HUSH = aud_24h_vol" << QString::number((double) hush["aud_24h_vol"]); + Settings::getInstance() - > setAUDVolume(hush["aud_24h_vol"]); } - if (hush["btc_market_cap"] >= 0) - { - qDebug() << "HUSH = btc_market_cap" << QString::number((double)hush["btc_market_cap"]); - Settings::getInstance()->setBTCCAP( hush["btc_market_cap"]); + if (hush["usd_market_cap"] >= 0) { + qDebug() << "HUSH = usd_market_cap" << QString::number((double) hush["usd_market_cap"]); + Settings::getInstance() - > setUSDCAP(hush["usd_market_cap"]); } - if (hush["cny_market_cap"] >= 0) - { - qDebug() << "HUSH = cny_market_cap" << QString::number((double)hush["cny_market_cap"]); - Settings::getInstance()->setCNYCAP( hush["cny_market_cap"]); + if (hush["eur_market_cap"] >= 0) { + qDebug() << "HUSH = eur_market_cap" << QString::number((double) hush["eur_market_cap"]); + Settings::getInstance() - > setEURCAP(hush["eur_market_cap"]); } - if (hush["rub_market_cap"] >= 0) - { - qDebug() << "HUSH = rub_market_cap" << QString::number((double)hush["rub_market_cap"]); - Settings::getInstance()->setRUBCAP( hush["rub_market_cap"]); + if (hush["btc_market_cap"] >= 0) { + qDebug() << "HUSH = btc_market_cap" << QString::number((double) hush["btc_market_cap"]); + Settings::getInstance() - > setBTCCAP(hush["btc_market_cap"]); } - if (hush["cad_market_cap"] >= 0) - { - qDebug() << "HUSH = cad_market_cap" << QString::number((double)hush["cad_market_cap"]); - Settings::getInstance()->setCADCAP( hush["cad_market_cap"]); + if (hush["cny_market_cap"] >= 0) { + qDebug() << "HUSH = cny_market_cap" << QString::number((double) hush["cny_market_cap"]); + Settings::getInstance() - > setCNYCAP(hush["cny_market_cap"]); } - if (hush["sgd_market_cap"] >= 0) - { - qDebug() << "HUSH = sgd_market_cap" << QString::number((double)hush["sgd_market_cap"]); - Settings::getInstance()->setSGDCAP( hush["sgd_market_cap"]); + if (hush["rub_market_cap"] >= 0) { + qDebug() << "HUSH = rub_market_cap" << QString::number((double) hush["rub_market_cap"]); + Settings::getInstance() - > setRUBCAP(hush["rub_market_cap"]); } - if (hush["chf_market_cap"] >= 0) - { - qDebug() << "HUSH = chf_market_cap" << QString::number((double)hush["chf_market_cap"]); - Settings::getInstance()->setCHFCAP( hush["chf_market_cap"]); + if (hush["cad_market_cap"] >= 0) { + qDebug() << "HUSH = cad_market_cap" << QString::number((double) hush["cad_market_cap"]); + Settings::getInstance() - > setCADCAP(hush["cad_market_cap"]); } - if (hush["inr_market_cap"] >= 0) - { - qDebug() << "HUSH = inr_market_cap" << QString::number((double)hush["inr_market_cap"]); - Settings::getInstance()->setINRCAP( hush["inr_market_cap"]); + if (hush["sgd_market_cap"] >= 0) { + qDebug() << "HUSH = sgd_market_cap" << QString::number((double) hush["sgd_market_cap"]); + Settings::getInstance() - > setSGDCAP(hush["sgd_market_cap"]); } - if (hush["gbp_market_cap"] >= 0) - { - qDebug() << "HUSH = gbp_market_cap" << QString::number((double)hush["gbp_market_cap"]); - Settings::getInstance()->setGBPCAP( hush["gbp_market_cap"]); + if (hush["chf_market_cap"] >= 0) { + qDebug() << "HUSH = chf_market_cap" << QString::number((double) hush["chf_market_cap"]); + Settings::getInstance() - > setCHFCAP(hush["chf_market_cap"]); } - if (hush["aud_market_cap"] >= 0) - { - qDebug() << "HUSH = aud_market_cap" << QString::number((double)hush["aud_market_cap"]); - Settings::getInstance()->setAUDCAP( hush["aud_market_cap"]); + if (hush["inr_market_cap"] >= 0) { + qDebug() << "HUSH = inr_market_cap" << QString::number((double) hush["inr_market_cap"]); + Settings::getInstance() - > setINRCAP(hush["inr_market_cap"]); + } + + if (hush["gbp_market_cap"] >= 0) { + qDebug() << "HUSH = gbp_market_cap" << QString::number((double) hush["gbp_market_cap"]); + Settings::getInstance() - > setGBPCAP(hush["gbp_market_cap"]); + } + + if (hush["aud_market_cap"] >= 0) { + qDebug() << "HUSH = aud_market_cap" << QString::number((double) hush["aud_market_cap"]); + Settings::getInstance() - > setAUDCAP(hush["aud_market_cap"]); } return; - } - catch (const std::exception& e) - { + } catch (const std::exception & e) { // If anything at all goes wrong, just set the price to 0 and move on. qDebug() << QString("Caught something nasty: ") << e.what(); } // If nothing, then set the price to 0; - Settings::getInstance()->setZECPrice(0); - Settings::getInstance()->setEURPrice(0); - Settings::getInstance()->setBTCPrice(0); - Settings::getInstance()->setCNYPrice(0); - Settings::getInstance()->setRUBPrice(0); - Settings::getInstance()->setCADPrice(0); - Settings::getInstance()->setSGDPrice(0); - Settings::getInstance()->setCHFPrice(0); - Settings::getInstance()->setGBPPrice(0); - Settings::getInstance()->setAUDPrice(0); - Settings::getInstance()->setINRPrice(0); - Settings::getInstance()->setBTCVolume(0); - Settings::getInstance()->setUSDVolume(0); - Settings::getInstance()->setEURVolume(0); - Settings::getInstance()->setBTCVolume(0); - Settings::getInstance()->setCNYVolume(0); - Settings::getInstance()->setRUBVolume(0); - Settings::getInstance()->setCADVolume(0); - Settings::getInstance()->setINRVolume(0); - Settings::getInstance()->setSGDVolume(0); - Settings::getInstance()->setCHFVolume(0); - Settings::getInstance()->setGBPVolume(0); - Settings::getInstance()->setAUDVolume(0); - Settings::getInstance()->setUSDCAP(0); - Settings::getInstance()->setEURCAP(0); - Settings::getInstance()->setBTCCAP(0); - Settings::getInstance()->setCNYCAP(0); - Settings::getInstance()->setRUBCAP(0); - Settings::getInstance()->setCADCAP(0); - Settings::getInstance()->setINRCAP(0); - Settings::getInstance()->setSGDCAP(0); - Settings::getInstance()->setCHFCAP(0); - Settings::getInstance()->setGBPCAP(0); - Settings::getInstance()->setAUDCAP(0); + Settings::getInstance() - > setZECPrice(0); + Settings::getInstance() - > setEURPrice(0); + Settings::getInstance() - > setBTCPrice(0); + Settings::getInstance() - > setCNYPrice(0); + Settings::getInstance() - > setRUBPrice(0); + Settings::getInstance() - > setCADPrice(0); + Settings::getInstance() - > setSGDPrice(0); + Settings::getInstance() - > setCHFPrice(0); + Settings::getInstance() - > setGBPPrice(0); + Settings::getInstance() - > setAUDPrice(0); + Settings::getInstance() - > setINRPrice(0); + Settings::getInstance() - > setBTCVolume(0); + Settings::getInstance() - > setUSDVolume(0); + Settings::getInstance() - > setEURVolume(0); + Settings::getInstance() - > setBTCVolume(0); + Settings::getInstance() - > setCNYVolume(0); + Settings::getInstance() - > setRUBVolume(0); + Settings::getInstance() - > setCADVolume(0); + Settings::getInstance() - > setINRVolume(0); + Settings::getInstance() - > setSGDVolume(0); + Settings::getInstance() - > setCHFVolume(0); + Settings::getInstance() - > setGBPVolume(0); + Settings::getInstance() - > setAUDVolume(0); + Settings::getInstance() - > setUSDCAP(0); + Settings::getInstance() - > setEURCAP(0); + Settings::getInstance() - > setBTCCAP(0); + Settings::getInstance() - > setCNYCAP(0); + Settings::getInstance() - > setRUBCAP(0); + Settings::getInstance() - > setCADCAP(0); + Settings::getInstance() - > setINRCAP(0); + Settings::getInstance() - > setSGDCAP(0); + Settings::getInstance() - > setCHFCAP(0); + Settings::getInstance() - > setGBPCAP(0); + Settings::getInstance() - > setAUDCAP(0); }); } -void Controller::shutdownhushd() -{ +void Controller::shutdownhushd() { // Save the wallet and exit the lightclient library cleanly. - if (zrpc->haveConnection()) - { + if (zrpc - > haveConnection()) { QDialog d(main); Ui_ConnectionDialog connD; - connD.setupUi(&d); - connD.topIcon->setPixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256)); - connD.status->setText(QObject::tr("Please wait for SilentDragonLite to exit")); - connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit")); + connD.setupUi( & d); + connD.topIcon - > setPixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256)); + connD.status - > setText(QObject::tr("Please wait for SilentDragonLite to exit")); + connD.statusDetail - > setText(QObject::tr("Waiting for hushd to exit")); bool finished = false; - zrpc->saveWallet([&] (json) { + zrpc - > saveWallet([ & ](json) { if (!finished) d.accept(); finished = true; @@ -1607,24 +1480,21 @@ void Controller::shutdownhushd() /** * Get a Sapling address from the user's wallet - */ -QString Controller::getDefaultSaplingAddress() -{ - for (QString addr: model->getAllZAddresses()) - { - if (Settings::getInstance()->isSaplingAddress(addr)) + */ +QString Controller::getDefaultSaplingAddress() { + for (QString addr: model - > getAllZAddresses()) { + if (Settings::getInstance() - > isSaplingAddress(addr)) return addr; } return QString(); } -QString Controller::getDefaultTAddress() -{ - if (model->getAllTAddresses().length() > 0) - return model->getAllTAddresses().at(0); +QString Controller::getDefaultTAddress() { + if (model - > getAllTAddresses().length() > 0) + return model - > getAllTAddresses().at(0); - else + else return QString(); - -} + +} \ No newline at end of file From ac2e27d2f7299012eb355b54751bb8aba6fd7620 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 14 May 2020 13:57:54 +0200 Subject: [PATCH 103/253] fix some typos --- src/controller.cpp | 1898 +++++++++++++++++++++++--------------------- 1 file changed, 1009 insertions(+), 889 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 8023cbc..47a1a1e 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -2,67 +2,58 @@ // GPLv3 #include "controller.h" - #include "mainwindow.h" - #include "addressbook.h" - #include "settings.h" - #include "version.h" - #include "camount.h" - #include "websockets.h" - #include "Model/ChatItem.h" - #include "DataStore/DataStore.h" /*template<> DataStore* DataStore::instance = nullptr; template<> bool DataStore::instanced = false;*/ -ChatModel * chatModel = new ChatModel(); -Chat * chat = new Chat(); -ContactModel * contactModel = new ContactModel(); +ChatModel *chatModel = new ChatModel(); +Chat *chat = new Chat(); +ContactModel *contactModel = new ContactModel(); using json = nlohmann::json; -Controller::Controller(MainWindow * main) { +Controller::Controller(MainWindow* main) +{ auto cl = new ConnectionLoader(main, this); // Execute the load connection async, so we can set up the rest of RPC properly. - QTimer::singleShot(1, [ = ]() { - cl - > loadConnection(); - }); + QTimer::singleShot(1, [=]() { cl->loadConnection(); }); - this - > main = main; - this - > ui = main - > ui; + this->main = main; + this->ui = main->ui; // Setup balances table model - balancesTableModel = new BalancesTableModel(main - > ui - > balancesTable); - main - > ui - > balancesTable - > setModel(balancesTableModel); + balancesTableModel = new BalancesTableModel(main->ui->balancesTable); + main->ui->balancesTable->setModel(balancesTableModel); // Setup transactions table model - transactionsTableModel = new TxTableModel(ui - > transactionsTable); - main - > ui - > transactionsTable - > setModel(transactionsTableModel); - + transactionsTableModel = new TxTableModel(ui->transactionsTable); + main->ui->transactionsTable->setModel(transactionsTableModel); + // Set up timer to refresh Price priceTimer = new QTimer(main); - QObject::connect(priceTimer, & QTimer::timeout, [ = ]() { - if (Settings::getInstance() - > getAllowFetchPrices()) - refreshZECPrice(); - + QObject::connect(priceTimer, &QTimer::timeout, [=]() { + if (Settings::getInstance()->getAllowFetchPrices()) + refreshZECPrice(); + }); - priceTimer - > start(Settings::priceRefreshSpeed); // Every 5 Min + priceTimer->start(Settings::priceRefreshSpeed); // Every 5 Min // Set up a timer to refresh the UI every few seconds timer = new QTimer(main); - QObject::connect(timer, & QTimer::timeout, [ = ]() { + QObject::connect(timer, &QTimer::timeout, [=]() { refresh(); }); - timer - > start(Settings::updateSpeed); + timer->start(Settings::updateSpeed); // Create the data model model = new DataModel(); @@ -71,7 +62,8 @@ Controller::Controller(MainWindow * main) { zrpc = new LiteInterface(); } -Controller::~Controller() { +Controller::~Controller() +{ delete timer; delete txTimer; delete transactionsTableModel; @@ -79,21 +71,22 @@ Controller::~Controller() { delete model; delete zrpc; } - + // Called when a connection to hushd is available. -void Controller::setConnection(Connection * c) { - if (c == nullptr) +void Controller::setConnection(Connection* c) +{ + if (c == nullptr) return; - this - > zrpc - > setConnection(c); - ui - > statusBar - > showMessage(""); + this->zrpc->setConnection(c); + ui->statusBar->showMessage(""); // If we're allowed to get the Hush Price, get the prices - if (Settings::getInstance() - > getAllowFetchPrices()) + if (Settings::getInstance()->getAllowFetchPrices()) refreshZECPrice(); // If we're allowed to check for updates, check for a new release - if (Settings::getInstance() - > getCheckForUpdates()) + if (Settings::getInstance()->getCheckForUpdates()) checkForUpdate(); // Force update, because this might be coming from a settings update @@ -102,417 +95,458 @@ void Controller::setConnection(Connection * c) { // Create Sietch zdust addr at startup. // Using DataStore singelton, to store the data outside of lambda, bing bada boom :D - for (uint8_t i = 0; i < 10; i++) { - zrpc - > createNewSietchZaddr([ = ](json reply) { - QString zdust = QString::fromStdString(reply.get < json::array_t > ()[0]); - DataStore::getSietchDataStore() - > setData("Sietch" + QString(i), zdust.toUtf8()); + for(uint8_t i = 0; i < 10; i++) + { + zrpc->createNewSietchZaddr( [=] (json reply) { + QString zdust = QString::fromStdString(reply.get()[0]); + DataStore::getSietchDataStore()->setData("Sietch" + QString(i), zdust.toUtf8()); }); } } // Build the RPC JSON Parameters for this tx -void Controller::fillTxJsonParams(json & allRecepients, Tx tx) { +void Controller::fillTxJsonParams(json& allRecepients, Tx tx) +{ Q_ASSERT(allRecepients.is_array()); // Construct the JSON params json rec = json::object(); //creating the JSON dust parameters in a std::vector to iterate over there during tx - std::vector < json > dust(10); + std::vector dust(10); dust.resize(10, json::object()); // Create Sietch zdust addr again to not use it twice. // Using DataStore singelton, to store the data outside of lambda, bing bada boom :D - for (uint8_t i = 0; i < 10; i++) { - zrpc - > createNewSietchZaddr([ = ](json reply) { - QString zdust = QString::fromStdString(reply.get < json::array_t > ()[0]); - DataStore::getSietchDataStore() - > setData(QString("Sietch") + QString(i), zdust.toUtf8()); - }); + for(uint8_t i = 0; i < 10; i++) + { + zrpc->createNewSietchZaddr( [=] (json reply) { + QString zdust = QString::fromStdString(reply.get()[0]); + DataStore::getSietchDataStore()->setData(QString("Sietch") + QString(i), zdust.toUtf8()); + } ); } // Set sietch zdust addr to json. // Using DataStore singelton, to store the data into the dusts, bing bada boom :D - for (uint8_t i = 0; i < 10; i++) { - dust.at(i)["address"] = DataStore::getSietchDataStore() - > getData(QString("Sietch" + QString(i))).toStdString(); + for(uint8_t i = 0; i < 10; i++) + { + dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString(); } - DataStore::getSietchDataStore() - > clear(); // clears the datastore + DataStore::getSietchDataStore()->clear(); // clears the datastore // Dust amt/memo, construct the JSON - for (uint8_t i = 0; i < 10; i++) { + for(uint8_t i = 0; i < 10; i++) + { dust.at(i)["amount"] = 0; dust.at(i)["memo"] = ""; - + } - + // For each addr/amt/memo, construct the JSON and also build the confirm dialog box - for (int i = 0; i < tx.toAddrs.size(); i++) { + for (int i=0; i < tx.toAddrs.size(); i++) + { auto toAddr = tx.toAddrs[i]; rec["address"] = toAddr.addr.toStdString(); - rec["amount"] = toAddr.amount.toqint64(); + rec["amount"] = toAddr.amount.toqint64(); if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty()) rec["memo"] = toAddr.memo.toStdString(); - allRecepients.push_back(rec); + allRecepients.push_back(rec) ; } - allRecepients.insert(std::begin(allRecepients), { - dust.at(0), - dust.at(1), - dust.at(2), - dust.at(3), - dust.at(4), - dust.at(5), - dust.at(6), - dust.at(7), - dust.at(8) - }); + allRecepients.insert(std::begin(allRecepients), { + dust.at(0), + dust.at(1), + dust.at(2), + dust.at(3), + dust.at(4), + dust.at(5), + dust.at(6), + dust.at(7), + dust.at(8) + }) ; } -void Controller::noConnection() { - QIcon i = QApplication::style() - > standardIcon(QStyle::SP_MessageBoxCritical); - main - > statusIcon - > setPixmap(i.pixmap(16, 16)); - main - > statusIcon - > setToolTip(""); - main - > statusLabel - > setText(QObject::tr("No Connection")); - main - > statusLabel - > setToolTip(""); - main - > ui - > statusBar - > showMessage(QObject::tr("No Connection"), 1000); +void Controller::noConnection() +{ + QIcon i = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); + main->statusIcon->setPixmap(i.pixmap(16, 16)); + main->statusIcon->setToolTip(""); + main->statusLabel->setText(QObject::tr("No Connection")); + main->statusLabel->setToolTip(""); + main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000); // Clear balances table. - QMap < QString, CAmount > emptyBalances; - QList < UnspentOutput > emptyOutputs; - QList < QString > emptyAddresses; - balancesTableModel - > setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs); + QMap emptyBalances; + QList emptyOutputs; + QList emptyAddresses; + balancesTableModel->setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs); // Clear Transactions table. - QList < TransactionItem > emptyTxs; - transactionsTableModel - > replaceData(emptyTxs); + QList emptyTxs; + transactionsTableModel->replaceData(emptyTxs); // Clear balances - ui - > balSheilded - > setText(""); - ui - > balTransparent - > setText(""); - ui - > balTotal - > setText(""); + ui->balSheilded->setText(""); + ui->balTransparent->setText(""); + ui->balTotal->setText(""); - ui - > balSheilded - > setToolTip(""); - ui - > balTransparent - > setToolTip(""); - ui - > balTotal - > setToolTip(""); + ui->balSheilded->setToolTip(""); + ui->balTransparent->setToolTip(""); + ui->balTotal->setToolTip(""); } /// This will refresh all the balance data from hushd -void Controller::refresh(bool force) { - if (!zrpc - > haveConnection()) +void Controller::refresh(bool force) +{ + if (!zrpc->haveConnection()) return noConnection(); getInfoThenRefresh(force); } -void Controller::processInfo(const json & info) { +void Controller::processInfo(const json& info) +{ // Testnet? QString chainName; - if (!info["chain_name"].is_null()) { - chainName = QString::fromStdString(info["chain_name"].get < json::string_t > ()); - Settings::getInstance() - > setTestnet(chainName == "test"); + if (!info["chain_name"].is_null()) + { + chainName = QString::fromStdString(info["chain_name"].get()); + Settings::getInstance()->setTestnet(chainName == "test"); } - QString version = QString::fromStdString(info["version"].get < json::string_t > ()); - Settings::getInstance() - > sethushdVersion(version); + QString version = QString::fromStdString(info["version"].get()); + Settings::getInstance()->sethushdVersion(version); // Recurring pamynets are testnet only - if (!Settings::getInstance() - > isTestnet()) - main - > disableRecurring(); + if (!Settings::getInstance()->isTestnet()) + main->disableRecurring(); } -void Controller::getInfoThenRefresh(bool force) { - if (!zrpc - > haveConnection()) +void Controller::getInfoThenRefresh(bool force) +{ + if (!zrpc->haveConnection()) return noConnection(); static bool prevCallSucceeded = false; - zrpc - > fetchInfo([ = ](const json & reply) { - prevCallSucceeded = true; - int curBlock = reply["latest_block_height"].get < json::number_integer_t > (); - int longestchain = reply["longestchain"].get < json::number_integer_t > (); - int notarized = reply["notarized"].get < json::number_integer_t > (); - int difficulty = reply["difficulty"].get < json::number_integer_t > (); - int blocks_until_halving = 340000 - curBlock; - int halving_days = (blocks_until_halving * 150) / (60 * 60 * 24); - bool doUpdate = force || (model - > getLatestBlock() != curBlock); - model - > setLatestBlock(curBlock); + zrpc->fetchInfo([=] (const json& reply) { + prevCallSucceeded = true; + int curBlock = reply["latest_block_height"].get(); + int longestchain = reply["longestchain"].get(); + int notarized = reply["notarized"].get(); + int difficulty = reply["difficulty"].get(); + int blocks_until_halving= 340000 - curBlock; + int halving_days = (blocks_until_halving * 150) / (60*60*24) ; + bool doUpdate = force || (model->getLatestBlock() != curBlock); + model->setLatestBlock(curBlock); if ( - Settings::getInstance() - > get_currency_name() == "EUR" || - Settings::getInstance() - > get_currency_name() == "CHF" || - Settings::getInstance() - > get_currency_name() == "RUB" - ) { - ui - > blockHeight - > setText( + Settings::getInstance()->get_currency_name() == "EUR" || + Settings::getInstance()->get_currency_name() == "CHF" || + Settings::getInstance()->get_currency_name() == "RUB" + ) + { + ui->blockHeight->setText( "Block: " + QLocale(QLocale::German).toString(curBlock) ); - ui - > last_notarized - > setText( + ui->last_notarized->setText( "Block: " + QLocale(QLocale::German).toString(notarized) ); - ui - > longestchain - > setText( + ui->longestchain->setText( "Block: " + QLocale(QLocale::German).toString(longestchain) ); - ui - > difficulty - > setText( + ui->difficulty->setText( QLocale(QLocale::German).toString(difficulty) ); - ui - > halvingTime - > setText( - (QLocale(QLocale::German).toString(blocks_until_halving)) + - " Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days") + ui->halvingTime->setText( + (QLocale(QLocale::German).toString(blocks_until_halving)) + + " Blocks or , " + (QLocale(QLocale::German).toString(halving_days) + " days" ) ); - } else { - ui - > blockHeight - > setText( + } + else + { + ui->blockHeight->setText( "Block: " + QLocale(QLocale::English).toString(curBlock) ); - ui - > last_notarized - > setText( + ui->last_notarized->setText( "Block: " + QLocale(QLocale::English).toString(notarized) ); - ui - > longestchain - > setText( + ui->longestchain->setText( "Block: " + QLocale(QLocale::English).toString(longestchain) ); - ui - > difficulty - > setText( + ui->difficulty->setText( QLocale(QLocale::English).toString(difficulty) ); - ui - > halvingTime - > setText( - (QLocale(QLocale::English).toString(blocks_until_halving)) + - " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days") + ui->halvingTime->setText( + (QLocale(QLocale::English).toString(blocks_until_halving)) + + " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days" ) ); } - ui - > Version - > setText( - QString::fromStdString(reply["version"].get < json::string_t > ()) + ui->Version->setText( + QString::fromStdString(reply["version"].get()) + ); + ui->Vendor->setText( + QString::fromStdString(reply["vendor"].get()) ); - ui - > Vendor - > setText( - QString::fromStdString(reply["vendor"].get < json::string_t > ()) - ); - main - > logger - > write( - QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") + main->logger->write( + QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") ); // Connected, so display checkmark. - auto tooltip = Settings::getInstance() - > getSettings().server + "\n" + - QString::fromStdString(zrpc - > getConnection() - > getInfo().dump()); + auto tooltip = Settings::getInstance()->getSettings().server + "\n" + + QString::fromStdString(zrpc->getConnection()->getInfo().dump()); QIcon i(":/icons/res/connected.gif"); - QString chainName = Settings::getInstance() - > isTestnet() ? "test" : "main"; - main - > statusLabel - > setText(chainName + "(" + QString::number(curBlock) + ")"); + QString chainName = Settings::getInstance()->isTestnet() ? "test" : "main"; + main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")"); // use currency ComboBox as input - if (Settings::getInstance() - > get_currency_name() == "USD") { - double price = Settings::getInstance() - > getZECPrice(); - double volume = Settings::getInstance() - > getUSDVolume(); - double cap = Settings::getInstance() - > getUSDCAP(); - main - > statusLabel - > setText( - " HUSH/USD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) + if (Settings::getInstance()->get_currency_name() == "USD") + { + double price = Settings::getInstance()->getZECPrice(); + double volume = Settings::getInstance()->getUSDVolume(); + double cap = Settings::getInstance()->getUSDCAP(); + main->statusLabel->setText( + " HUSH/USD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "EUR") { - double price = Settings::getInstance() - > getEURPrice(); - double volume = Settings::getInstance() - > getEURVolume(); - double cap = Settings::getInstance() - > getEURCAP(); - main - > statusLabel - > setText( - "HUSH/EUR " + (QLocale(QLocale::German).toString(price, 'f', 2)) + " €" + } + else if (Settings::getInstance()->get_currency_name() == "EUR") + { + double price = Settings::getInstance()->getEURPrice(); + double volume = Settings::getInstance()->getEURVolume(); + double cap = Settings::getInstance()->getEURCAP(); + main->statusLabel->setText( + "HUSH/EUR "+(QLocale(QLocale::German).toString(price,'f', 2))+ " €" + ); + ui->volumeExchange->setText( + QLocale(QLocale::German).toString(volume,'f', 2)+ " €" ); - ui - > volumeExchange - > setText( - QLocale(QLocale::German).toString(volume, 'f', 2) + " €" - ); - ui - > marketcapTab - > setText( - QLocale(QLocale::German).toString(cap, 'f', 2) + " €" + ui->marketcapTab->setText( + QLocale(QLocale::German).toString(cap,'f', 2)+ " €" ); - } else if (Settings::getInstance() - > get_currency_name() == "BTC") { - double price = Settings::getInstance() - > getBTCPrice(); - double volume = Settings::getInstance() - > getBTCVolume(); - double cap = Settings::getInstance() - > getBTCCAP(); - main - > statusLabel - > setText( - " HUSH/BTC=BTC " + (QLocale(QLocale::English).toString(price, 'f', 8)) + } + else if (Settings::getInstance()->get_currency_name() == "BTC") + { + double price = Settings::getInstance()->getBTCPrice(); + double volume = Settings::getInstance()->getBTCVolume(); + double cap = Settings::getInstance()->getBTCCAP(); + main->statusLabel->setText( + " HUSH/BTC=BTC " + (QLocale(QLocale::English).toString(price, 'f',8)) ); - ui - > volumeExchange - > setText( - " BTC " + (QLocale(QLocale::English).toString(volume, 'f', 8)) + ui->volumeExchange->setText( + " BTC " + (QLocale(QLocale::English).toString(volume, 'f',8)) ); - ui - > marketcapTab - > setText( - " BTC " + (QLocale(QLocale::English).toString(cap, 'f', 8)) + ui->marketcapTab->setText( + " BTC " + (QLocale(QLocale::English).toString(cap, 'f',8)) ); - } else if (Settings::getInstance() - > get_currency_name() == "CNY") { - double price = Settings::getInstance() - > getCNYPrice(); - double volume = Settings::getInstance() - > getCNYVolume(); - double cap = Settings::getInstance() - > getCNYCAP(); - main - > statusLabel - > setText( - " HUSH/CNY=¥ /元 " + (QLocale(QLocale::Chinese).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "CNY") + { + double price = Settings::getInstance()->getCNYPrice(); + double volume = Settings::getInstance()->getCNYVolume(); + double cap = Settings::getInstance()->getCNYCAP(); + main->statusLabel->setText( + " HUSH/CNY=¥ /元 " + (QLocale(QLocale::Chinese).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " ¥ /元 " + (QLocale(QLocale::Chinese).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " ¥ /元 " + (QLocale(QLocale::Chinese).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " ¥ /元 " + (QLocale(QLocale::Chinese).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " ¥ /元 " + (QLocale(QLocale::Chinese).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "RUB") { - double price = Settings::getInstance() - > getRUBPrice(); - double volume = Settings::getInstance() - > getRUBVolume(); - double cap = Settings::getInstance() - > getRUBCAP(); - main - > statusLabel - > setText( - " HUSH/RUB=₽ " + (QLocale(QLocale::German).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "RUB") + { + double price = Settings::getInstance()->getRUBPrice(); + double volume = Settings::getInstance()->getRUBVolume(); + double cap = Settings::getInstance()->getRUBCAP(); + main->statusLabel->setText( + " HUSH/RUB=₽ " + (QLocale(QLocale::German).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " ₽ " + (QLocale(QLocale::German).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " ₽ " + (QLocale(QLocale::German).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " ₽ " + (QLocale(QLocale::German).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " ₽ " + (QLocale(QLocale::German).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "CAD") { - double price = Settings::getInstance() - > getCADPrice(); - double volume = Settings::getInstance() - > getCADVolume(); - double cap = Settings::getInstance() - > getCADCAP(); - main - > statusLabel - > setText( - " HUSH/CAD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "CAD") + { + double price = Settings::getInstance()->getCADPrice(); + double volume = Settings::getInstance()->getCADVolume(); + double cap = Settings::getInstance()->getCADCAP(); + main->statusLabel->setText( + " HUSH/CAD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "SGD") { - double price = Settings::getInstance() - > getSGDPrice(); - double volume = Settings::getInstance() - > getSGDVolume(); - double cap = Settings::getInstance() - > getSGDCAP(); - main - > statusLabel - > setText( - " HUSH/SGD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "SGD") + { + double price = Settings::getInstance()->getSGDPrice(); + double volume = Settings::getInstance()->getSGDVolume(); + double cap = Settings::getInstance()->getSGDCAP(); + main->statusLabel->setText( + " HUSH/SGD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "CHF") { - double price = Settings::getInstance() - > getCHFPrice(); - double volume = Settings::getInstance() - > getCHFVolume(); - double cap = Settings::getInstance() - > getCHFCAP(); - main - > statusLabel - > setText( - " HUSH/CHF= " + (QLocale(QLocale::German).toString(price, 'f', 2)) + " CHF" + } + else if (Settings::getInstance()->get_currency_name() == "CHF") + { + double price = Settings::getInstance()->getCHFPrice(); + double volume = Settings::getInstance()->getCHFVolume(); + double cap = Settings::getInstance()->getCHFCAP(); + main->statusLabel->setText( + " HUSH/CHF= " + (QLocale(QLocale::German).toString(price,'f', 2))+ " CHF" ); - ui - > volumeExchange - > setText( - QLocale(QLocale::German).toString(volume, 'f', 2) + " CHF" + ui->volumeExchange->setText( + QLocale(QLocale::German).toString(volume,'f', 2)+ " CHF" ); - ui - > marketcapTab - > setText( - QLocale(QLocale::German).toString(cap, 'f', 2) + " CHF" + ui->marketcapTab->setText( + QLocale(QLocale::German).toString(cap,'f', 2)+ " CHF" ); - } else if (Settings::getInstance() - > get_currency_name() == "INR") { - double price = Settings::getInstance() - > getINRPrice(); - double volume = Settings::getInstance() - > getINRVolume(); - double cap = Settings::getInstance() - > getINRCAP(); - main - > statusLabel - > setText( - " HUSH/INR=₹ " + (QLocale(QLocale::English).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "INR") + { + double price = Settings::getInstance()->getINRPrice(); + double volume = Settings::getInstance()->getINRVolume(); + double cap = Settings::getInstance()->getINRCAP(); + main->statusLabel->setText( + " HUSH/INR=₹ " + (QLocale(QLocale::English).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " ₹ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " ₹ " + (QLocale(QLocale::English).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " ₹ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " ₹ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "GBP") { - double price = Settings::getInstance() - > getGBPPrice(); - double volume = Settings::getInstance() - > getGBPVolume(); - double cap = Settings::getInstance() - > getGBPCAP(); - main - > statusLabel - > setText( - " HUSH/GBP=£ " + (QLocale(QLocale::English).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "GBP") + { + double price = Settings::getInstance()->getGBPPrice(); + double volume = Settings::getInstance()->getGBPVolume(); + double cap = Settings::getInstance()->getGBPCAP(); + main->statusLabel->setText( + " HUSH/GBP=£ " + (QLocale(QLocale::English).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " £ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " £ " + (QLocale(QLocale::English).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " £ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " £ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); - } else if (Settings::getInstance() - > get_currency_name() == "AUD") { - double price = Settings::getInstance() - > getAUDPrice(); - double volume = Settings::getInstance() - > getAUDVolume(); - double cap = Settings::getInstance() - > getAUDCAP(); - main - > statusLabel - > setText( - " HUSH/AUD=$ " + (QLocale(QLocale::English).toString(price, 'f', 2)) + } + else if (Settings::getInstance()->get_currency_name() == "AUD") + { + double price = Settings::getInstance()->getAUDPrice(); + double volume = Settings::getInstance()->getAUDVolume(); + double cap = Settings::getInstance()->getAUDCAP(); + main->statusLabel->setText( + " HUSH/AUD=$ " + (QLocale(QLocale::English).toString(price,'f', 2)) ); - ui - > volumeExchange - > setText( - " $ " + (QLocale(QLocale::English).toString(volume, 'f', 2)) + ui->volumeExchange->setText( + " $ " + (QLocale(QLocale::English).toString(volume,'f', 2)) ); - ui - > marketcapTab - > setText( - " $ " + (QLocale(QLocale::English).toString(cap, 'f', 2)) + ui->marketcapTab->setText( + " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); - - } else { - main - > statusLabel - > setText( - " HUSH/USD=$" + QString::number(Settings::getInstance() - > getZECPrice(), 'f', 2) + + } + else + { + main->statusLabel->setText( + " HUSH/USD=$" + QString::number(Settings::getInstance()->getZECPrice(),'f',2 ) ); - ui - > volumeExchange - > setText( - " $ " + QString::number((double) Settings::getInstance() - > getUSDVolume(), 'f', 2) + ui->volumeExchange->setText( + " $ " + QString::number((double) Settings::getInstance()->getUSDVolume() ,'f',2) ); - ui - > marketcapTab - > setText( - " $ " + QString::number((double) Settings::getInstance() - > getUSDCAP(), 'f', 2) + ui->marketcapTab->setText( + " $ " + QString::number((double) Settings::getInstance()->getUSDCAP() ,'f',2) ); } - main - > statusLabel - > setToolTip(tooltip); - main - > statusIcon - > setPixmap(i.pixmap(16, 16)); - main - > statusIcon - > setToolTip(tooltip); + main->statusLabel->setToolTip(tooltip); + main->statusIcon->setPixmap(i.pixmap(16, 16)); + main->statusIcon->setToolTip(tooltip); // See if recurring payments needs anything - Recurring::getInstance() - > processPending(main); + Recurring::getInstance()->processPending(main); // Check if the wallet is locked/encrypted - zrpc - > fetchWalletEncryptionStatus([ = ](const json & reply) { - bool isEncrypted = reply["encrypted"].get < json::boolean_t > (); - bool isLocked = reply["locked"].get < json::boolean_t > (); - model - > setEncryptionStatus(isEncrypted, isLocked); + zrpc->fetchWalletEncryptionStatus([=] (const json& reply) { + bool isEncrypted = reply["encrypted"].get(); + bool isLocked = reply["locked"].get(); + model->setEncryptionStatus(isEncrypted, isLocked); }); - // Get the total supply and render it with thousand decimal - zrpc - > fetchSupply([ = ](const json & reply) { - int supply = reply["supply"].get < json::number_integer_t > (); - int zfunds = reply["zfunds"].get < json::number_integer_t > (); - int total = reply["total"].get < json::number_integer_t > (); + // Get the total supply and render it with thousand decimal + zrpc->fetchSupply([=] (const json& reply) { + int supply = reply["supply"].get(); + int zfunds = reply["zfunds"].get(); + int total = reply["total"].get(); if ( - Settings::getInstance() - > get_currency_name() == "EUR" || - Settings::getInstance() - > get_currency_name() == "CHF" || - Settings::getInstance() - > get_currency_name() == "RUB" - ) { - ui - > supply_taddr - > setText((QLocale(QLocale::German).toString(supply) + " Hush")); - ui - > supply_zaddr - > setText((QLocale(QLocale::German).toString(zfunds) + " Hush")); - ui - > supply_total - > setText((QLocale(QLocale::German).toString(total) + " Hush")); - } else { - ui - > supply_taddr - > setText("Hush " + (QLocale(QLocale::English).toString(supply))); - ui - > supply_zaddr - > setText("Hush " + (QLocale(QLocale::English).toString(zfunds))); - ui - > supply_total - > setText("Hush " + (QLocale(QLocale::English).toString(total))); + Settings::getInstance()->get_currency_name() == "EUR" || + Settings::getInstance()->get_currency_name() == "CHF" || + Settings::getInstance()->get_currency_name() == "RUB" + ) + { + ui->supply_taddr->setText((QLocale(QLocale::German).toString(supply)+ " Hush")); + ui->supply_zaddr->setText((QLocale(QLocale::German).toString(zfunds)+ " Hush")); + ui->supply_total->setText((QLocale(QLocale::German).toString(total)+ " Hush")); + } + else + { + ui->supply_taddr->setText("Hush " + (QLocale(QLocale::English).toString(supply))); + ui->supply_zaddr->setText("Hush " +(QLocale(QLocale::English).toString(zfunds))); + ui->supply_total->setText("Hush " +(QLocale(QLocale::English).toString(total))); } }); - if (doUpdate) { + if ( doUpdate ) + { // Something changed, so refresh everything. - refreshBalances(); - refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() + refreshBalances(); + refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() refreshTransactions(); } - }, [ = ](QString err) { + }, [=](QString err) { // hushd has probably disappeared. - this - > noConnection(); + this->noConnection(); // Prevent multiple dialog boxes, because these are called async static bool shown = false; if (!shown && prevCallSucceeded) // show error only first time - { + { shown = true; QMessageBox::critical( - main, - QObject::tr("Connection Error"), - QObject::tr("There was an error connecting to hushd. The error was") + ": \n\n" + err, + main, + QObject::tr("Connection Error"), + QObject::tr("There was an error connecting to hushd. The error was") + ": \n\n"+ err, QMessageBox::StandardButton::Ok ); shown = false; @@ -522,498 +556,518 @@ void Controller::getInfoThenRefresh(bool force) { }); } -void Controller::refreshAddresses() { - if (!zrpc - > haveConnection()) +void Controller::refreshAddresses() +{ + if (!zrpc->haveConnection()) return noConnection(); - - auto newzaddresses = new QList < QString > (); - auto newtaddresses = new QList < QString > (); - zrpc - > fetchAddresses([ = ](json reply) { - auto zaddrs = reply["z_addresses"].get < json::array_t > (); - for (auto & it: zaddrs) { - auto addr = QString::fromStdString(it.get < json::string_t > ()); - newzaddresses - > push_back(addr); + + auto newzaddresses = new QList(); + auto newtaddresses = new QList(); + zrpc->fetchAddresses([=] (json reply) { + auto zaddrs = reply["z_addresses"].get(); + for (auto& it : zaddrs) + { + auto addr = QString::fromStdString(it.get()); + newzaddresses->push_back(addr); } - model - > replaceZaddresses(newzaddresses); - auto taddrs = reply["t_addresses"].get < json::array_t > (); - for (auto & it: taddrs) { - auto addr = QString::fromStdString(it.get < json::string_t > ()); + model->replaceZaddresses(newzaddresses); + auto taddrs = reply["t_addresses"].get(); + for (auto& it : taddrs) + { + auto addr = QString::fromStdString(it.get()); if (Settings::isTAddress(addr)) - newtaddresses - > push_back(addr); + newtaddresses->push_back(addr); } - model - > replaceTaddresses(newtaddresses); + model->replaceTaddresses(newtaddresses); // Refresh the sent and received txs from all these z-addresses refreshTransactions(); }); - + } // Function to create the data model and update the views, used below. -void Controller::updateUI(bool anyUnconfirmed) { - ui - > unconfirmedWarning - > setVisible(anyUnconfirmed); +void Controller::updateUI(bool anyUnconfirmed) +{ + ui->unconfirmedWarning->setVisible(anyUnconfirmed); // Update balances model data, which will update the table too - balancesTableModel - > setNewData( - model - > getAllZAddresses(), - model - > getAllTAddresses(), - model - > getAllBalances(), - model - > getUTXOs() + balancesTableModel->setNewData( + model->getAllZAddresses(), + model->getAllTAddresses(), + model->getAllBalances(), + model->getUTXOs() ); }; // Function to process reply of the listunspent and z_listunspent API calls, used below. -void Controller::processUnspent(const json & reply, QMap < QString, CAmount > * balancesMap, QList < UnspentOutput > * unspentOutputs) { - auto processFn = [ = ](const json & array) { - for (auto & it: array) { - QString qsAddr = QString::fromStdString(it["address"]); - int block = it["created_in_block"].get < json::number_unsigned_t > (); - QString txid = QString::fromStdString(it["created_in_txid"]); - CAmount amount = CAmount::fromqint64(it["value"].get < json::number_unsigned_t > ()); +void Controller::processUnspent(const json& reply, QMap* balancesMap, QList* unspentOutputs) { + auto processFn = [=](const json& array) { + for (auto& it : array) + { + QString qsAddr = QString::fromStdString(it["address"]); + int block = it["created_in_block"].get(); + QString txid = QString::fromStdString(it["created_in_txid"]); + CAmount amount = CAmount::fromqint64(it["value"].get()); - bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations - bool pending = !it["unconfirmed_spent"].is_null(); + bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations + bool pending = !it["unconfirmed_spent"].is_null(); - unspentOutputs - > push_back( - UnspentOutput { - qsAddr, - txid, - amount, - block, - spendable, - pending - } + unspentOutputs->push_back( + UnspentOutput{ qsAddr, txid, amount, block, spendable, pending } ); - if (spendable) { - ( * balancesMap)[qsAddr] = ( * balancesMap)[qsAddr] + - CAmount::fromqint64(it["value"].get < json::number_unsigned_t > ()); + if (spendable) + { + (*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] + + CAmount::fromqint64(it["value"].get()); } } }; - processFn(reply["unspent_notes"].get < json::array_t > ()); - processFn(reply["utxos"].get < json::array_t > ()); - processFn(reply["pending_notes"].get < json::array_t > ()); - processFn(reply["pending_utxos"].get < json::array_t > ()); + processFn(reply["unspent_notes"].get()); + processFn(reply["utxos"].get()); + processFn(reply["pending_notes"].get()); + processFn(reply["pending_utxos"].get()); }; -void Controller::updateUIBalances() { - CAmount balT = getModel() - > getBalT(); - CAmount balZ = getModel() - > getBalZ(); - CAmount balVerified = getModel() - > getBalVerified(); +void Controller::updateUIBalances() +{ + CAmount balT = getModel()->getBalT(); + CAmount balZ = getModel()->getBalZ(); + CAmount balVerified = getModel()->getBalVerified(); // Reduce the BalanceZ by the pending outgoing amount. We're adding // here because totalPending is already negative for outgoing txns. - balZ = balZ + getModel() - > getTotalPending(); + balZ = balZ + getModel()->getTotalPending(); - CAmount balTotal = balT + balZ; + CAmount balTotal = balT + balZ; CAmount balAvailable = balT + balVerified; - if (balZ < 0) + if (balZ < 0) balZ = CAmount::fromqint64(0); // Balances table - ui - > balSheilded - > setText(balZ.toDecimalhushString()); - ui - > balVerified - > setText(balVerified.toDecimalhushString()); - ui - > balTransparent - > setText(balT.toDecimalhushString()); - ui - > balTotal - > setText(balTotal.toDecimalhushString()); + ui->balSheilded->setText(balZ.toDecimalhushString()); + ui->balVerified->setText(balVerified.toDecimalhushString()); + ui->balTransparent->setText(balT.toDecimalhushString()); + ui->balTotal->setText(balTotal.toDecimalhushString()); - if (Settings::getInstance() - > get_currency_name() == "USD") { - ui - > balSheilded - > setToolTip(balZ.toDecimalUSDString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalUSDString()); - ui - > balTransparent - > setToolTip(balT.toDecimalUSDString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalUSDString()); + if (Settings::getInstance()->get_currency_name() == "USD") + { + ui->balSheilded->setToolTip(balZ.toDecimalUSDString()); + ui->balVerified->setToolTip(balVerified.toDecimalUSDString()); + ui->balTransparent->setToolTip(balT.toDecimalUSDString()); + ui->balTotal->setToolTip(balTotal.toDecimalUSDString()); - } else if (Settings::getInstance() - > get_currency_name() == "EUR") { - ui - > balSheilded - > setToolTip(balZ.toDecimalEURString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalEURString()); - ui - > balTransparent - > setToolTip(balT.toDecimalEURString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalEURString()); + } + else if (Settings::getInstance()->get_currency_name() == "EUR") + { + ui->balSheilded->setToolTip(balZ.toDecimalEURString()); + ui->balVerified->setToolTip(balVerified.toDecimalEURString()); + ui->balTransparent->setToolTip(balT.toDecimalEURString()); + ui->balTotal->setToolTip(balTotal.toDecimalEURString()); - } else if (Settings::getInstance() - > get_currency_name() == "BTC") { - ui - > balSheilded - > setToolTip(balZ.toDecimalBTCString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalBTCString()); - ui - > balTransparent - > setToolTip(balT.toDecimalBTCString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalBTCString()); + } + else if (Settings::getInstance()->get_currency_name() == "BTC") + { + ui->balSheilded->setToolTip(balZ.toDecimalBTCString()); + ui->balVerified->setToolTip(balVerified.toDecimalBTCString()); + ui->balTransparent->setToolTip(balT.toDecimalBTCString()); + ui->balTotal->setToolTip(balTotal.toDecimalBTCString()); + + } + else if (Settings::getInstance()->get_currency_name() == "CNY") + { + ui->balSheilded->setToolTip(balZ.toDecimalCNYString()); + ui->balVerified->setToolTip(balVerified.toDecimalCNYString()); + ui->balTransparent->setToolTip(balT.toDecimalCNYString()); + ui->balTotal->setToolTip(balTotal.toDecimalCNYString()); - } else if (Settings::getInstance() - > get_currency_name() == "CNY") { - ui - > balSheilded - > setToolTip(balZ.toDecimalCNYString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalCNYString()); - ui - > balTransparent - > setToolTip(balT.toDecimalCNYString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalCNYString()); + } + else if (Settings::getInstance()->get_currency_name() == "RUB") + { + ui->balSheilded->setToolTip(balZ.toDecimalRUBString()); + ui->balVerified->setToolTip(balVerified.toDecimalRUBString()); + ui->balTransparent->setToolTip(balT.toDecimalRUBString()); + ui->balTotal->setToolTip(balTotal.toDecimalRUBString()); - } else if (Settings::getInstance() - > get_currency_name() == "RUB") { - ui - > balSheilded - > setToolTip(balZ.toDecimalRUBString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalRUBString()); - ui - > balTransparent - > setToolTip(balT.toDecimalRUBString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalRUBString()); + } + else if (Settings::getInstance()->get_currency_name() == "CAD") + { + ui->balSheilded->setToolTip(balZ.toDecimalCADString()); + ui->balVerified->setToolTip(balVerified.toDecimalCADString()); + ui->balTransparent->setToolTip(balT.toDecimalCADString()); + ui->balTotal->setToolTip(balTotal.toDecimalCADString()); - } else if (Settings::getInstance() - > get_currency_name() == "CAD") { - ui - > balSheilded - > setToolTip(balZ.toDecimalCADString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalCADString()); - ui - > balTransparent - > setToolTip(balT.toDecimalCADString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalCADString()); + } + else if (Settings::getInstance()->get_currency_name() == "SGD") + { + ui->balSheilded->setToolTip(balZ.toDecimalSGDString()); + ui->balVerified->setToolTip(balVerified.toDecimalSGDString()); + ui->balTransparent->setToolTip(balT.toDecimalSGDString()); + ui->balTotal->setToolTip(balTotal.toDecimalSGDString()); - } else if (Settings::getInstance() - > get_currency_name() == "SGD") { - ui - > balSheilded - > setToolTip(balZ.toDecimalSGDString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalSGDString()); - ui - > balTransparent - > setToolTip(balT.toDecimalSGDString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalSGDString()); + } + else if (Settings::getInstance()->get_currency_name() == "CHF") + { + ui->balSheilded->setToolTip(balZ.toDecimalCHFString()); + ui->balVerified->setToolTip(balVerified.toDecimalCHFString()); + ui->balTransparent->setToolTip(balT.toDecimalCHFString()); + ui->balTotal->setToolTip(balTotal.toDecimalCHFString()); - } else if (Settings::getInstance() - > get_currency_name() == "CHF") { - ui - > balSheilded - > setToolTip(balZ.toDecimalCHFString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalCHFString()); - ui - > balTransparent - > setToolTip(balT.toDecimalCHFString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalCHFString()); + } + else if (Settings::getInstance()->get_currency_name() == "INR") + { + ui->balSheilded->setToolTip(balZ.toDecimalINRString()); + ui->balVerified->setToolTip(balVerified.toDecimalINRString()); + ui->balTransparent->setToolTip(balT.toDecimalINRString()); + ui->balTotal->setToolTip(balTotal.toDecimalINRString()); - } else if (Settings::getInstance() - > get_currency_name() == "INR") { - ui - > balSheilded - > setToolTip(balZ.toDecimalINRString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalINRString()); - ui - > balTransparent - > setToolTip(balT.toDecimalINRString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalINRString()); + } + else if (Settings::getInstance()->get_currency_name() == "GBP") + { + ui->balSheilded ->setToolTip(balZ.toDecimalGBPString()); + ui->balVerified ->setToolTip(balVerified.toDecimalGBPString()); + ui->balTransparent->setToolTip(balT.toDecimalGBPString()); + ui->balTotal ->setToolTip(balTotal.toDecimalGBPString()); - } else if (Settings::getInstance() - > get_currency_name() == "GBP") { - ui - > balSheilded - > setToolTip(balZ.toDecimalGBPString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalGBPString()); - ui - > balTransparent - > setToolTip(balT.toDecimalGBPString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalGBPString()); - - } else if (Settings::getInstance() - > get_currency_name() == "AUD") { - ui - > balSheilded - > setToolTip(balZ.toDecimalAUDString()); - ui - > balVerified - > setToolTip(balVerified.toDecimalAUDString()); - ui - > balTransparent - > setToolTip(balT.toDecimalAUDString()); - ui - > balTotal - > setToolTip(balTotal.toDecimalAUDString()); + } + else if (Settings::getInstance()->get_currency_name() == "AUD") + { + ui->balSheilded ->setToolTip(balZ.toDecimalAUDString()); + ui->balVerified ->setToolTip(balVerified.toDecimalAUDString()); + ui->balTransparent->setToolTip(balT.toDecimalAUDString()); + ui->balTotal ->setToolTip(balTotal.toDecimalAUDString()); } // Send tab - ui - > txtAvailablehush - > setText(balAvailable.toDecimalhushString()); + ui->txtAvailablehush->setText(balAvailable.toDecimalhushString()); - if (Settings::getInstance() - > get_currency_name() == "USD") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalUSDString()); + if (Settings::getInstance()->get_currency_name() == "USD") + ui->txtAvailableUSD->setText(balAvailable.toDecimalUSDString()); - else if (Settings::getInstance() - > get_currency_name() == "EUR") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalEURString()); + else if (Settings::getInstance()->get_currency_name() == "EUR") + ui->txtAvailableUSD->setText(balAvailable.toDecimalEURString()); - else if (Settings::getInstance() - > get_currency_name() == "BTC") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalBTCString()); + else if (Settings::getInstance()->get_currency_name() == "BTC") + ui->txtAvailableUSD->setText(balAvailable.toDecimalBTCString()); - else if (Settings::getInstance() - > get_currency_name() == "CNY") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalCNYString()); + else if (Settings::getInstance()->get_currency_name() == "CNY") + ui->txtAvailableUSD->setText(balAvailable.toDecimalCNYString()); - else if (Settings::getInstance() - > get_currency_name() == "RUB") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalRUBString()); + else if (Settings::getInstance()->get_currency_name() == "RUB") + ui->txtAvailableUSD->setText(balAvailable.toDecimalRUBString()); - else if (Settings::getInstance() - > get_currency_name() == "CAD") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalCADString()); + else if (Settings::getInstance()->get_currency_name() == "CAD") + ui->txtAvailableUSD->setText(balAvailable.toDecimalCADString()); - else if (Settings::getInstance() - > get_currency_name() == "SGD") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalSGDString()); + else if (Settings::getInstance()->get_currency_name() == "SGD") + ui->txtAvailableUSD->setText(balAvailable.toDecimalSGDString()); - else if (Settings::getInstance() - > get_currency_name() == "CHF") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalCHFString()); + else if (Settings::getInstance()->get_currency_name() == "CHF") + ui->txtAvailableUSD->setText(balAvailable.toDecimalCHFString()); - else if (Settings::getInstance() - > get_currency_name() == "INR") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalINRString()); + else if (Settings::getInstance()->get_currency_name() == "INR") + ui->txtAvailableUSD->setText(balAvailable.toDecimalINRString()); - else if (Settings::getInstance() - > get_currency_name() == "GBP") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalGBPString()); + else if (Settings::getInstance()->get_currency_name() == "GBP") + ui->txtAvailableUSD->setText(balAvailable.toDecimalGBPString()); - else if (Settings::getInstance() - > get_currency_name() == "AUD") - ui - > txtAvailableUSD - > setText(balAvailable.toDecimalAUDString()); + else if (Settings::getInstance()->get_currency_name() == "AUD") + ui->txtAvailableUSD->setText(balAvailable.toDecimalAUDString()); } -void Controller::refreshBalances() { - if (!zrpc - > haveConnection()) +void Controller::refreshBalances() +{ + if (!zrpc->haveConnection()) return noConnection(); // 1. Get the Balances - zrpc - > fetchBalance([ = ](json reply) { - CAmount balT = CAmount::fromqint64(reply["tbalance"].get < json::number_unsigned_t > ()); - CAmount balZ = CAmount::fromqint64(reply["zbalance"].get < json::number_unsigned_t > ()); - CAmount balVerified = CAmount::fromqint64(reply["verified_zbalance"].get < json::number_unsigned_t > ()); - - model - > setBalT(balT); - model - > setBalZ(balZ); - model - > setBalVerified(balVerified); + zrpc->fetchBalance([=] (json reply) { + CAmount balT = CAmount::fromqint64(reply["tbalance"].get()); + CAmount balZ = CAmount::fromqint64(reply["zbalance"].get()); + CAmount balVerified = CAmount::fromqint64(reply["verified_zbalance"].get()); + + model->setBalT(balT); + model->setBalZ(balZ); + model->setBalVerified(balVerified); // This is for the websockets - AppDataModel::getInstance() - > setBalances(balT, balZ); - + AppDataModel::getInstance()->setBalances(balT, balZ); + // This is for the datamodel CAmount balAvailable = balT + balVerified; - model - > setAvailableBalance(balAvailable); + model->setAvailableBalance(balAvailable); updateUIBalances(); }); // 2. Get the UTXOs // First, create a new UTXO list. It will be replacing the existing list when everything is processed. - auto newUnspentOutputs = new QList < UnspentOutput > (); - auto newBalances = new QMap < QString, CAmount > (); + auto newUnspentOutputs = new QList(); + auto newBalances = new QMap(); // Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI - zrpc - > fetchUnspent([ = ](json reply) { + zrpc->fetchUnspent([=] (json reply) { processUnspent(reply, newBalances, newUnspentOutputs); // Swap out the balances and UTXOs - model - > replaceBalances(newBalances); - model - > replaceUTXOs(newUnspentOutputs); + model->replaceBalances(newBalances); + model->replaceUTXOs(newUnspentOutputs); // Find if any output is not spendable or is pending bool anyUnconfirmed = std::find_if( - newUnspentOutputs - > constBegin(), - newUnspentOutputs - > constEnd(), - [ = ](const UnspentOutput & u) - > bool { - return !u.spendable || u.pending; + newUnspentOutputs->constBegin(), + newUnspentOutputs->constEnd(), + [=](const UnspentOutput& u) -> bool { + return !u.spendable || u.pending; } - ) != newUnspentOutputs - > constEnd(); + ) != newUnspentOutputs->constEnd(); updateUI(anyUnconfirmed); - main - > balancesReady(); + main->balancesReady(); }); } -void Controller::refreshTransactions() { - if (!zrpc - > haveConnection()) +void Controller::refreshTransactions() { + if (!zrpc->haveConnection()) return noConnection(); - zrpc - > fetchTransactions([ = ](json reply) { - QList < TransactionItem > txdata; + zrpc->fetchTransactions([=] (json reply) { + QList txdata; - for (auto & it: reply.get < json::array_t > ()) { + for (auto& it : reply.get()) { QString address; CAmount total_amount; - QList < TransactionItemDetail > items; + QList items; long confirmations; - if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get < json::boolean_t > ()) { + if (it.find("unconfirmed") != it.end() && it["unconfirmed"].get()) { confirmations = 0; } else { - confirmations = model - > getLatestBlock() - it["block_height"].get < json::number_integer_t > () + 1; + confirmations = model->getLatestBlock() - it["block_height"].get() + 1; } - + auto txid = QString::fromStdString(it["txid"]); - auto datetime = it["datetime"].get < json::number_integer_t > (); - + auto datetime = it["datetime"].get(); + // First, check if there's outgoing metadata if (!it["outgoing_metadata"].is_null()) { - - for (auto o: it["outgoing_metadata"].get < json::array_t > ()) { - - QString address; - + + for (auto o: it["outgoing_metadata"].get()) { + + QString address; + address = QString::fromStdString(o["address"]); - + // Sent items are -ve - CAmount amount = CAmount::fromqint64(-1 * o["value"].get < json::number_unsigned_t > ()); - - // Check for Memos - + CAmount amount = CAmount::fromqint64(-1* o["value"].get()); + + // Check for Memos + QString memo; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"]); - QString cid; + QString cid; ChatItem item = ChatItem( - datetime, - address, - QString(""), - memo, - QString(""), - QString(""), - cid, - txid, - true - ); - qDebug() << "Memo : " << memo; + datetime, + address, + QString(""), + memo, + QString(""), + QString(""), + cid, + txid, + true + ); + qDebug()<<"Memo : " < setData(ChatIDGenerator::getInstance() - > generateID(item), item); - - } - - items.push_back(TransactionItemDetail { - address, - amount, - memo - }); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + + } + + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } - + { - QList < QString > addresses; - for (auto item: items) { - // Concat all the addresses - - addresses.push_back(item.address); - address = addresses.join(","); + QList addresses; + for (auto item : items) { + // Concat all the addresses + + + addresses.push_back(item.address); + address = addresses.join(","); } - - } - - txdata.push_back(TransactionItem { - "send", - datetime, - address, - txid, - confirmations, - items + + } + + txdata.push_back(TransactionItem{ + "send", datetime, address, txid,confirmations, items }); - + } else { // Incoming Transaction address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"])); - model - > markAddressUsed(address); + model->markAddressUsed(address); QString memo; + QString test; if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); } - items.push_back(TransactionItemDetail { + items.push_back(TransactionItemDetail{ address, - CAmount::fromqint64(it["amount"].get < json::number_integer_t > ()), + CAmount::fromqint64(it["amount"].get()), memo }); - TransactionItem tx { - "Receive", - datetime, - address, - txid, - confirmations, - items + TransactionItem tx{ + "Receive", datetime, address, txid,confirmations, items }; txdata.push_back(tx); - - QString type; - QString cid; - int position; - QString requestZaddr; + + QString type; + QString cid; + int position; + QString requestZaddr; if (!it["memo"].is_null()) { - if (memo.startsWith("{")) { + if (memo.startsWith("{")) { - QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); + QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); - cid = headermemo["cid"].toString(); - type = headermemo["t"].toString(); - requestZaddr = headermemo["z"].toString(); + cid = headermemo["cid"].toString(); + type = headermemo["t"].toString(); + requestZaddr = headermemo["z"].toString(); - chatModel - > addCid(txid, cid); - chatModel - > addrequestZaddr(txid, requestZaddr); + chatModel->addCid(txid, cid); + chatModel->addrequestZaddr(txid, requestZaddr); + } + + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ + + cid = chatModel->getCidByTx(txid); + + }else{ + cid = ""; } + + if (chatModel->getrequestZaddrByTx(txid) != QString("0xdeadbeef")){ - if (chatModel - > getCidByTx(txid) != QString("0xdeadbeef")) { - - cid = chatModel - > getCidByTx(txid); - - } else { - cid = ""; - } - - if (chatModel - > getrequestZaddrByTx(txid) != QString("0xdeadbeef")) { - - requestZaddr = chatModel - > getrequestZaddrByTx(txid); - } else { - requestZaddr = ""; - } - position = it["position"].get < json::number_integer_t > (); + requestZaddr = chatModel->getrequestZaddrByTx(txid); + }else{ + requestZaddr = ""; + } + position = it["position"].get(); ChatItem item = ChatItem( - datetime, - address, - QString(""), - memo, - requestZaddr, - type, - cid, - txid, - false - ); - qDebug() << "Position : " << position; + datetime, + address, + QString(""), + memo, + requestZaddr, + type, + cid, + txid, + false + ); + qDebug()<< "Position : " << position; - DataStore::getChatDataStore() - > setData(ChatIDGenerator::getInstance() - > generateID(item), item); - } + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + } } - + } // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds CAmount totalPending; - for (auto txitem: txdata) { + for (auto txitem : txdata) { if (txitem.confirmations == 0) { for (auto item: txitem.items) { totalPending = totalPending + item.amount; } } } - getModel() - > setTotalPending(totalPending); + getModel()->setTotalPending(totalPending); // Update UI Balance updateUIBalances(); - // Update model data, which updates the table view - transactionsTableModel - > replaceData(txdata); - chat - > renderChatBox(ui, ui - > listChat); + // Update model data, which updates the table view + transactionsTableModel->replaceData(txdata); + chat->renderChatBox(ui, ui->listChat); refreshContacts( - ui - > listContactWidget - + ui->listContactWidget + ); - }); + }); } -void Controller::refreshChat(QListView * listWidget) { - chat - > renderChatBox(ui, listWidget); - +void Controller::refreshChat(QListView *listWidget) +{ + chat->renderChatBox(ui, listWidget); + } -void Controller::refreshContacts(QListView * listWidget) { - contactModel - > renderContactList(listWidget); +void Controller::refreshContacts(QListView *listWidget) +{ + contactModel->renderContactList(listWidget); } // If the wallet is encrpyted and locked, we need to unlock it -void Controller::unlockIfEncrypted(std:: function < void(void) > cb, std:: function < void(void) > error) { - auto encStatus = getModel() - > getEncryptionStatus(); - if (encStatus.first && encStatus.second) { +void Controller::unlockIfEncrypted(std::function cb, std::function error) +{ + auto encStatus = getModel()->getEncryptionStatus(); + if (encStatus.first && encStatus.second) + { // Wallet is encrypted and locked. Ask for the password and unlock. QString password = QInputDialog::getText( - main, - main - > tr("Wallet Password"), - main - > tr("Your wallet is encrypted.\nPlease enter your wallet password"), + main, + main->tr("Wallet Password"), + main->tr("Your wallet is encrypted.\nPlease enter your wallet password"), QLineEdit::Password ); - if (password.isEmpty()) { + if (password.isEmpty()) + { QMessageBox::critical( - main, - main - > tr("Wallet Decryption Failed"), - main - > tr("Please enter a valid password"), + main, + main->tr("Wallet Decryption Failed"), + main->tr("Please enter a valid password"), QMessageBox::Ok ); error(); return; } - zrpc - > unlockWallet(password, [ = ](json reply) { - if (isJsonResultSuccess(reply)) { + zrpc->unlockWallet(password, [=](json reply) { + if (isJsonResultSuccess(reply)) + { cb(); // Refresh the wallet so the encryption status is now in sync. refresh(true); - } else { + } + else + { QMessageBox::critical( - main, - main - > tr("Wallet Decryption Failed"), - QString::fromStdString(reply["error"].get < json::string_t > ()), + main, + main->tr("Wallet Decryption Failed"), + QString::fromStdString(reply["error"].get()), QMessageBox::Ok ); error(); } }); - } else { + } + else + { // Not locked, so just call the function cb(); } @@ -1023,75 +1077,86 @@ void Controller::unlockIfEncrypted(std:: function < void(void) > cb, std:: funct * Execute a transaction with the standard UI. i.e., standard status bar message and standard error * handling */ -void Controller::executeStandardUITransaction(Tx tx) { - executeTransaction(tx, [ = ](QString txid) { - ui - > statusBar - > showMessage(Settings::txidStatusMessage + " " + txid); +void Controller::executeStandardUITransaction(Tx tx) +{ + executeTransaction(tx, [=] (QString txid) { + ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid); }, - [ = ](QString opid, QString errStr) { - ui - > statusBar - > showMessage( + [=] (QString opid, QString errStr) { + ui->statusBar->showMessage( QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000 ); if (!opid.isEmpty()) - errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; + errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; QMessageBox::critical( - main, - QObject::tr("Transaction Error"), - errStr, + main, + QObject::tr("Transaction Error"), + errStr, QMessageBox::Ok - ); + ); } ); } + // Execute a transaction! -void Controller::executeTransaction(Tx tx, - const std:: function < void(QString txid) > submitted, - const std:: function < void(QString txid, QString errStr) > error) { - unlockIfEncrypted([ = ]() { +void Controller::executeTransaction(Tx tx, + const std::function submitted, + const std::function error) +{ + unlockIfEncrypted([=] () { // First, create the json params json params = json::array(); fillTxJsonParams(params, tx); std::cout << std::setw(2) << params << std::endl; - zrpc - > sendTransaction(QString::fromStdString(params.dump()), [ = ](const json & reply) { - if (reply.find("txid") == reply.end()) { - error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump())); - } else { - QString txid = QString::fromStdString(reply["txid"].get < json::string_t > ()); - submitted(txid); - } - }, - [ = ](QString errStr) { - error("", errStr); - }); - }, [ = ]() { - error("", main - > tr("Failed to unlock wallet")); + zrpc->sendTransaction(QString::fromStdString(params.dump()), [=](const json& reply) { + if (reply.find("txid") == reply.end()) + { + error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump())); + } + else + { + QString txid = QString::fromStdString(reply["txid"].get()); + submitted(txid); + } + }, + [=](QString errStr) { + error("", errStr); + }); + }, [=]() { + error("", main->tr("Failed to unlock wallet")); }); } -void Controller::checkForUpdate(bool silent) { - if (!zrpc - > haveConnection()) + +void Controller::checkForUpdate(bool silent) +{ + if (!zrpc->haveConnection()) return noConnection(); QUrl cmcURL("https://api.github.com/repos/MyHush/SilentDragonLite/releases"); QNetworkRequest req; req.setUrl(cmcURL); + + QNetworkAccessManager *manager = new QNetworkAccessManager(this->main); + QNetworkReply *reply = manager->get(req); - QNetworkAccessManager * manager = new QNetworkAccessManager(this - > main); - QNetworkReply * reply = manager - > get(req); + QObject::connect(reply, &QNetworkReply::finished, [=] { + reply->deleteLater(); + manager->deleteLater(); - QObject::connect(reply, & QNetworkReply::finished, [ = ] { - reply - > deleteLater(); - manager - > deleteLater(); - - try { - if (reply - > error() == QNetworkReply::NoError) { - auto releases = QJsonDocument::fromJson(reply - > readAll()).array(); + try + { + if (reply->error() == QNetworkReply::NoError) + { + auto releases = QJsonDocument::fromJson(reply->readAll()).array(); QVersionNumber maxVersion(0, 0, 0); - for (QJsonValue rel: releases) { + for (QJsonValue rel : releases) + { if (!rel.toObject().contains("tag_name")) continue; @@ -1099,7 +1164,8 @@ void Controller::checkForUpdate(bool silent) { if (tag.startsWith("v")) tag = tag.right(tag.length() - 1); - if (!tag.isEmpty()) { + if (!tag.isEmpty()) + { auto v = QVersionNumber::fromString(tag); if (v > maxVersion) maxVersion = v; @@ -1107,367 +1173,418 @@ void Controller::checkForUpdate(bool silent) { } auto currentVersion = QVersionNumber::fromString(APP_VERSION); - + // Get the max version that the user has hidden updates for QSettings s; auto maxHiddenVersion = QVersionNumber::fromString( - s.value("update/lastversion", "0.0.0").toString()); + s.value("update/lastversion", "0.0.0" + ).toString()); qDebug() << "Version check: Current " << currentVersion << ", Available " << maxVersion; - if (maxVersion > currentVersion && (!silent || maxVersion > maxHiddenVersion)) { - auto ans = QMessageBox::information(main, QObject::tr("Update Available"), + if (maxVersion > currentVersion && (!silent || maxVersion > maxHiddenVersion)) + { + auto ans = QMessageBox::information(main, QObject::tr("Update Available"), QObject::tr("A new release v%1 is available! You have v%2.\n\nWould you like to visit the releases page?") - .arg(maxVersion.toString()) - .arg(currentVersion.toString()), + .arg(maxVersion.toString()) + .arg(currentVersion.toString()), QMessageBox::Yes, QMessageBox::Cancel); - if (ans == QMessageBox::Yes) { + if (ans == QMessageBox::Yes) + { QDesktopServices::openUrl(QUrl("https://github.com/MyHush/SilentDragonLite/releases")); - } else { + } + else + { // If the user selects cancel, don't bother them again for this version s.setValue("update/lastversion", maxVersion.toString()); } - } else { - if (!silent) { - QMessageBox::information(main, QObject::tr("No updates available"), + } + else + { + if (!silent) + { + QMessageBox::information(main, QObject::tr("No updates available"), QObject::tr("You already have the latest release v%1") - .arg(currentVersion.toString())); + .arg(currentVersion.toString())); } - } + } } - } catch (...) { + } + catch (...) + { // If anything at all goes wrong, just set the price to 0 and move on. qDebug() << QString("Caught something nasty"); - } + } }); } // Get the hush->USD price from coinmarketcap using their API -void Controller::refreshZECPrice() { - if (!zrpc - > haveConnection()) +void Controller::refreshZECPrice() +{ + if (!zrpc->haveConnection()) return noConnection(); - // TODO: use/render all this data + // TODO: use/render all this data QUrl cmcURL("https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur%2Ceth%2Cgbp%2Ccny%2Cjpy%2Crub%2Ccad%2Csgd%2Cchf%2Cinr%2Caud%2Cinr&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true"); - + QNetworkRequest req; req.setUrl(cmcURL); - QNetworkAccessManager * manager = new QNetworkAccessManager(this - > main); - QNetworkReply * reply = manager - > get(req); - QObject::connect(reply, & QNetworkReply::finished, [ = ] { - reply - > deleteLater(); - manager - > deleteLater(); + QNetworkAccessManager *manager = new QNetworkAccessManager(this->main); + QNetworkReply *reply = manager->get(req); + QObject::connect(reply, &QNetworkReply::finished, [=] { + reply->deleteLater(); + manager->deleteLater(); - try { - if (reply - > error() != QNetworkReply::NoError) { - auto parsed = json::parse(reply - > readAll(), nullptr, false); - if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) + 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(); + qDebug() << reply->errorString(); - Settings::getInstance() - > setZECPrice(0); - Settings::getInstance() - > setEURPrice(0); - Settings::getInstance() - > setBTCPrice(0); - Settings::getInstance() - > setCNYPrice(0); - Settings::getInstance() - > setRUBPrice(0); - Settings::getInstance() - > setCADPrice(0); - Settings::getInstance() - > setSGDPrice(0); - Settings::getInstance() - > setCHFPrice(0); - Settings::getInstance() - > setGBPPrice(0); - Settings::getInstance() - > setAUDPrice(0); - Settings::getInstance() - > setINRPrice(0); - Settings::getInstance() - > setUSDVolume(0); - Settings::getInstance() - > setEURVolume(0); - Settings::getInstance() - > setBTCVolume(0); - Settings::getInstance() - > setCNYVolume(0); - Settings::getInstance() - > setRUBVolume(0); - Settings::getInstance() - > setCADVolume(0); - Settings::getInstance() - > setINRVolume(0); - Settings::getInstance() - > setSGDVolume(0); - Settings::getInstance() - > setCHFVolume(0); - Settings::getInstance() - > setGBPVolume(0); - Settings::getInstance() - > setAUDVolume(0); - Settings::getInstance() - > setUSDCAP(0); - Settings::getInstance() - > setEURCAP(0); - Settings::getInstance() - > setBTCCAP(0); - Settings::getInstance() - > setCNYCAP(0); - Settings::getInstance() - > setRUBCAP(0); - Settings::getInstance() - > setCADCAP(0); - Settings::getInstance() - > setINRCAP(0); - Settings::getInstance() - > setSGDCAP(0); - Settings::getInstance() - > setCHFCAP(0); - Settings::getInstance() - > setGBPCAP(0); - Settings::getInstance() - > setAUDCAP(0); + Settings::getInstance()->setZECPrice(0); + Settings::getInstance()->setEURPrice(0); + Settings::getInstance()->setBTCPrice(0); + Settings::getInstance()->setCNYPrice(0); + Settings::getInstance()->setRUBPrice(0); + Settings::getInstance()->setCADPrice(0); + Settings::getInstance()->setSGDPrice(0); + Settings::getInstance()->setCHFPrice(0); + Settings::getInstance()->setGBPPrice(0); + Settings::getInstance()->setAUDPrice(0); + Settings::getInstance()->setINRPrice(0); + Settings::getInstance()->setUSDVolume(0); + Settings::getInstance()->setEURVolume(0); + Settings::getInstance()->setBTCVolume(0); + Settings::getInstance()->setCNYVolume(0); + Settings::getInstance()->setRUBVolume(0); + Settings::getInstance()->setCADVolume(0); + Settings::getInstance()->setINRVolume(0); + Settings::getInstance()->setSGDVolume(0); + Settings::getInstance()->setCHFVolume(0); + Settings::getInstance()->setGBPVolume(0); + Settings::getInstance()->setAUDVolume(0); + Settings::getInstance()->setUSDCAP(0); + Settings::getInstance()->setEURCAP(0); + Settings::getInstance()->setBTCCAP(0); + Settings::getInstance()->setCNYCAP(0); + Settings::getInstance()->setRUBCAP(0); + Settings::getInstance()->setCADCAP(0); + Settings::getInstance()->setINRCAP(0); + Settings::getInstance()->setSGDCAP(0); + Settings::getInstance()->setCHFCAP(0); + Settings::getInstance()->setGBPCAP(0); + Settings::getInstance()->setAUDCAP(0); return; } qDebug() << "No network errors"; - auto all = reply - > readAll(); + auto all = reply->readAll(); auto parsed = json::parse(all, nullptr, false); - if (parsed.is_discarded()) { - Settings::getInstance() - > setZECPrice(0); - Settings::getInstance() - > setEURPrice(0); - Settings::getInstance() - > setBTCPrice(0); - Settings::getInstance() - > setCNYPrice(0); - Settings::getInstance() - > setRUBPrice(0); - Settings::getInstance() - > setCADPrice(0); - Settings::getInstance() - > setSGDPrice(0); - Settings::getInstance() - > setCHFPrice(0); - Settings::getInstance() - > setGBPPrice(0); - Settings::getInstance() - > setAUDPrice(0); - Settings::getInstance() - > setINRPrice(0); - Settings::getInstance() - > setUSDVolume(0); - Settings::getInstance() - > setEURVolume(0); - Settings::getInstance() - > setBTCVolume(0); - Settings::getInstance() - > setCNYVolume(0); - Settings::getInstance() - > setRUBVolume(0); - Settings::getInstance() - > setCADVolume(0); - Settings::getInstance() - > setINRVolume(0); - Settings::getInstance() - > setSGDVolume(0); - Settings::getInstance() - > setCHFVolume(0); - Settings::getInstance() - > setGBPVolume(0); - Settings::getInstance() - > setAUDVolume(0); - Settings::getInstance() - > setUSDCAP(0); - Settings::getInstance() - > setEURCAP(0); - Settings::getInstance() - > setBTCCAP(0); - Settings::getInstance() - > setCNYCAP(0); - Settings::getInstance() - > setRUBCAP(0); - Settings::getInstance() - > setCADCAP(0); - Settings::getInstance() - > setINRCAP(0); - Settings::getInstance() - > setSGDCAP(0); - Settings::getInstance() - > setCHFCAP(0); - Settings::getInstance() - > setGBPCAP(0); - Settings::getInstance() - > setAUDCAP(0); + if (parsed.is_discarded()) + { + Settings::getInstance()->setZECPrice(0); + Settings::getInstance()->setEURPrice(0); + Settings::getInstance()->setBTCPrice(0); + Settings::getInstance()->setCNYPrice(0); + Settings::getInstance()->setRUBPrice(0); + Settings::getInstance()->setCADPrice(0); + Settings::getInstance()->setSGDPrice(0); + Settings::getInstance()->setCHFPrice(0); + Settings::getInstance()->setGBPPrice(0); + Settings::getInstance()->setAUDPrice(0); + Settings::getInstance()->setINRPrice(0); + Settings::getInstance()->setUSDVolume(0); + Settings::getInstance()->setEURVolume(0); + Settings::getInstance()->setBTCVolume(0); + Settings::getInstance()->setCNYVolume(0); + Settings::getInstance()->setRUBVolume(0); + Settings::getInstance()->setCADVolume(0); + Settings::getInstance()->setINRVolume(0); + Settings::getInstance()->setSGDVolume(0); + Settings::getInstance()->setCHFVolume(0); + Settings::getInstance()->setGBPVolume(0); + Settings::getInstance()->setAUDVolume(0); + Settings::getInstance()->setUSDCAP(0); + Settings::getInstance()->setEURCAP(0); + Settings::getInstance()->setBTCCAP(0); + Settings::getInstance()->setCNYCAP(0); + Settings::getInstance()->setRUBCAP(0); + Settings::getInstance()->setCADCAP(0); + Settings::getInstance()->setINRCAP(0); + Settings::getInstance()->setSGDCAP(0); + Settings::getInstance()->setCHFCAP(0); + Settings::getInstance()->setGBPCAP(0); + Settings::getInstance()->setAUDCAP(0); return; } qDebug() << "Parsed JSON"; - const json & item = parsed.get < json::object_t > (); - const json & hush = item["hush"].get < json::object_t > (); + const json& item = parsed.get(); + const json& hush = item["hush"].get(); - if (hush["usd"] >= 0) { + if (hush["usd"] >= 0) + { qDebug() << "Found hush key in price json"; - qDebug() << "HUSH = $" << QString::number((double) hush["usd"]); - Settings::getInstance() - > setZECPrice(hush["usd"]); + qDebug() << "HUSH = $" << QString::number((double)hush["usd"]); + Settings::getInstance()->setZECPrice( hush["usd"] ); } - if (hush["eur"] >= 0) { - qDebug() << "HUSH = €" << QString::number((double) hush["eur"]); - Settings::getInstance() - > setEURPrice(hush["eur"]); + if (hush["eur"] >= 0) + { + qDebug() << "HUSH = €" << QString::number((double)hush["eur"]); + Settings::getInstance()->setEURPrice(hush["eur"]); } - if (hush["btc"] >= 0) { - qDebug() << "HUSH = BTC" << QString::number((double) hush["btc"]); - Settings::getInstance() - > setBTCPrice(hush["btc"]); + if (hush["btc"] >= 0) + { + qDebug() << "HUSH = BTC" << QString::number((double)hush["btc"]); + Settings::getInstance()->setBTCPrice( hush["btc"]); } - if (hush["cny"] >= 0) { - qDebug() << "HUSH = CNY" << QString::number((double) hush["cny"]); - Settings::getInstance() - > setCNYPrice(hush["cny"]); + if (hush["cny"] >= 0) + { + qDebug() << "HUSH = CNY" << QString::number((double)hush["cny"]); + Settings::getInstance()->setCNYPrice( hush["cny"]); } - if (hush["rub"] >= 0) { - qDebug() << "HUSH = RUB" << QString::number((double) hush["rub"]); - Settings::getInstance() - > setRUBPrice(hush["rub"]); + if (hush["rub"] >= 0) + { + qDebug() << "HUSH = RUB" << QString::number((double)hush["rub"]); + Settings::getInstance()->setRUBPrice( hush["rub"]); } - if (hush["cad"] >= 0) { - qDebug() << "HUSH = CAD" << QString::number((double) hush["cad"]); - Settings::getInstance() - > setCADPrice(hush["cad"]); + if (hush["cad"] >= 0) + { + qDebug() << "HUSH = CAD" << QString::number((double)hush["cad"]); + Settings::getInstance()->setCADPrice( hush["cad"]); } - if (hush["sgd"] >= 0) { - qDebug() << "HUSH = SGD" << QString::number((double) hush["sgd"]); - Settings::getInstance() - > setSGDPrice(hush["sgd"]); + if (hush["sgd"] >= 0) + { + qDebug() << "HUSH = SGD" << QString::number((double)hush["sgd"]); + Settings::getInstance()->setSGDPrice( hush["sgd"]); } - if (hush["chf"] >= 0) { - qDebug() << "HUSH = CHF" << QString::number((double) hush["chf"]); - Settings::getInstance() - > setCHFPrice(hush["chf"]); + if (hush["chf"] >= 0) + { + qDebug() << "HUSH = CHF" << QString::number((double)hush["chf"]); + Settings::getInstance()->setCHFPrice( hush["chf"]); } - if (hush["inr"] >= 0) { - qDebug() << "HUSH = INR" << QString::number((double) hush["inr"]); - Settings::getInstance() - > setINRPrice(hush["inr"]); + if (hush["inr"] >= 0) + { + qDebug() << "HUSH = INR" << QString::number((double)hush["inr"]); + Settings::getInstance()->setINRPrice( hush["inr"]); } - if (hush["gbp"] >= 0) { - qDebug() << "HUSH = GBP" << QString::number((double) hush["gbp"]); - Settings::getInstance() - > setGBPPrice(hush["gbp"]); + if (hush["gbp"] >= 0) + { + qDebug() << "HUSH = GBP" << QString::number((double)hush["gbp"]); + Settings::getInstance()->setGBPPrice( hush["gbp"]); } - if (hush["aud"] >= 0) { - qDebug() << "HUSH = AUD" << QString::number((double) hush["aud"]); - Settings::getInstance() - > setAUDPrice(hush["aud"]); + if (hush["aud"] >= 0) + { + qDebug() << "HUSH = AUD" << QString::number((double)hush["aud"]); + Settings::getInstance()->setAUDPrice( hush["aud"]); } - if (hush["btc_24h_vol"] >= 0) { - qDebug() << "HUSH = usd_24h_vol" << QString::number((double) hush["usd_24h_vol"]); - Settings::getInstance() - > setUSDVolume(hush["usd_24h_vol"]); + if (hush["btc_24h_vol"] >= 0) + { + qDebug() << "HUSH = usd_24h_vol" << QString::number((double)hush["usd_24h_vol"]); + Settings::getInstance()->setUSDVolume( hush["usd_24h_vol"]); } - if (hush["btc_24h_vol"] >= 0) { - qDebug() << "HUSH = euro_24h_vol" << QString::number((double) hush["eur_24h_vol"]); - Settings::getInstance() - > setEURVolume(hush["eur_24h_vol"]); + if (hush["btc_24h_vol"] >= 0) + { + qDebug() << "HUSH = euro_24h_vol" << QString::number((double)hush["eur_24h_vol"]); + Settings::getInstance()->setEURVolume( hush["eur_24h_vol"]); } - if (hush["btc_24h_vol"] >= 0) { - qDebug() << "HUSH = btc_24h_vol" << QString::number((double) hush["btc_24h_vol"]); - Settings::getInstance() - > setBTCVolume(hush["btc_24h_vol"]); + if (hush["btc_24h_vol"] >= 0) + { + qDebug() << "HUSH = btc_24h_vol" << QString::number((double)hush["btc_24h_vol"]); + Settings::getInstance()->setBTCVolume( hush["btc_24h_vol"]); + } + + if (hush["cny_24h_vol"] >= 0) + { + qDebug() << "HUSH = cny_24h_vol" << QString::number((double)hush["cny_24h_vol"]); + Settings::getInstance()->setCNYVolume( hush["cny_24h_vol"]); } - if (hush["cny_24h_vol"] >= 0) { - qDebug() << "HUSH = cny_24h_vol" << QString::number((double) hush["cny_24h_vol"]); - Settings::getInstance() - > setCNYVolume(hush["cny_24h_vol"]); + if (hush["rub_24h_vol"] >= 0) + { + qDebug() << "HUSH = rub_24h_vol" << QString::number((double)hush["rub_24h_vol"]); + Settings::getInstance()->setRUBVolume( hush["rub_24h_vol"]); + } + + if (hush["cad_24h_vol"] >= 0) + { + qDebug() << "HUSH = cad_24h_vol" << QString::number((double)hush["cad_24h_vol"]); + Settings::getInstance()->setCADVolume( hush["cad_24h_vol"]); } - if (hush["rub_24h_vol"] >= 0) { - qDebug() << "HUSH = rub_24h_vol" << QString::number((double) hush["rub_24h_vol"]); - Settings::getInstance() - > setRUBVolume(hush["rub_24h_vol"]); + if (hush["sgd_24h_vol"] >= 0) + { + qDebug() << "HUSH = sgd_24h_vol" << QString::number((double)hush["sgd_24h_vol"]); + Settings::getInstance()->setSGDVolume( hush["sgd_24h_vol"]); } - if (hush["cad_24h_vol"] >= 0) { - qDebug() << "HUSH = cad_24h_vol" << QString::number((double) hush["cad_24h_vol"]); - Settings::getInstance() - > setCADVolume(hush["cad_24h_vol"]); + if (hush["chf_24h_vol"] >= 0) + { + qDebug() << "HUSH = chf_24h_vol" << QString::number((double)hush["chf_24h_vol"]); + Settings::getInstance()->setCHFVolume( hush["chf_24h_vol"]); } - if (hush["sgd_24h_vol"] >= 0) { - qDebug() << "HUSH = sgd_24h_vol" << QString::number((double) hush["sgd_24h_vol"]); - Settings::getInstance() - > setSGDVolume(hush["sgd_24h_vol"]); + if (hush["inr_24h_vol"] >= 0) + { + qDebug() << "HUSH = inr_24h_vol" << QString::number((double)hush["inr_24h_vol"]); + Settings::getInstance()->setINRVolume( hush["inr_24h_vol"]); } - if (hush["chf_24h_vol"] >= 0) { - qDebug() << "HUSH = chf_24h_vol" << QString::number((double) hush["chf_24h_vol"]); - Settings::getInstance() - > setCHFVolume(hush["chf_24h_vol"]); + if (hush["gbp_24h_vol"] >= 0) + { + qDebug() << "HUSH = gbp_24h_vol" << QString::number((double)hush["gbp_24h_vol"]); + Settings::getInstance()->setGBPVolume( hush["gbp_24h_vol"]); } - if (hush["inr_24h_vol"] >= 0) { - qDebug() << "HUSH = inr_24h_vol" << QString::number((double) hush["inr_24h_vol"]); - Settings::getInstance() - > setINRVolume(hush["inr_24h_vol"]); + if (hush["aud_24h_vol"] >= 0) + { + qDebug() << "HUSH = aud_24h_vol" << QString::number((double)hush["aud_24h_vol"]); + Settings::getInstance()->setAUDVolume( hush["aud_24h_vol"]); } - if (hush["gbp_24h_vol"] >= 0) { - qDebug() << "HUSH = gbp_24h_vol" << QString::number((double) hush["gbp_24h_vol"]); - Settings::getInstance() - > setGBPVolume(hush["gbp_24h_vol"]); + if (hush["usd_market_cap"] >= 0) + { + qDebug() << "HUSH = usd_market_cap" << QString::number((double)hush["usd_market_cap"]); + Settings::getInstance()->setUSDCAP( hush["usd_market_cap"]); } - if (hush["aud_24h_vol"] >= 0) { - qDebug() << "HUSH = aud_24h_vol" << QString::number((double) hush["aud_24h_vol"]); - Settings::getInstance() - > setAUDVolume(hush["aud_24h_vol"]); + if (hush["eur_market_cap"] >= 0) + { + qDebug() << "HUSH = eur_market_cap" << QString::number((double)hush["eur_market_cap"]); + Settings::getInstance()->setEURCAP( hush["eur_market_cap"]); } - if (hush["usd_market_cap"] >= 0) { - qDebug() << "HUSH = usd_market_cap" << QString::number((double) hush["usd_market_cap"]); - Settings::getInstance() - > setUSDCAP(hush["usd_market_cap"]); + if (hush["btc_market_cap"] >= 0) + { + qDebug() << "HUSH = btc_market_cap" << QString::number((double)hush["btc_market_cap"]); + Settings::getInstance()->setBTCCAP( hush["btc_market_cap"]); } - if (hush["eur_market_cap"] >= 0) { - qDebug() << "HUSH = eur_market_cap" << QString::number((double) hush["eur_market_cap"]); - Settings::getInstance() - > setEURCAP(hush["eur_market_cap"]); + if (hush["cny_market_cap"] >= 0) + { + qDebug() << "HUSH = cny_market_cap" << QString::number((double)hush["cny_market_cap"]); + Settings::getInstance()->setCNYCAP( hush["cny_market_cap"]); } - if (hush["btc_market_cap"] >= 0) { - qDebug() << "HUSH = btc_market_cap" << QString::number((double) hush["btc_market_cap"]); - Settings::getInstance() - > setBTCCAP(hush["btc_market_cap"]); + if (hush["rub_market_cap"] >= 0) + { + qDebug() << "HUSH = rub_market_cap" << QString::number((double)hush["rub_market_cap"]); + Settings::getInstance()->setRUBCAP( hush["rub_market_cap"]); } - if (hush["cny_market_cap"] >= 0) { - qDebug() << "HUSH = cny_market_cap" << QString::number((double) hush["cny_market_cap"]); - Settings::getInstance() - > setCNYCAP(hush["cny_market_cap"]); + if (hush["cad_market_cap"] >= 0) + { + qDebug() << "HUSH = cad_market_cap" << QString::number((double)hush["cad_market_cap"]); + Settings::getInstance()->setCADCAP( hush["cad_market_cap"]); } - if (hush["rub_market_cap"] >= 0) { - qDebug() << "HUSH = rub_market_cap" << QString::number((double) hush["rub_market_cap"]); - Settings::getInstance() - > setRUBCAP(hush["rub_market_cap"]); + if (hush["sgd_market_cap"] >= 0) + { + qDebug() << "HUSH = sgd_market_cap" << QString::number((double)hush["sgd_market_cap"]); + Settings::getInstance()->setSGDCAP( hush["sgd_market_cap"]); } - if (hush["cad_market_cap"] >= 0) { - qDebug() << "HUSH = cad_market_cap" << QString::number((double) hush["cad_market_cap"]); - Settings::getInstance() - > setCADCAP(hush["cad_market_cap"]); + if (hush["chf_market_cap"] >= 0) + { + qDebug() << "HUSH = chf_market_cap" << QString::number((double)hush["chf_market_cap"]); + Settings::getInstance()->setCHFCAP( hush["chf_market_cap"]); } - if (hush["sgd_market_cap"] >= 0) { - qDebug() << "HUSH = sgd_market_cap" << QString::number((double) hush["sgd_market_cap"]); - Settings::getInstance() - > setSGDCAP(hush["sgd_market_cap"]); + if (hush["inr_market_cap"] >= 0) + { + qDebug() << "HUSH = inr_market_cap" << QString::number((double)hush["inr_market_cap"]); + Settings::getInstance()->setINRCAP( hush["inr_market_cap"]); } - if (hush["chf_market_cap"] >= 0) { - qDebug() << "HUSH = chf_market_cap" << QString::number((double) hush["chf_market_cap"]); - Settings::getInstance() - > setCHFCAP(hush["chf_market_cap"]); + if (hush["gbp_market_cap"] >= 0) + { + qDebug() << "HUSH = gbp_market_cap" << QString::number((double)hush["gbp_market_cap"]); + Settings::getInstance()->setGBPCAP( hush["gbp_market_cap"]); } - if (hush["inr_market_cap"] >= 0) { - qDebug() << "HUSH = inr_market_cap" << QString::number((double) hush["inr_market_cap"]); - Settings::getInstance() - > setINRCAP(hush["inr_market_cap"]); - } - - if (hush["gbp_market_cap"] >= 0) { - qDebug() << "HUSH = gbp_market_cap" << QString::number((double) hush["gbp_market_cap"]); - Settings::getInstance() - > setGBPCAP(hush["gbp_market_cap"]); - } - - if (hush["aud_market_cap"] >= 0) { - qDebug() << "HUSH = aud_market_cap" << QString::number((double) hush["aud_market_cap"]); - Settings::getInstance() - > setAUDCAP(hush["aud_market_cap"]); + if (hush["aud_market_cap"] >= 0) + { + qDebug() << "HUSH = aud_market_cap" << QString::number((double)hush["aud_market_cap"]); + Settings::getInstance()->setAUDCAP( hush["aud_market_cap"]); } return; - } catch (const std::exception & e) { + } + catch (const std::exception& e) + { // If anything at all goes wrong, just set the price to 0 and move on. qDebug() << QString("Caught something nasty: ") << e.what(); } // If nothing, then set the price to 0; - Settings::getInstance() - > setZECPrice(0); - Settings::getInstance() - > setEURPrice(0); - Settings::getInstance() - > setBTCPrice(0); - Settings::getInstance() - > setCNYPrice(0); - Settings::getInstance() - > setRUBPrice(0); - Settings::getInstance() - > setCADPrice(0); - Settings::getInstance() - > setSGDPrice(0); - Settings::getInstance() - > setCHFPrice(0); - Settings::getInstance() - > setGBPPrice(0); - Settings::getInstance() - > setAUDPrice(0); - Settings::getInstance() - > setINRPrice(0); - Settings::getInstance() - > setBTCVolume(0); - Settings::getInstance() - > setUSDVolume(0); - Settings::getInstance() - > setEURVolume(0); - Settings::getInstance() - > setBTCVolume(0); - Settings::getInstance() - > setCNYVolume(0); - Settings::getInstance() - > setRUBVolume(0); - Settings::getInstance() - > setCADVolume(0); - Settings::getInstance() - > setINRVolume(0); - Settings::getInstance() - > setSGDVolume(0); - Settings::getInstance() - > setCHFVolume(0); - Settings::getInstance() - > setGBPVolume(0); - Settings::getInstance() - > setAUDVolume(0); - Settings::getInstance() - > setUSDCAP(0); - Settings::getInstance() - > setEURCAP(0); - Settings::getInstance() - > setBTCCAP(0); - Settings::getInstance() - > setCNYCAP(0); - Settings::getInstance() - > setRUBCAP(0); - Settings::getInstance() - > setCADCAP(0); - Settings::getInstance() - > setINRCAP(0); - Settings::getInstance() - > setSGDCAP(0); - Settings::getInstance() - > setCHFCAP(0); - Settings::getInstance() - > setGBPCAP(0); - Settings::getInstance() - > setAUDCAP(0); + Settings::getInstance()->setZECPrice(0); + Settings::getInstance()->setEURPrice(0); + Settings::getInstance()->setBTCPrice(0); + Settings::getInstance()->setCNYPrice(0); + Settings::getInstance()->setRUBPrice(0); + Settings::getInstance()->setCADPrice(0); + Settings::getInstance()->setSGDPrice(0); + Settings::getInstance()->setCHFPrice(0); + Settings::getInstance()->setGBPPrice(0); + Settings::getInstance()->setAUDPrice(0); + Settings::getInstance()->setINRPrice(0); + Settings::getInstance()->setBTCVolume(0); + Settings::getInstance()->setUSDVolume(0); + Settings::getInstance()->setEURVolume(0); + Settings::getInstance()->setBTCVolume(0); + Settings::getInstance()->setCNYVolume(0); + Settings::getInstance()->setRUBVolume(0); + Settings::getInstance()->setCADVolume(0); + Settings::getInstance()->setINRVolume(0); + Settings::getInstance()->setSGDVolume(0); + Settings::getInstance()->setCHFVolume(0); + Settings::getInstance()->setGBPVolume(0); + Settings::getInstance()->setAUDVolume(0); + Settings::getInstance()->setUSDCAP(0); + Settings::getInstance()->setEURCAP(0); + Settings::getInstance()->setBTCCAP(0); + Settings::getInstance()->setCNYCAP(0); + Settings::getInstance()->setRUBCAP(0); + Settings::getInstance()->setCADCAP(0); + Settings::getInstance()->setINRCAP(0); + Settings::getInstance()->setSGDCAP(0); + Settings::getInstance()->setCHFCAP(0); + Settings::getInstance()->setGBPCAP(0); + Settings::getInstance()->setAUDCAP(0); }); } -void Controller::shutdownhushd() { +void Controller::shutdownhushd() +{ // Save the wallet and exit the lightclient library cleanly. - if (zrpc - > haveConnection()) { + if (zrpc->haveConnection()) + { QDialog d(main); Ui_ConnectionDialog connD; - connD.setupUi( & d); - connD.topIcon - > setPixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256)); - connD.status - > setText(QObject::tr("Please wait for SilentDragonLite to exit")); - connD.statusDetail - > setText(QObject::tr("Waiting for hushd to exit")); + connD.setupUi(&d); + connD.topIcon->setPixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256)); + connD.status->setText(QObject::tr("Please wait for SilentDragonLite to exit")); + connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit")); bool finished = false; - zrpc - > saveWallet([ & ](json) { + zrpc->saveWallet([&] (json) { if (!finished) d.accept(); finished = true; @@ -1480,21 +1597,24 @@ void Controller::shutdownhushd() { /** * Get a Sapling address from the user's wallet - */ -QString Controller::getDefaultSaplingAddress() { - for (QString addr: model - > getAllZAddresses()) { - if (Settings::getInstance() - > isSaplingAddress(addr)) + */ +QString Controller::getDefaultSaplingAddress() +{ + for (QString addr: model->getAllZAddresses()) + { + if (Settings::getInstance()->isSaplingAddress(addr)) return addr; } return QString(); } -QString Controller::getDefaultTAddress() { - if (model - > getAllTAddresses().length() > 0) - return model - > getAllTAddresses().at(0); +QString Controller::getDefaultTAddress() +{ + if (model->getAllTAddresses().length() > 0) + return model->getAllTAddresses().at(0); - else + else return QString(); - -} \ No newline at end of file + +} From b40b482b32de5ac9b9dfa5410c7d11d84a2f402b Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 14 May 2020 14:22:26 +0200 Subject: [PATCH 104/253] switch back to getAllContactRequests for rendering --- src/chatmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 01aed54..1e72714 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -97,7 +97,7 @@ void MainWindow::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); { - for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()) + for (auto &c : DataStore::getChatDataStore()->getAllContactRequests()) { QStandardItem* Items = new QStandardItem(c.second.getAddress()); From 74aaa0482fafa66b2f9aca951e05605b7c66f96a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 14 May 2020 22:52:28 +0200 Subject: [PATCH 105/253] improve some gui elements --- application.qrc | 5 +++ res/lock.png | Bin 0 -> 812 bytes res/lock.svg | 7 ++++ res/lock_blue.svg | 7 ++++ res/lock_green.svg | 7 ++++ res/unlocked.svg | 7 ++++ src/Chat/Chat.cpp | 11 +++-- src/Chat/Helper/ChatDelegator.h | 72 ++++++++++++++++++++++++++------ src/DataStore/ChatDataStore.cpp | 7 +++- src/Model/ChatItem.cpp | 39 +++++++++++++---- src/Model/ChatItem.h | 10 ++++- src/addressbook.cpp | 1 + src/chatmodel.h | 3 ++ src/contactmodel.cpp | 1 + src/controller.cpp | 4 ++ src/mainwindow.cpp | 1 + 16 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 res/lock.png create mode 100644 res/lock.svg create mode 100644 res/lock_blue.svg create mode 100644 res/lock_green.svg create mode 100644 res/unlocked.svg diff --git a/application.qrc b/application.qrc index 29a1765..d323bff 100644 --- a/application.qrc +++ b/application.qrc @@ -36,6 +36,11 @@ res/upload.png res/upload.svg res/message-icon.svg + res/lock.svg + res/lock.png + res/lock_green.svg + res/lock_blue.svg + res/unlocked.svg res/hushdlogo.gif diff --git a/res/lock.png b/res/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..b05dc49e515101200ed38e5691913accf38d5667 GIT binary patch literal 812 zcmV+{1JnG8P)EX>4Tx04R}tkv&MmP!xqvTT4Z%4rUN>$WS|35EXIMDionYs1;guFnQ@8G%+M8 zE{=k0!NH%!s)LKOt`4q(Aov5~9J6k5c1;qgAsyXWxUeL%2LWt!DB257o% zW>QHpmtPShuLz?L0s@H3%ra&rDGlHHx~D#>y9Cej@B6cQ)q=%;uku-v%zO+nTZmTta@{6o#XTY$kMFRH^9Lm z5HC^on$NqtJLmRqPiuZZEdz3kXeP*K00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliru`ai6{UIA?M@c5#R0oJ~$pEnybdcu0ztP{RVYafRn7|AnDqVEa60)gRoV4+rQ< z@@E)r2~vF~$tmn4*gJag7QR1FF4iHcH{4Ir`zxrXg~ec!jyjFH&{`)~L9G}ZHkKqG zBbhg&m0zQpaa=T#aR7tS>CTfe1LlLnnvL}!zl_Aa&~3E|E3XBU?dKKDh1Dh#Vk<$~ q(`<6wF^wvwF^Y1)YJsq$gh;=DyEZAQ + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/res/lock_blue.svg b/res/lock_blue.svg new file mode 100644 index 0000000..752bc53 --- /dev/null +++ b/res/lock_blue.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/res/lock_green.svg b/res/lock_green.svg new file mode 100644 index 0000000..1c5e4ef --- /dev/null +++ b/res/lock_green.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + \ No newline at end of file diff --git a/res/unlocked.svg b/res/unlocked.svg new file mode 100644 index 0000000..50ff5e1 --- /dev/null +++ b/res/unlocked.svg @@ -0,0 +1,7 @@ + + + + + Svg Vector Icons : http://www.onlinewebfonts.com/icon + + diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index 7038fe1..5b34929 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #include "Chat.h" #include "../addressbook.h" #include "../DataStore/DataStore.h" @@ -23,9 +26,11 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) { QStandardItem *Items = new QStandardItem(c.second.toChatLine()); - Items->setData("Outgoing", Qt::UserRole + 1); + + Items->setData(OUTGOING, Qt::UserRole + 1); chat->appendRow(Items); - ui->listChat->setModel(chat); + ui->listChat->setModel(chat); + } else { @@ -39,7 +44,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) { QStandardItem *Items1 = new QStandardItem(c.second.toChatLine()); - Items1->setData("Incoming", Qt::UserRole + 1); + Items1->setData(INCOMING, Qt::UserRole + 1); chat->appendRow(Items1); ui->listChat->setModel(chat); } diff --git a/src/Chat/Helper/ChatDelegator.h b/src/Chat/Helper/ChatDelegator.h index ef6a150..6e3e676 100644 --- a/src/Chat/Helper/ChatDelegator.h +++ b/src/Chat/Helper/ChatDelegator.h @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #ifndef CHATDELEGATOR_H #define CHATDELEGATOR_H @@ -6,6 +9,14 @@ #include #include +enum RenderType +{ + OUTGOING=0, + INCOMING=1, + INDATE=2, + OUTDATE=3 +}; + class ListViewDelegate : public QAbstractItemDelegate { int d_radius; @@ -26,7 +37,7 @@ class ListViewDelegate : public QAbstractItemDelegate inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; }; -inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(15), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) +inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.6) { } @@ -43,7 +54,9 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons qreal contentswidth = option.rect.width() * d_widthfraction - d_horizontalmargin - d_pointerwidth - d_leftpadding - d_rightpadding; bodydoc.setTextWidth(contentswidth); qreal bodyheight = bodydoc.size().height(); - bool outgoing = index.data(Qt::UserRole + 1).toString() == "Outgoing"; + int outgoing = index.data(Qt::UserRole + 1).toInt(); + int outdate = index.data(Qt::UserRole + 1).toInt(); + int indate = index.data(Qt::UserRole + 1).toInt(); painter->save(); painter->setRenderHint(QPainter::Antialiasing); @@ -53,10 +66,26 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons painter->translate(option.rect.left() + d_horizontalmargin, option.rect.top() + ((index.row() == 0) ? d_verticalmargin : 0)); - // background color for chat bubble - QColor bgcolor("#535353"); - if (outgoing) - bgcolor = "#eeeeee"; + QColor bgcolor("#ffffff"); + switch(outgoing) + { + case INDATE: + bgcolor = "transparent"; + break; + + case OUTDATE: + bgcolor = "transparent"; + break; + + case OUTGOING: + bgcolor = "#f8f9fa"; + break; + + default: + case INCOMING: + bgcolor = "#535353"; + break; + } // create chat bubble QPainterPath pointie; @@ -85,7 +114,7 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons pointie.closeSubpath(); // rotate bubble for outgoing messages - if (outgoing) + if ((outgoing == OUTGOING) || (outdate == OUTDATE)) { painter->translate(option.rect.width() - pointie.boundingRect().width() - d_horizontalmargin - d_pointerwidth, 0); painter->translate(pointie.boundingRect().center()); @@ -99,7 +128,7 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons painter->fillPath(pointie, QBrush(bgcolor)); // rotate back or painter is going to paint the text rotated... - if (outgoing) + if ((outgoing == OUTGOING) || (outdate == OUTDATE)) { painter->translate(pointie.boundingRect().center()); painter->rotate(-180); @@ -108,13 +137,30 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons // set text color used to draw message body QAbstractTextDocumentLayout::PaintContext ctx; - if (outgoing) - ctx.palette.setColor(QPalette::Text, QColor("black")); - else - ctx.palette.setColor(QPalette::Text, QColor("white")); + switch(outgoing) + { + case INDATE: + ctx.palette.setColor(QPalette::Text, QColor("Black")); + break; + + case OUTDATE: + ctx.palette.setColor(QPalette::Text, QColor("Black")); + break; + + case OUTGOING: + ctx.palette.setColor(QPalette::Text, QColor("Black")); + break; + + default: + case INCOMING: + ctx.palette.setColor(QPalette::Text, QColor("whitesmoke")); + break; + } + // draw body text - painter->translate((outgoing ? 0 : d_pointerwidth) + d_leftpadding, 0); + painter->translate((outgoing == OUTGOING ? 0 : d_pointerwidth) + d_leftpadding, 0); + painter->translate((outdate == OUTDATE ? 0 : d_pointerwidth) + d_leftpadding, 0); bodydoc.documentLayout()->draw(painter, ctx); painter->restore(); diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 4dfc605..5223d04 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #include "ChatDataStore.h" ChatDataStore* ChatDataStore::getInstance() @@ -43,8 +46,8 @@ std::map ChatDataStore::getAllContactRequests() for(auto &c: this->data) { if ( - (c.second.getType() == "cont") && - (c.second.isOutgoing() == false) && + (c.second.isOutgoing() == false) && + (c.second.getType() == "cont") && (c.second.getMemo().startsWith("{")) ) { diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index 39d4a68..afdde53 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -1,8 +1,11 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #include "ChatItem.h" ChatItem::ChatItem() {} -ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid) +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations) { _timestamp = timestamp; _address = address; @@ -12,10 +15,11 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _type = type; _cid = cid; _txid = txid; + _confirmations = confirmations; _outgoing = false; } -ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing) +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing) { _timestamp = timestamp; _address = address; @@ -25,6 +29,7 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _type = type; _cid = cid; _txid = txid; + _confirmations = confirmations; _outgoing = outgoing; } @@ -66,6 +71,10 @@ QString ChatItem::getTxid() { return _txid; } +int ChatItem::getConfirmations() +{ + return _confirmations; +} bool ChatItem::isOutgoing() { @@ -110,26 +119,38 @@ void ChatItem::setTxid(QString txid) { _txid = txid; } +void ChatItem::setConfirmations(int confirmations) +{ + _confirmations = confirmations; +} void ChatItem::toggleOutgo() { _outgoing = true; } + QString ChatItem::toChatLine() { QDateTime myDateTime; + QString lock; myDateTime.setTime_t(_timestamp); - QString line = QString("[") + myDateTime.toString("d.M.yy hh:mm") + QString("] "); - line += QString("") + QString(_memo) + QString("\n\n"); + + if (_confirmations == 0){ + lock = " "; + }else{ + + lock = " "; + + } + + QString line = QString("") + myDateTime.toString("dd.MM.yyyy hh:mm"); + line += QString(lock) + QString(""); + line += QString("

") + _memo.toHtmlEscaped() + QString("

"); return line; } ChatItem::~ChatItem() { - /*delete timestamp; - delete address; - delete contact; - delete memo; - delete outgoing;*/ + } \ No newline at end of file diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h index 467341f..6f27609 100644 --- a/src/Model/ChatItem.h +++ b/src/Model/ChatItem.h @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #ifndef CHATITEM_H #define CHATITEM_H @@ -14,12 +17,13 @@ class ChatItem QString _type; QString _cid; QString _txid; + int _confirmations; bool _outgoing = false; public: ChatItem(); - ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid); - ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, bool outgoing); + ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations); + ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing); long getTimestamp(); QString getAddress(); QString getContact(); @@ -28,6 +32,7 @@ class ChatItem QString getType(); QString getCid(); QString getTxid(); + int getConfirmations(); bool isOutgoing(); void setTimestamp(long timestamp); void setAddress(QString address); @@ -37,6 +42,7 @@ class ChatItem void setType(QString type); void setCid(QString cid); void setTxid(QString txid); + void setConfirmations(int confirmations); void toggleOutgo(); QString toChatLine(); ~ChatItem(); diff --git a/src/addressbook.cpp b/src/addressbook.cpp index d17726c..c3fdc6c 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -1,5 +1,6 @@ // Copyright 2019-2020 The Hush developers // GPLv3 + #include "addressbook.h" #include "ui_addressbook.h" #include "ui_mainwindow.h" diff --git a/src/chatmodel.h b/src/chatmodel.h index 04493b8..bf3e255 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #ifndef CHATMODEL_H #define CHATMODEL_H #include diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index ad58ccb..6f452fa 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -1,5 +1,6 @@ // Copyright 2019-2020 The Hush developers // GPLv3 + #include "contactmodel.h" #include "addressbook.h" #include "mainwindow.h" diff --git a/src/controller.cpp b/src/controller.cpp index 47a1a1e..534fffe 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -878,9 +878,11 @@ void Controller::refreshTransactions() { QString(""), cid, txid, + confirmations, true ); qDebug()<<"Memo : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); @@ -973,9 +975,11 @@ void Controller::refreshTransactions() { type, cid, txid, + confirmations, false ); qDebug()<< "Position : " << position; + qDebug()<<"Confirmation :" << confirmations; DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7a1f6c2..de034ac 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,5 +1,6 @@ // Copyright 2019-2020 The Hush developers // GPLv3 + #include "mainwindow.h" #include "addressbook.h" #include "viewalladdresses.h" From 9f7fa3ae995c4c996f8bbd33d1c0987eeecd24be Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sat, 16 May 2020 11:48:15 +0200 Subject: [PATCH 106/253] update// improved addressbook performance --- src/addressbook.cpp | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index c3fdc6c..2c7c107 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -373,35 +373,38 @@ void AddressBook::readFromStorage() in >> version; qDebug() << "Detected old addressbook format"; // Convert old addressbook format v1 to v2 - QList> stuff; - in >> stuff; - //qDebug() << "Stuff: " << stuff; - for (int i=0; i < stuff.size(); i++) + if(in.status() == QDataStream::ReadCorruptData) { - //qDebug() << "0:" << stuff[i][0]; - //qDebug() << "1:" << stuff[i][1]; - //qDebug() << "2:" << stuff[i][2]; - ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); - //qDebug() << "contact=" << contact.toQTString(); - allLabels.push_back(contact); + qDebug() << "Error reading contacts! ---> Your hush contacts from disk maybe corrupted"; + QString filepath = QFileInfo(AddressBook::writeableFile()).absolutePath() + QString("/"); + QFile::rename(filepath + QString("addresslabels.dat"), filepath + QString("addresslabels.dat-corrupted")); + QMessageBox::critical( + nullptr, + QObject::tr("Error reading contacts!"), + QObject::tr("Your hush contacts from disk maybe corrupted"), + QMessageBox::Ok + ); } + else + { + qDebug() << "Read " << version << " Hush contacts from disk..."; + QList> stuff; + in >> stuff; + for (int i=0; i < stuff.size(); i++) + { + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + allLabels.push_back(contact); + } - qDebug() << "Read " << version << " Hush contacts from disk..."; + qDebug() << "Hush contacts readed from disk..."; + } + file.close(); } else { qDebug() << "No Hush contacts found on disk!"; } - - // Special. - // Add the default silentdragon donation address if it isn't already present - // QList allAddresses; - // std::transform(allLabels.begin(), allLabels.end(), - // std::back_inserter(allAddresses), [=] (auto i) { return i.getPartnerAddress(); }); - // if (!allAddresses.contains(Settings::getDonationAddr(true))) { - // allLabels.append(QPair("silentdragon donation", Settings::getDonationAddr(true))); - // } } void AddressBook::writeToStorage() From 1e59b30280a9bc837bc0b486340ff3009d8766ba Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 16 May 2020 20:29:35 +0200 Subject: [PATCH 107/253] undo addressbook fix --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- src/addressbook.cpp | 37 ++++++++++++++----------------------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index e198570..01613d0 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1da0f0e3210db704edec74de1bc318b4e22cb6c8)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=1da0f0e3210db704edec74de1bc318b4e22cb6c8#1da0f0e3210db704edec74de1bc318b4e22cb6c8" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359#32ca60735b3529ff8589ab08fc16678f508a9359" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1da0f0e3210db704edec74de1bc318b4e22cb6c8)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index bdf5a9b..fba5265 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "1da0f0e3210db704edec74de1bc318b4e22cb6c8" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "32ca60735b3529ff8589ab08fc16678f508a9359" } diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 2c7c107..8c4d132 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -373,39 +373,30 @@ void AddressBook::readFromStorage() in >> version; qDebug() << "Detected old addressbook format"; // Convert old addressbook format v1 to v2 - if(in.status() == QDataStream::ReadCorruptData) + QList> stuff; + in >> stuff; + //qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) { - qDebug() << "Error reading contacts! ---> Your hush contacts from disk maybe corrupted"; - QString filepath = QFileInfo(AddressBook::writeableFile()).absolutePath() + QString("/"); - QFile::rename(filepath + QString("addresslabels.dat"), filepath + QString("addresslabels.dat-corrupted")); - QMessageBox::critical( - nullptr, - QObject::tr("Error reading contacts!"), - QObject::tr("Your hush contacts from disk maybe corrupted"), - QMessageBox::Ok - ); + //qDebug() << "0:" << stuff[i][0]; + //qDebug() << "1:" << stuff[i][1]; + //qDebug() << "2:" << stuff[i][2]; + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + //qDebug() << "contact=" << contact.toQTString(); + allLabels.push_back(contact); } - else - { - qDebug() << "Read " << version << " Hush contacts from disk..."; - QList> stuff; - in >> stuff; - for (int i=0; i < stuff.size(); i++) - { - ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); - allLabels.push_back(contact); - } - qDebug() << "Hush contacts readed from disk..."; - } + { + qDebug() << "Read " << version << " Hush contacts from disk..."; file.close(); } - else + }else{ { qDebug() << "No Hush contacts found on disk!"; } } +} void AddressBook::writeToStorage() { From 4f584ac86ec55f6e59983e7c91e007a72c833a53 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sun, 17 May 2020 13:18:19 +0200 Subject: [PATCH 108/253] update// added filesystem and reformated addressbook --- silentdragon-lite.pro | 4 +- src/Crypto/FileEncryption.cpp | 102 ++++++++++++++++++++++++++++++++++ src/Crypto/FileEncryption.h | 18 ++++++ src/FileSystem/FileSystem.cpp | 82 +++++++++++++++++++++++++++ src/FileSystem/FileSystem.h | 24 ++++++++ src/Logger/LogContext.h | 11 ++++ src/Logger/LogCrtitical.h | 18 ++++++ src/Logger/LogDebug.h | 18 ++++++ src/Logger/LogError.h | 18 ++++++ src/Logger/LogFatal.h | 18 ++++++ src/Logger/LogInfo.h | 18 ++++++ src/Logger/LogStrategy.h | 11 ++++ src/Logger/LogSuccess.h | 18 ++++++ src/Logger/LogType.h | 47 ++++++++++++++++ src/Logger/LogWarning.h | 18 ++++++ src/Logger/LogWriter.cpp | 35 ++++++++++++ src/Logger/LogWriter.h | 22 ++++++++ src/Logger/Logger.h | 25 +++++++++ src/Logger/SimpleLogger.h | 84 ++++++++++++++++++++++++++++ src/Logger/test.cpp | 14 +++++ src/addressbook.cpp | 17 +++--- src/addressbook.h | 1 + 22 files changed, 615 insertions(+), 8 deletions(-) create mode 100644 src/Crypto/FileEncryption.cpp create mode 100644 src/Crypto/FileEncryption.h create mode 100644 src/FileSystem/FileSystem.cpp create mode 100644 src/FileSystem/FileSystem.h create mode 100644 src/Logger/LogContext.h create mode 100644 src/Logger/LogCrtitical.h create mode 100644 src/Logger/LogDebug.h create mode 100644 src/Logger/LogError.h create mode 100644 src/Logger/LogFatal.h create mode 100644 src/Logger/LogInfo.h create mode 100644 src/Logger/LogStrategy.h create mode 100644 src/Logger/LogSuccess.h create mode 100644 src/Logger/LogType.h create mode 100644 src/Logger/LogWarning.h create mode 100644 src/Logger/LogWriter.cpp create mode 100644 src/Logger/LogWriter.h create mode 100644 src/Logger/Logger.h create mode 100644 src/Logger/SimpleLogger.h create mode 100644 src/Logger/test.cpp diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index da53d6d..56c9e4c 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -79,7 +79,9 @@ SOURCES += \ src/Model/ContactRequestChatItem.cpp \ src/Model/ContactItem.cpp \ src/Chat/Helper/ChatIDGenerator.cpp \ - src/Chat/Chat.cpp + src/Chat/Chat.cpp \ + src/FileSystem/FileSystem.cpp \ + src/Crypto/FileEncryption.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/Crypto/FileEncryption.cpp b/src/Crypto/FileEncryption.cpp new file mode 100644 index 0000000..0100585 --- /dev/null +++ b/src/Crypto/FileEncryption.cpp @@ -0,0 +1,102 @@ +#include "FileEncryption.h" + +void FileEncryption::showConfig() +{ + qInfo() << FILEENCRYPTION_CHUNK_SIZE; +} + +int FileEncryption::encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + unsigned char buf_in[FILEENCRYPTION_CHUNK_SIZE]; + unsigned char buf_out[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + crypto_secretstream_xchacha20poly1305_state st; + FILE *fp_t, *fp_s; + unsigned long long out_len; + size_t rlen; + int eof; + unsigned char tag; + + fp_s = fopen(source_file.toStdString().c_str(), "rb"); + fp_t = fopen(target_file.toStdString().c_str(), "wb"); + crypto_secretstream_xchacha20poly1305_init_push(&st, header, key); + fwrite(header, 1, sizeof header, fp_t); + do + { + rlen = fread(buf_in, 1, sizeof buf_in, fp_s); + eof = feof(fp_s); + tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0; + crypto_secretstream_xchacha20poly1305_push( + &st, + buf_out, + &out_len, + buf_in, + rlen, + NULL, + 0, + tag + ); + + fwrite(buf_out, 1, (size_t) out_len, fp_t); + } + while (! eof); + + fclose(fp_t); + fclose(fp_s); + return 0; +} + +int FileEncryption::decrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + unsigned char buf_in[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; + unsigned char buf_out[FILEENCRYPTION_CHUNK_SIZE]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + crypto_secretstream_xchacha20poly1305_state st; + FILE *fp_t, *fp_s; + unsigned long long out_len; + size_t rlen; + int eof; + int ret = -1; + unsigned char tag; + + fp_s = fopen(source_file.toStdString().c_str(), "rb"); + fp_t = fopen(target_file.toStdString().c_str(), "wb"); + fread(header, 1, sizeof header, fp_s); + if (crypto_secretstream_xchacha20poly1305_init_pull(&st, header, key) != 0) + { + goto ret; /* incomplete header */ + } + + do + { + rlen = fread(buf_in, 1, sizeof buf_in, fp_s); + eof = feof(fp_s); + if (crypto_secretstream_xchacha20poly1305_pull( + &st, + buf_out, + &out_len, + &tag, + buf_in, + rlen, + NULL, + 0 + ) != 0) + { + goto ret; /* corrupted chunk */ + } + + if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL && ! eof) + { + goto ret; /* premature end (end of file reached before the end of the stream) */ + } + + fwrite(buf_out, 1, (size_t) out_len, fp_t); + } + while (! eof); + ret = 0; + +ret: + fclose(fp_t); + fclose(fp_s); + return ret; +} \ No newline at end of file diff --git a/src/Crypto/FileEncryption.h b/src/Crypto/FileEncryption.h new file mode 100644 index 0000000..6db8977 --- /dev/null +++ b/src/Crypto/FileEncryption.h @@ -0,0 +1,18 @@ +#ifndef FILEENCRYPTION_H +#define FILEENCRYPTION_H +#include +#include +#include + +#define FILEENCRYPTION_CHUNK_SIZE 4096 + +class FileEncryption +{ + public: + static void showConfig(); + static int encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); + static int decrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); +}; + + +#endif \ No newline at end of file diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp new file mode 100644 index 0000000..5ee2fef --- /dev/null +++ b/src/FileSystem/FileSystem.cpp @@ -0,0 +1,82 @@ +#include "FileSystem.h" + +#include +#include + +FileSystem::FileSystem() +{ +} + +FileSystem* FileSystem::getInstance() +{ + if(!FileSystem::instanced) + { + FileSystem::instanced = true; + FileSystem::instance = new FileSystem(); + FileEncryption::showConfig(); + } + + return FileSystem::instance; +} + +QList FileSystem::readContacts(QString file) +{ + QList contacts; + QFile _file(file); + if (_file.exists()) + { + contacts.clear(); + _file.open(QIODevice::ReadOnly); + QDataStream in(&_file); // read the data serialized from the file + QString version; + in >> version; + qDebug() << "Read " << version << " Hush contacts from disk..."; + qDebug() << "Detected old addressbook format"; + QList> stuff; + in >> stuff; + //qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) + { + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + contacts.push_back(contact); + } + + _file.close(); + } + else + { + qDebug() << "No Hush contacts found on disk!"; + } + + return contacts; +} + +void FileSystem::writeContacts(QString file, QList contacts) +{ + QFile _file(file); + _file.open(QIODevice::ReadWrite | QIODevice::Truncate); + QDataStream out(&_file); // we will serialize the data into the file + QList> _contacts; + for(auto &item: contacts) + { + QList c; + c.push_back(item.getName()); + c.push_back(item.getPartnerAddress()); + c.push_back(item.getMyAddress()); + c.push_back(item.getCid()); + c.push_back(item.getAvatar()); + _contacts.push_back(c); + } + out << QString("v1") << _contacts; + _file.close(); +} + +FileSystem::~FileSystem() +{ + this->instance = nullptr; + this->instanced = false; + delete this->instance; +} + +FileSystem *FileSystem::instance = nullptr; +bool FileSystem::instanced = false; \ No newline at end of file diff --git a/src/FileSystem/FileSystem.h b/src/FileSystem/FileSystem.h new file mode 100644 index 0000000..995c586 --- /dev/null +++ b/src/FileSystem/FileSystem.h @@ -0,0 +1,24 @@ +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#include +#include +#include "../Model/ContactItem.h" +#include "../Crypto/FileEncryption.h" + +class FileSystem +{ + private: + static bool instanced; + static FileSystem* instance; + FileSystem(); + + public: + static FileSystem* getInstance(); + QList readContacts(QString file); + void writeContacts(QString file, QList contacts); + ~FileSystem(); + +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogContext.h b/src/Logger/LogContext.h new file mode 100644 index 0000000..bd8e988 --- /dev/null +++ b/src/Logger/LogContext.h @@ -0,0 +1,11 @@ +#ifndef LOGCONTEXT_H +#define LOGCONTEXT_H + +#include +class LogContext +{ + public: + virtual void log(std::string message) {}; +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogCrtitical.h b/src/Logger/LogCrtitical.h new file mode 100644 index 0000000..cf08849 --- /dev/null +++ b/src/Logger/LogCrtitical.h @@ -0,0 +1,18 @@ +#ifndef LOGCRITICAL_H +#define LOGCRITICAL_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogCritical : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::CRITICAL, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogDebug.h b/src/Logger/LogDebug.h new file mode 100644 index 0000000..e1dd644 --- /dev/null +++ b/src/Logger/LogDebug.h @@ -0,0 +1,18 @@ +#ifndef LOGDEBUG_H +#define LOGDEBUG_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogDebug : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::DEBUG, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogError.h b/src/Logger/LogError.h new file mode 100644 index 0000000..34399c8 --- /dev/null +++ b/src/Logger/LogError.h @@ -0,0 +1,18 @@ +#ifndef LOGERROR_H +#define LOGERROR_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogError : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::ERROR, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogFatal.h b/src/Logger/LogFatal.h new file mode 100644 index 0000000..4b376d3 --- /dev/null +++ b/src/Logger/LogFatal.h @@ -0,0 +1,18 @@ +#ifndef LOGFATAL_H +#define LOGFATAL_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogFatal : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::FATAL, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogInfo.h b/src/Logger/LogInfo.h new file mode 100644 index 0000000..2a876a1 --- /dev/null +++ b/src/Logger/LogInfo.h @@ -0,0 +1,18 @@ +#ifndef LOGINFO_H +#define LOGINFO_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogInfo : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::INFO, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogStrategy.h b/src/Logger/LogStrategy.h new file mode 100644 index 0000000..d619ae0 --- /dev/null +++ b/src/Logger/LogStrategy.h @@ -0,0 +1,11 @@ +#ifndef LOGSTRATEGY_H +#define LOGSTRATEGY_H + +#include +class LogStrategy +{ + public: + virtual void log(std::string message) {}; +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogSuccess.h b/src/Logger/LogSuccess.h new file mode 100644 index 0000000..8dae948 --- /dev/null +++ b/src/Logger/LogSuccess.h @@ -0,0 +1,18 @@ +#ifndef LOGSUCCESS_H +#define LOGSUCCESS_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogSuccess : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::SUCCESS, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogType.h b/src/Logger/LogType.h new file mode 100644 index 0000000..3cb006a --- /dev/null +++ b/src/Logger/LogType.h @@ -0,0 +1,47 @@ +#ifndef LOGTYPE_H +#define LOGTYPE_H + +#include + +class LogType +{ + public: + enum TYPE { + INFO = 0, + DEBUG = 1, + SUCCESS = 2, + WARNING = 3, + ERROR = 4, + FATAL = 5, + CRITICAL = 6 + }; + + static std::string enum2String(int type) + { + switch (type) + { + default: + case 0: + return "INFO"; + + case 1: + return "DEBUG"; + + case 2: + return "SUCCESS"; + + case 3: + return "WARNING"; + + case 4: + return "ERROR"; + + case 5: + return "FATAL"; + + case 6: + return "CRITICAL"; + } + } +}; +#endif \ No newline at end of file diff --git a/src/Logger/LogWarning.h b/src/Logger/LogWarning.h new file mode 100644 index 0000000..58d6222 --- /dev/null +++ b/src/Logger/LogWarning.h @@ -0,0 +1,18 @@ +#ifndef LOGWARNING_H +#define LOGWARNING_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogWarning : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::WARNING, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogWriter.cpp b/src/Logger/LogWriter.cpp new file mode 100644 index 0000000..622de6a --- /dev/null +++ b/src/Logger/LogWriter.cpp @@ -0,0 +1,35 @@ +#include "LogWriter.h" + +LogWriter* LogWriter::getInstance() +{ + if(instance == nullptr) + instance = new LogWriter(); + + return instance; +} + +void LogWriter::setLogFile(std::string file) +{ + this->logfile = file; +} + +void LogWriter::write(LogType::TYPE type, std::string message) +{ + std::ofstream writer(this->logfile, std::ios::out | std::ios::app); + if(writer.good()) + { + time_t now = time(0); + tm *ltm = localtime(&now); + std::stringstream ss; + ss << "[" << LogType::enum2String(type) << "] " << + ltm->tm_mon << "-" << + ltm->tm_mday << "-" << + (1900 + ltm->tm_year) << " " << + ltm->tm_hour << ":" << + ltm->tm_min << ":" << + ltm->tm_sec << " > " << message; + writer << ss.str() << "\n"; + } + + writer.close(); +} \ No newline at end of file diff --git a/src/Logger/LogWriter.h b/src/Logger/LogWriter.h new file mode 100644 index 0000000..f4e9776 --- /dev/null +++ b/src/Logger/LogWriter.h @@ -0,0 +1,22 @@ +#ifndef LOGWRITER_H +#define LOGWRITER_H + +#include +#include +#include +#include +#include "LogType.h" + +class LogWriter +{ + public: + static LogWriter* getInstance(); + std::string logfile = ""; + void setLogFile(std::string file); + void write(LogType::TYPE t, std::string message); + + private: + static LogWriter* instance; +}; + +#endif \ No newline at end of file diff --git a/src/Logger/Logger.h b/src/Logger/Logger.h new file mode 100644 index 0000000..4a307c8 --- /dev/null +++ b/src/Logger/Logger.h @@ -0,0 +1,25 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include "LogContext.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class Logger : LogContext +{ + private: + LogStrategy * strategy = nullptr; + + public: + Logger(LogStrategy * strategy) + { + this->strategy = strategy; + } + + void log(std::string message) + { + this->strategy->log(message); + } +}; +LogWriter* LogWriter::instance = nullptr; +#endif \ No newline at end of file diff --git a/src/Logger/SimpleLogger.h b/src/Logger/SimpleLogger.h new file mode 100644 index 0000000..7d18dc3 --- /dev/null +++ b/src/Logger/SimpleLogger.h @@ -0,0 +1,84 @@ +#ifndef SIMPLELOGGER_H +#define SIMPLELOGGER_H + +#include "Logger.h" +#include "LogInfo.h" +#include "LogDebug.h" +#include "LogSuccess.h" +#include "LogWarning.h" +#include "LogError.h" +#include "LogFatal.h" +#include "LogCrtitical.h" +#include "LogWriter.h" + +class SimpleLogger +{ + public: + SimpleLogger() + { + LogWriter::getInstance()->setLogFile("log.txt"); + } + + SimpleLogger(std::string logFile) + { + LogWriter::getInstance()->setLogFile(logFile); + } + + void logInfo(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogInfo(); + logger = new Logger(li); + logger->log(message); + } + + void logDebug(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogDebug(); + logger = new Logger(li); + logger->log(message); + } + + void logSuccess(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogSuccess(); + logger = new Logger(li); + logger->log(message); + } + + void logWarning(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogWarning(); + logger = new Logger(li); + logger->log(message); + } + + void logError(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogError(); + logger = new Logger(li); + logger->log(message); + } + + void logFatal(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogFatal(); + logger = new Logger(li); + logger->log(message); + } + + void logCritical(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogCritical(); + logger = new Logger(li); + logger->log(message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/test.cpp b/src/Logger/test.cpp new file mode 100644 index 0000000..a717d18 --- /dev/null +++ b/src/Logger/test.cpp @@ -0,0 +1,14 @@ +#include "SimpleLogger.h" + +int main(int argc, char** argv) +{ + SimpleLogger sl = SimpleLogger("/tmp/simplelog.log"); + sl.logInfo("test info"); + sl.logDebug("test debug"); + sl.logSuccess("test success"); + sl.logWarning("test warning"); + sl.logError("test error"); + sl.logFatal("test fatal"); + sl.logCritical("test critical"); + return 0; +} \ No newline at end of file diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 8c4d132..55a3b5e 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -7,6 +7,7 @@ #include "settings.h" #include "mainwindow.h" #include "controller.h" +#include "FileSystem/FileSystem.h" AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) @@ -362,7 +363,7 @@ AddressBook::AddressBook() void AddressBook::readFromStorage() { - QFile file(AddressBook::writeableFile()); + /*QFile file(AddressBook::writeableFile()); if (file.exists()) { @@ -392,15 +393,17 @@ void AddressBook::readFromStorage() file.close(); } }else{ - { - qDebug() << "No Hush contacts found on disk!"; - } -} + { + qDebug() << "No Hush contacts found on disk!"; + } + }*/ + allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); } void AddressBook::writeToStorage() { - QFile file(AddressBook::writeableFile()); + FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), allLabels); + /*QFile file(AddressBook::writeableFile()); file.open(QIODevice::ReadWrite | QIODevice::Truncate); QDataStream out(&file); // we will serialize the data into the file QList> contacts; @@ -415,7 +418,7 @@ void AddressBook::writeToStorage() contacts.push_back(c); } out << QString("v1") << contacts; - file.close(); + file.close();*/ } QString AddressBook::writeableFile() diff --git a/src/addressbook.h b/src/addressbook.h index fee3ac6..8e32fe8 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -3,6 +3,7 @@ #include "precompiled.h" #include "contactmodel.h" +#include "FileSystem/FileSystem.h" class MainWindow; From d4bf7a83c8b3bdac7948104c946c6aba63e56392 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sun, 17 May 2020 14:12:27 +0200 Subject: [PATCH 109/253] update// implemented dump method to each datastoretype --- .gdb_history | 35 ++++++++++++++++++++ peda-session-SilentDragonLite.txt | 2 ++ silentdragon-lite.pro | 1 + src/Chat/Chat.cpp | 2 +- src/DataStore/ChatDataStore.cpp | 11 +++++++ src/DataStore/ContactDataStore.cpp | 53 ++++++++++++++++++++++++++++++ src/DataStore/ContactDataStore.h | 34 +++++++++++++++++++ src/DataStore/DataStore.cpp | 5 +++ src/DataStore/DataStore.h | 2 ++ src/Model/ChatItem.cpp | 16 +++++++++ src/Model/ChatItem.h | 2 ++ src/Model/ContactItem.cpp | 11 +++++++ src/Model/ContactItem.h | 2 ++ src/addressbook.cpp | 8 +++++ 14 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 .gdb_history create mode 100644 peda-session-SilentDragonLite.txt create mode 100644 src/DataStore/ContactDataStore.cpp create mode 100644 src/DataStore/ContactDataStore.h diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..2eb34c2 --- /dev/null +++ b/.gdb_history @@ -0,0 +1,35 @@ +b ContactDataStore::dump() +r +n +q +b ContactDataStore::dump() +r +n +c +./build.sh +$(./build.sh) +$(./build.sh) +q +r +q +r +b ContactDataStore::dump() +r +n +b ContactItem::toJson() +r +c +n +q +b ContactItem::toJson() +r +n +c +c +c +c +c +c +c +c +q diff --git a/peda-session-SilentDragonLite.txt b/peda-session-SilentDragonLite.txt new file mode 100644 index 0000000..87f58c8 --- /dev/null +++ b/peda-session-SilentDragonLite.txt @@ -0,0 +1,2 @@ +break ContactItem::toJson() + diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 56c9e4c..bb10655 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -75,6 +75,7 @@ SOURCES += \ src/DataStore/DataStore.cpp \ src/DataStore/ChatDataStore.cpp \ src/DataStore/SietchDataStore.cpp \ + src/DataStore/ContactDataStore.cpp \ src/Model/ChatItem.cpp \ src/Model/ContactRequestChatItem.cpp \ src/Model/ContactItem.cpp \ diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index 5b34929..c7d6637 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -12,7 +12,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) // ui->lcdNumber->setStyleSheet("background-color: red"); // ui->lcdNumber->setPalette(Qt::red); // ui->lcdNumber->display("1"); - + DataStore::getChatDataStore()->dump(); // test to see if the chat items in datastore are correctly dumped to json for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { for (auto &c : DataStore::getChatDataStore()->getAllMemos()) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 5223d04..ff56c79 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -32,6 +32,17 @@ ChatItem ChatDataStore::getData(QString key) QString ChatDataStore::dump() { + json chats; + chats["count"] = this->data.size(); + json j = {}; + for (auto &c: this->data) + { + j.push_back(c.second.toJson()); + } + chats["chatitems"] = j; + + std::string dump = chats.dump(4); + qDebug() << dump.c_str(); return ""; } diff --git a/src/DataStore/ContactDataStore.cpp b/src/DataStore/ContactDataStore.cpp new file mode 100644 index 0000000..4a1f691 --- /dev/null +++ b/src/DataStore/ContactDataStore.cpp @@ -0,0 +1,53 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + +#include "ContactDataStore.h" +#include + +ContactDataStore* ContactDataStore::getInstance() +{ + if(!ContactDataStore::instanced) + { + ContactDataStore::instanced = true; + ContactDataStore::instance = new ContactDataStore(); + } + + return ContactDataStore::instance; +} + +void ContactDataStore::clear() +{ + this->data.clear(); +} + + +void ContactDataStore::setData(QString key, ContactItem value) +{ + this->data[key] = value; +} + +ContactItem ContactDataStore::getData(QString key) +{ + return this->data[key]; +} + +QString ContactDataStore::dump() +{ + json contacts; + contacts["count"] = this->data.size(); + json j = {}; + for (auto &c: this->data) + { + qDebug() << c.second.toQTString(); + c.second.toJson(); + j.push_back(c.second.toJson()); + } + contacts["contacts"] = j; + + std::string dump = contacts.dump(4); + qDebug() << dump.c_str(); + return ""; +} + +ContactDataStore* ContactDataStore::instance = nullptr; +bool ContactDataStore::instanced = false; \ No newline at end of file diff --git a/src/DataStore/ContactDataStore.h b/src/DataStore/ContactDataStore.h new file mode 100644 index 0000000..009657e --- /dev/null +++ b/src/DataStore/ContactDataStore.h @@ -0,0 +1,34 @@ +#ifndef CONTACTDATASTORE_H +#define CONTACTDATASTORE_H +#include "../Model/ContactItem.h" +#include +using json = nlohmann::json; + +class ContactDataStore +{ + private: + static bool instanced; + static ContactDataStore* instance; + std::map data; + ContactDataStore() + { + + } + + public: + static ContactDataStore* getInstance(); + void clear(); + void setData(QString key, ContactItem value); + ContactItem getData(QString key); + QString dump(); + + ~ContactDataStore() + { + ContactDataStore::instanced = false; + ContactDataStore::instance = nullptr; + } +}; + + + +#endif \ No newline at end of file diff --git a/src/DataStore/DataStore.cpp b/src/DataStore/DataStore.cpp index d16c255..ae85ed6 100644 --- a/src/DataStore/DataStore.cpp +++ b/src/DataStore/DataStore.cpp @@ -8,4 +8,9 @@ SietchDataStore* DataStore::getSietchDataStore() ChatDataStore* DataStore::getChatDataStore() { return ChatDataStore::getInstance(); +} + +ContactDataStore* DataStore::getContactDataStore() +{ + return ContactDataStore::getInstance(); } \ No newline at end of file diff --git a/src/DataStore/DataStore.h b/src/DataStore/DataStore.h index 6715c02..9fa42d3 100644 --- a/src/DataStore/DataStore.h +++ b/src/DataStore/DataStore.h @@ -3,12 +3,14 @@ #include "SietchDataStore.h" #include "ChatDataStore.h" +#include "ContactDataStore.h" class DataStore { public: static SietchDataStore* getSietchDataStore(); static ChatDataStore* getChatDataStore(); + static ContactDataStore* getContactDataStore(); }; #endif \ No newline at end of file diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index afdde53..dd43785 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -150,6 +150,22 @@ QString ChatItem::toChatLine() return line; } +json ChatItem::toJson() +{ + json j; + j["_timestamp"] = _timestamp; + j["_address"] = _address.toStdString(); + j["_contact"] = _contact.toStdString(); + j["_memo"] = _memo.toStdString(); + j["_requestZaddr"] = _requestZaddr.toStdString(); + j["_type"] = _type.toStdString(); + j["_cid"] = _cid.toStdString(); + j["_txid"] = _txid.toStdString(); + j["_confirmations"] = _confirmations; + j["_outgoing"] = _outgoing; + return j; +} + ChatItem::~ChatItem() { diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h index 6f27609..be8a807 100644 --- a/src/Model/ChatItem.h +++ b/src/Model/ChatItem.h @@ -5,6 +5,7 @@ #define CHATITEM_H #include +using json = nlohmann::json; class ChatItem { @@ -45,6 +46,7 @@ class ChatItem void setConfirmations(int confirmations); void toggleOutgo(); QString toChatLine(); + json toJson(); ~ChatItem(); }; diff --git a/src/Model/ContactItem.cpp b/src/Model/ContactItem.cpp index f338552..d38c1c5 100644 --- a/src/Model/ContactItem.cpp +++ b/src/Model/ContactItem.cpp @@ -63,4 +63,15 @@ void ContactItem::setAvatar(QString avatar) QString ContactItem::toQTString() { return _name + "|" + _partnerAddress + "|" + _myAddress + "|" + _cid + "|" + _avatar; +} + +json ContactItem::toJson() +{ + json j; + j["_myAddress"] = _myAddress.toStdString(); + j["_partnerAddress"] = _partnerAddress.toStdString(); + j["_name"] = _name.toStdString(); + j["_cid"] = _cid.toStdString(); + j["_avatar"] = _avatar.toStdString(); + return j; } \ No newline at end of file diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index a18d0f7..f066740 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -3,6 +3,7 @@ #include #include +using json = nlohmann::json; class ContactItem { @@ -27,6 +28,7 @@ public: void setcid(QString cid); void setAvatar(QString avatar); QString toQTString(); + json toJson(); }; #endif \ No newline at end of file diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 55a3b5e..58c8695 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -7,6 +7,7 @@ #include "settings.h" #include "mainwindow.h" #include "controller.h" +#include "DataStore/DataStore.h" #include "FileSystem/FileSystem.h" @@ -398,6 +399,13 @@ void AddressBook::readFromStorage() } }*/ allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); + + // test to see if the contact items in datastore are correctly dumped to json + for(ContactItem item: allLabels) + { + DataStore::getContactDataStore()->setData(item.getCid(), item); + } + DataStore::getContactDataStore()->dump(); } void AddressBook::writeToStorage() From e6b8f000c94ff14f5f7f6dfe5c839334bc6246ad Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sun, 17 May 2020 14:57:38 +0200 Subject: [PATCH 110/253] update// added new writer method to filesystem to convert old format to new --- .gdb_history | 15 +++++++ peda-session-SilentDragonLite.txt | 2 +- src/DataStore/ChatDataStore.cpp | 5 +-- src/DataStore/ContactDataStore.cpp | 5 +-- src/FileSystem/FileSystem.cpp | 65 +++++++++++++++++++++--------- src/FileSystem/FileSystem.h | 9 ++++- src/addressbook.cpp | 7 +++- 7 files changed, 76 insertions(+), 32 deletions(-) diff --git a/.gdb_history b/.gdb_history index 2eb34c2..4e303b8 100644 --- a/.gdb_history +++ b/.gdb_history @@ -33,3 +33,18 @@ c c c q +b FileSystem::writeContacts(QString file, json j) +b FileSystem::writeContacts +r +q +b FileSystem::writeContacts +r +b ContactDataStore::dump() +r +c +n +q +b FileSystem::writeContacts +r +n +q diff --git a/peda-session-SilentDragonLite.txt b/peda-session-SilentDragonLite.txt index 87f58c8..f57fa7c 100644 --- a/peda-session-SilentDragonLite.txt +++ b/peda-session-SilentDragonLite.txt @@ -1,2 +1,2 @@ -break ContactItem::toJson() +break FileSystem::writeContacts diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index ff56c79..22c10f5 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -40,10 +40,7 @@ QString ChatDataStore::dump() j.push_back(c.second.toJson()); } chats["chatitems"] = j; - - std::string dump = chats.dump(4); - qDebug() << dump.c_str(); - return ""; + return QString::fromStdString(chats.dump()); } std::map ChatDataStore::getAllRawChatItems() diff --git a/src/DataStore/ContactDataStore.cpp b/src/DataStore/ContactDataStore.cpp index 4a1f691..e853770 100644 --- a/src/DataStore/ContactDataStore.cpp +++ b/src/DataStore/ContactDataStore.cpp @@ -43,10 +43,7 @@ QString ContactDataStore::dump() j.push_back(c.second.toJson()); } contacts["contacts"] = j; - - std::string dump = contacts.dump(4); - qDebug() << dump.c_str(); - return ""; + return QString::fromStdString(contacts.dump(4)); } ContactDataStore* ContactDataStore::instance = nullptr; diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 5ee2fef..49c8178 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -20,6 +20,51 @@ FileSystem* FileSystem::getInstance() } QList FileSystem::readContacts(QString file) +{ + return this->readContactsOldFormat(file); //will be called if addresses are in the old dat-format +} + +void FileSystem::writeContacts(QString file, QString data) +{ + qDebug() << data; + QFile _file(file); + if (_file.exists()) + { + std::ofstream f(file.toStdString().c_str()); + if(f.is_open()) + { + f << data.toStdString(); + } + + f.close(); + } + else + { + qInfo() << file << "not exist"; + } +} + +void FileSystem::writeContactsOldFormat(QString file, QList contacts) +{ + QFile _file(file); + _file.open(QIODevice::ReadWrite | QIODevice::Truncate); + QDataStream out(&_file); // we will serialize the data into the file + QList> _contacts; + for(auto &item: contacts) + { + QList c; + c.push_back(item.getName()); + c.push_back(item.getPartnerAddress()); + c.push_back(item.getMyAddress()); + c.push_back(item.getCid()); + c.push_back(item.getAvatar()); + _contacts.push_back(c); + } + out << QString("v1") << _contacts; + _file.close(); +} + +QList FileSystem::readContactsOldFormat(QString file) { QList contacts; QFile _file(file); @@ -51,26 +96,6 @@ QList FileSystem::readContacts(QString file) return contacts; } -void FileSystem::writeContacts(QString file, QList contacts) -{ - QFile _file(file); - _file.open(QIODevice::ReadWrite | QIODevice::Truncate); - QDataStream out(&_file); // we will serialize the data into the file - QList> _contacts; - for(auto &item: contacts) - { - QList c; - c.push_back(item.getName()); - c.push_back(item.getPartnerAddress()); - c.push_back(item.getMyAddress()); - c.push_back(item.getCid()); - c.push_back(item.getAvatar()); - _contacts.push_back(c); - } - out << QString("v1") << _contacts; - _file.close(); -} - FileSystem::~FileSystem() { this->instance = nullptr; diff --git a/src/FileSystem/FileSystem.h b/src/FileSystem/FileSystem.h index 995c586..30dd5fc 100644 --- a/src/FileSystem/FileSystem.h +++ b/src/FileSystem/FileSystem.h @@ -5,7 +5,8 @@ #include #include "../Model/ContactItem.h" #include "../Crypto/FileEncryption.h" - +#include +using json = nlohmann::json; class FileSystem { private: @@ -16,7 +17,11 @@ class FileSystem public: static FileSystem* getInstance(); QList readContacts(QString file); - void writeContacts(QString file, QList contacts); + void writeContacts(QString file, QString data); + + //converter + QList readContactsOldFormat(QString file); + void writeContactsOldFormat(QString file, QList contacts); ~FileSystem(); }; diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 58c8695..b557dd9 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -406,11 +406,16 @@ void AddressBook::readFromStorage() DataStore::getContactDataStore()->setData(item.getCid(), item); } DataStore::getContactDataStore()->dump(); + AddressBook::writeToStorage(); } void AddressBook::writeToStorage() { - FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), allLabels); + //FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), DataStore::getContactDataStore()->dump()); + + FileSystem::getInstance()->writeContactsOldFormat(AddressBook::writeableFile(), allLabels); + + /*QFile file(AddressBook::writeableFile()); file.open(QIODevice::ReadWrite | QIODevice::Truncate); QDataStream out(&file); // we will serialize the data into the file From ea7f3bc72a50cb641c19a4fbf5913f0195629cf7 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Sun, 17 May 2020 15:03:49 +0200 Subject: [PATCH 111/253] update// implemented reader for addressbook --- src/FileSystem/FileSystem.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 49c8178..d560d98 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -22,6 +22,23 @@ FileSystem* FileSystem::getInstance() QList FileSystem::readContacts(QString file) { return this->readContactsOldFormat(file); //will be called if addresses are in the old dat-format + + QFile _file(file); + if (_file.exists()) + { + std::ifstream f(file.toStdString().c_str(), std::ios::binary); + if(f.is_open()) + { + std::vector buffer(std::istreambuf_iterator(f), {}); + //todo covert to string to use is as json to feed the data store in addressbook + } + + f.close(); + } + else + { + qInfo() << file << "not exist"; + } } void FileSystem::writeContacts(QString file, QString data) @@ -33,6 +50,8 @@ void FileSystem::writeContacts(QString file, QString data) std::ofstream f(file.toStdString().c_str()); if(f.is_open()) { + //ENCRYPT HERE + f << data.toStdString(); } From 3431af2f6e6e29658562125776996fdac0b5a15f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 17 May 2020 19:39:14 +0200 Subject: [PATCH 112/253] update lib --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 01613d0..b48d1b4 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=e368816c6d12267f25fbebec0aaac4c15d62d2a3)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359#32ca60735b3529ff8589ab08fc16678f508a9359" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=e368816c6d12267f25fbebec0aaac4c15d62d2a3#e368816c6d12267f25fbebec0aaac4c15d62d2a3" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=e368816c6d12267f25fbebec0aaac4c15d62d2a3)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index fba5265..9784a1a 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "32ca60735b3529ff8589ab08fc16678f508a9359" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "e368816c6d12267f25fbebec0aaac4c15d62d2a3" } From 41e3bbdfae808f7496aab68dca27c4570686b64c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 20 May 2020 20:53:14 +0200 Subject: [PATCH 113/253] add new icons, dont write over send button --- application.qrc | 9 +++ res/addContactBlack.png | Bin 0 -> 21089 bytes res/addContactWhite.png | Bin 0 -> 12617 bytes res/getAddrBlack.png | Bin 0 -> 20966 bytes res/getAddrWhite.png | Bin 0 -> 12887 bytes res/lock_green.png | Bin 0 -> 1041 bytes res/requestBlack.png | Bin 0 -> 22429 bytes res/requestWhite.png | Bin 0 -> 12883 bytes res/send-white.png | Bin 0 -> 11875 bytes res/sendBlack.png | Bin 0 -> 16812 bytes res/unlocked.png | Bin 0 -> 1006 bytes src/DataStore/ChatDataStore.cpp | 24 ++++++- src/DataStore/ChatDataStore.h | 3 +- src/chatmodel.cpp | 77 ++++++++++++----------- src/chatmodel.h | 5 ++ src/contactrequest.ui | 18 ++++-- src/mainwindow.cpp | 29 ++++----- src/mainwindow.h | 5 -- src/mainwindow.ui | 108 ++++++++++++++------------------ 19 files changed, 152 insertions(+), 126 deletions(-) create mode 100644 res/addContactBlack.png create mode 100644 res/addContactWhite.png create mode 100644 res/getAddrBlack.png create mode 100644 res/getAddrWhite.png create mode 100644 res/lock_green.png create mode 100644 res/requestBlack.png create mode 100644 res/requestWhite.png create mode 100644 res/send-white.png create mode 100644 res/sendBlack.png create mode 100644 res/unlocked.png diff --git a/application.qrc b/application.qrc index d323bff..7ab9af5 100644 --- a/application.qrc +++ b/application.qrc @@ -41,6 +41,15 @@ res/lock_green.svg res/lock_blue.svg res/unlocked.svg + res/getAddrWhite.png + res/send-white.png + res/requestWhite.png + res/addContactWhite.png + res/getAddrBlack.png + res/sendBlack.png + res/requestBlack.png + res/addContactBlack.png +
res/hushdlogo.gif diff --git a/res/addContactBlack.png b/res/addContactBlack.png new file mode 100644 index 0000000000000000000000000000000000000000..984c6e3e10659d2923f961ae2243b0be928b56da GIT binary patch literal 21089 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 literal 0 HcmV?d00001 diff --git a/res/addContactWhite.png b/res/addContactWhite.png new file mode 100644 index 0000000000000000000000000000000000000000..fea4efc6eb1278e228ffb015041034d288a69afc GIT binary patch literal 12617 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 ab|vNW;h(G-u@8fPCX7!>JUC8X{Qm(Zf7iAE literal 0 HcmV?d00001 diff --git a/res/getAddrWhite.png b/res/getAddrWhite.png new file mode 100644 index 0000000000000000000000000000000000000000..6caeeae319540c6c3bbc1b0b91af02aa7e042a72 GIT binary patch literal 12887 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 literal 0 HcmV?d00001 diff --git a/res/lock_green.png b/res/lock_green.png new file mode 100644 index 0000000000000000000000000000000000000000..cd7c2abaa256da5a3c5675a42e005578830973b6 GIT binary patch literal 1041 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 literal 0 HcmV?d00001 diff --git a/res/send-white.png b/res/send-white.png new file mode 100644 index 0000000000000000000000000000000000000000..96c76214708a25c7218a7472b9aadcb520517890 GIT binary patch literal 11875 zcmc&)e^iuZzJF(6M#KRz5r;vLz-%nEK}SNA7Q+TCF(~i3Ub1%hWrJ5#3{zP%7!1J% zknZZLyLO@1W4M_ScS_xxEhETkW|#N+BPF+VwIb23x!N&L<^6u2U++7JR%icM&+#Y^ z&-;D8KR(}|&r_Q{J0m365-dql$jrY4I{2Vr z-B<8)WZ5Hg%br|3zifHl(jsYk;o|(F*qJ4H&lWvVlvlX2^ia_>Ng97`=8WlcR`gu- zCF&$8s6F=5=<84EMNmY{3qn)oeIslyvry2%e*~-9(NbWyE1*C_YR(`@*E!J=h~Fe!K6~jC-KmtZu?Zh0TW;Xe zD4^kyKbeyO$Cf0R9JZd=NI2CMP$5}LoXAm6g}G!6VXY-p(!0EsiNK>PKHvKd{>R#s zA_X-m#xCGm4yjcff5HD$T##Zb98qRGA!)25Dn<@z05-J*3i9Ds$^8kegY(YxCt!v1 zsz4_FA2nPx;d%A_h|0GTEy*TAob)5=%^^Y*_z_hc2axx=IzOUOBZv@5ew>!f`PoFP z??BYiKhE=N{NQ_<22&-oOb(*pGU<11w;qrbReRDBA3Qc3gy)4ZBEo!KZhufH`=Wj3BWu{A%h&7b z>NZFuRB`h`Xegj@s5ktO>l~Nr@V*=xuj0+}=7m($YLhwoh&hFYiV&f|LI$9%aginS zsHT0cy~z|nWq}3u;dL}pt~bbXWYtKBdA&hhnzKI8oK?imnr4nZWL|}5W!N-wt*#eQ zWj;m|wAc8I3>t1{H+tqnL?VmNJIg*OJcB{F-swr2!0oy)+JF%jgY^-KE31nU1p%_I zvc;Xg-m*jO5>=r_tf|5;wj9JDj9~d*C7N}b6Af*koIYKZxTS^d?5tFlMSAi46nCPE ztG1OQ6WDbPR9CLZRQ04K{G^>Rg8i&ke$sq)62$+p$GA@ZJLB*o9)HJnvsHs!l*|*; z@Gl7Si0igL@c2J?DMPi-wRtwnSIU}XqEVD|;p;4Yxb&l_QvlYwo@8mvewG;;Y|^)b zWuGl)nC`(pG2A(yg;zIm8Vr@jh(Y8wCOD+ zIgc1=HP3vmzhTBC1acqe8Q88c;9AXZKEU(dmbrrU6H%OX{w+klNWPX8E5zvw6XK|u ze%W9lPA3>~lSxUIOL8 zEP2>NLKB`7Q?NLJjf%R_+LQ!Ez_8=(W&vyv`^DY>s29o_zZ4wWdJdw}Vz(PvrW|n>Upj zi=ptrF^+SE^nl){wug>@V>=cE7I@>L-rGFCYz99&0#uSWiMVCT_^*{c79z3!!iF7H zBQRoFz?`v>F7ZM2@H&{SW&-!-qEN^s`>e;srek_kU# zHP4A$ppwa0JA{zI(yJdC5>QR=gK+a$ROlY}RB;GeXmLN7l#B|@i^{gXsAjj-?w!v0xIMnRFhbw5a&!oEX$C7oSl<{GoZ>KDR}9|Z^7c5 z905zhJ#)lveGd}$hIl|u4d2~w-m9a!@+5@`5^WnX+5rhnYnanj!$DfYpBTQvj8*SE z8Hx_2n;h&ow-k#aA|WaFA%eqC9Ckg;GW8S*aWlZqs5(y8wem5HtUz^=hCpx&+BMrw zlbs;Y@y0_2sMp86f`$Dk?hqv1g{%lDD7%UkG>6Ug<8OeQ^ka;YhM>GEpKoJ_VHl<>Bfk5fm=}{uw%w!<$}W1@xRf5gY8*C zV+ofchO2Rgcbjm%v|r;YZS^>EKZ?d2kQlOTD2sIz(LTXg&Bm)j5xq}+s|W37FS}0A z$(eYM)k7rMP?V~TW|JhxKf^(G`98vJ%aj!)@^Nlgb8dwm;?3O)ve6%^*QEphabS4{ z|8AWCli-VIM&bw5X!~{J9qUmuty94#$6gTzGNs;fn5L-ju2gb7+!VdP+lPr_Zgi4{ zaB%em4kp!4B;&DB3Al_M?6()V%+0d@lI>|lMse~S~rO8GNbJ$&1zo05j_X7~lIo56-|2-|)n30n1 zsER73v5l*(cLPyHb_A~jNnSfUM8KDC6h%(BX|OFNA2dhAGridcZndem*q&~ zoEq2626O>eCcsdOQy$9Fu6-1(8C_^l)_A(z9KAipkpA{PsoWy^8+uwIlc>#oh*wnv zdyKI&hV!1705N5)YeeSJ@V zt=EoG2mxdvOo5CLb55&>*a+HvSj}xtuQHV@?HScyc{ED9R?qcNGxH*g5I$?uXaLD; z7PI^kbxo$=SOcfa6#-ktsO5^YY)uI_1!-#Ntc6FjiVIs)K#g>OBNT(u#+?M6uZ}Tv z?07_@bJmuSqgXuSrRacb9Y)XW|KO3Y>h(6k`G-x&6%H+<`^Sw_Gx?YKdAK%S>!w4IOuRlGdX?p;K3~26kXUBRuu_ zJjsxlPv>7KDnW9~r;P#qga^2Y#=_b8?k?fDX;T3ev*eeqFhvnft2zNYF|xb`$+2DZ z_12u`t1tS2iZGz=9O&z~_Fg-bhjiy>S4L>nOpvPKb9bA{CrRa+!6Ha{+k?#D5_#uy zY=7{%Zp45NF}2XbpCm_8AENsExiIlnbuHPJk~NV5wL1o&uNh+g^w*i%uhAjAfY3Xy)fnZYWBAu47-KX;TEDMr2FWs=hyu-PJYoEdbDE)u zTe~j9muZlTUu224Nt?^KiCKd!x?X>~H95<+V6A~kvMGk=JOO)GdKK^5Nxh6|&u=Z3 zdL3QHsm)wR6{(>e+LD*3UZ0TqJ0+WjgXfd20TQ2P^9H(Pu4;Q4kii*mS%aaNH*dNs z6-ZD{B{(pE1h6IoB$tY=#s0SHUB}uQRfA_gYlT*|n@x_G3EX*qZ8e9yREcGZX7=9G zY8EpRLwt;9b_0nAuzC#Zy4&uwcTS_Vk9r*R`Req@muzq_~u$oVc zDJ?hX$y`;9z6rkGUNZg0acL{)b(3RAFLU@;LtZBR zY9XoY+@hZ62DtCdKEDvAV0&y&zqGG z-3etwhaI6Bx(RC}@FxzFUEa0H!N&W|S-+Q^wg;(%V|XorTGrnOtLflydZW>=79oay zO&TY6NiFUrWLg3}!AXC|eQ|w&9P-zkv_62i6=64pmGi=H{ZcCY#8eE-we>sRfk0H-MLKW|AN?|n{@$_xrckg1PJ(V!Rrm z?n>BRy&nQ~{O*gISjsNq$oO{b0!vcQ-$Ap*u0rMxfB`dS1r&9F3*&umEgRc|r>m^M zT1{<_u|BjEdPnc1@3~$by1P~6>tBOqh+I&Hd|5vi)@P+3dYc5b%3{vDVHYp_j8Nru^6jT8Vge+bJdBzK03H6FHFg&bP{4Ng5D}x|n=k>A$WgxhB6n(N z`b>bIzaSEfNbyy)T43pD%Hs2MhyVKv7#FJ&1BMGGl@;Y&)cPMEp3 zZzz!seJ&WBk!%6L?D($_5t!(GEC`@wuu2R7#pIr>e|K93^&8-2+TnR36$uKYRIzu5 znlGKIcb`2iwB=Z^FBm&C7{WNtEf?GAc=iz}GIS$2B(3I4-P0juz_j`U;OV!*58OEw z!3;~Dq*3Esb3I*TqUrR$cK~5uY+nMN5W7#{!lVD5JD@eTnFGV^3o;fAibkym6o-4d z?m4SkDL4}gLIMKatFVmW8&om%x$|HS7<=!8pKQXV0IDXAypl0-p!R}AB#Pvocw!K_ z8)~X^H-iZmDpsH?#4Q!H|~GbjownygU*s0f5i_0J3K(|LAL}sh9l-FCdyyp z#vk4x7H_QKjdd-54gpTddR2Tb!6bJ@Kg@bvB@jCrLcseq-^uBrCi$8xU) z6mdoV1!rBEs6I@<0suE3{#t4KJ-5%`WqkFbn0P6Hkj98Dimnl>VKlheP^}N~t=+vi zBY<9rU?z$u$bpwAaSVCNQq4n*M21_}%4wp#5f3@MqcjgO#FLL7**lV_&reBnmVLu7 z(vv1sPoimE3FL?@x}+j%KXx@Bh%)hc+9$&$ajYaCy@zQGBIF{Lawc(>}SkSHAj7Jc;sQT)g}e%6n5bP>*a%~@urXW{dgsz~r%m?_|M zD{3=nktkjvmuz0lt-G5o#+y3=J@xacTv%b*Akv`^Bu(V*2UQ1mA%0Ql#tVkCl;zsD;?&Hbga?szkX}{W$d}`pY>T zfGBB@`*TVXSbyKdLIDhA0S$X@60ruMxjmz=ClQp%};UK zMMkpyi4sGRI!MFmLPS3)BQ!*PM10wAcBKqR)aNPy|4V{5x*G9eGy#w4`Voa)@QT(| z?ndnc7sAe!Qc8jjjhaSB8)n@jLQQma#+>s*0%7;!*V zd^mc&(nX@6AJN&4DB7S2@H2;Iy8l@Zwkvef4~6x`2@6N3NbqOoBeQ4hdf4gyf9n(H AAOHXW literal 0 HcmV?d00001 diff --git a/res/sendBlack.png b/res/sendBlack.png new file mode 100644 index 0000000000000000000000000000000000000000..62d9d1e25f4f452aecaa6c35b682028fa361dbf3 GIT binary patch literal 16812 zcmb7seOOavAOAT!dvk0sbi!f0I7Myx_%dh$qUb^JY?>OV8JW}pF(-d3VHl>EX3U_r7dFReVaXd;GXPMVgTId@&hb#D@mVN#Fg z#-OsdZwWtEW9*ZUvDLJVQ8}!+IvMTNlA?AohU+^#q{tom75@gOFlUO6d(8hzt-+L( zTj2#5>ki8VbW4 z_V8RRMZHQn-FDYKCmAS|>-yI0U262G!!-xDwO5j&di++4m?-M$J`t$@5;p85u%LX{ z6lcF4yRdvMsdy`spcEAndF7fx5|TDd08zR6^{w}2>Tsb;A=NA9|w}4?INRn3y+aTUV%(fMpZ~xd@ zQp(aPDHSPcu!=^G2~72tBpHprV4H#;%B<0;N4hbCjnJPsTwtEQNaYaB=u;Zmb!Fz= z$2DhXgJ3AxU96;ZSrI#9|3p&pdamy4kh+Z}Iqcr?f=cy3cUyv+-QFdrKb(}_2z!hQ z@ixsV6PesYb`_Z4EL8a-CNgZra_q}*6>cxQB@4Y(G8gSL8QVVng0AB{DN4jcET@b_ zR#mbLJ@2!rj#^}WxAZAd70WI0q9#%BZTXM1=+2bWtX~-;Y7$OlQ&NUk+@xbfSuvp( zn(dniqG*qxy_W2JkR-D|j@_XC*@|6oCYL?`g_fL+X;?azbThU3k(6SyQ1jJdGUINs z$}yvkEilU#spNx0B03)%6)vyzZ`tVg0Wp|7K}XT!q8t^)4y!jLYVksMp}D>gBzwst z5Vy{E`kOwby{?df*!C9`U?p>hI_$_$hg!mX_7(!ObA;5K z;jW+F=;v;G%+0t$TA;>_WS*UIEr#BgiL6DGhn;k~pUpRTDLiP~7E_)I$Qwl;t*!t$ zzFdlR_|kN0m7CoaWSD(U5hfD1nx>vGnUF6q3g;&GH9d_V2gl=F+tdVnSgS;cPdy#0 zcC&j!!m2L-U3yJf;M#%%L~u{Py&0HtE1Z7d&XwM$={&T&j9cL9|1JP(Ha%QGuqrl6 z;ImKl@&t|Y;&%UyLvB_OQ~))rsjxS0D_Uz_mb&fHSid0HP@bRs2qf{=%R+iH%qtaL;a(7s! z0mp+Ivxf@sXBX#A=2YSkOzgs%0{0xbED^LZSL&GlBz^7~j!z>I<^mBcc_SAKd1#$o zRGXPJs63uV0t0o3v2kOlw&4S4TcL^#iaR#S-8L9h?hq7P3Awv%xEqu5^c{(f2D{4* z+Z3cPCx)ey)rNgD=^*B{F3Xcr@cpqYW2x+m*}PRg6<)>v2#$# z0*=A}refDkuKVtph#Th})<_}jViqp!(T}2HHkc!?ARRI;%ydAg-+s72ucgIE#*vOH ze*-r9(!|Lf4d?}xT!T58gM;EvljD(64LbXaO;aod=5}N>xw^ZafT=}_0Y;@;lh(&Z z_mjKbQHVXOw;yeIoW}S?FP^I-I|nCoab`MW)-S9^=p64QpL2%gfGfS$%8{eR&ztDK zVZ~ble#MFEDA$aB>6<@f^m>lzERvn|_l&pLzwhZoIp?G^nlh-Gch>3wzh|64koG zOBr^@U;6>Fh%jWJTZ)+2XqO$(%E%cpjep|}TsngXnbj%6e5ZC?F~mmm>{5?o$38Er z-x06jd{}-jb&QJCY#nciIHN|^>kxFLCSTr`k}MW;PHg+k8FqeVZ6BAeLDdoYKc~n7 zybosnr)3k-6i8`D=m84V=3x21!&Brt^_I+cTY#=^-tcAOIQHYi9}MbjnLY^ZeaskW zYamO;p_~T3?ZRCa1529_>wY+pp-!=dc^1g{;Mb{f|7!1iK#5SybtVL8?kknXf z;@nCmelal%oYF*aLfN?1xpku-QWB2q%m_N7XLlrTApRB(je*r7Y(nMI-n-byAW#Rb z&dt3)q(Fcd}d7Scx2IE8Nm5bcbd#Zv;Ti;#S zJ1?ZNk|H3sT!?Yr-6w6W=1|q)SM;P5$tJ&N^M6+2(~VaQSwUUWxH=CzIC+41e3#^Cbu; zL&%KTabZa9V)5>kxex~{&vK{+W_~9&<`=`6RtmY<&LIV4#9y=u;h==7%@gvg`#J&T#jVcV6fs zbe+=v7ktFbIl~;{3%riHgmzEzuO~`>QNeD8DYGl_H4(#I|8=He&`s?E55nxs+bB6lP{_v71+bOt*Wit2vpy&l7 zbdFg&gFu}w6~4Vc*1mNyP?+Xq+QIk(;euAbK7Du4kMg|tFY2EXD5<917Q8cMeB-dU z{_?!r|1{*1yh13vsrcGRp!kmwulxUTUJ|FZs%3MxJR!3C_rJlvLPkA(j1c-tNiUfp zThC--AIa76ejXVGy4u&)HrVxG%7Z&S?DDtd{u8@#V;MWrl4MrJZ>#Qor zET?=V_0f|4aVr(Yr?!PSQIlWK83va9ra^ZPB8^Sl)Asc(en+xXbwYUCE+`&|5}K!v6SvcaAv?nE5199%ye3Ont!?#(Y;d{Rv%2AekOZ z_4_g6M4-1OZEA9v>ui_scJIff^}#4Tm@y`JL`o{Fc#E*?Tla~(gk(XSs@#Qx2!IUiDloW+`y z{~U=+U73@o3YIbKTBqZK7w=4@jeW3I;?VT^II z$3rqa!T5eYAcR%E^{`{E9~?9@E35y>h+&_HOgKxar6ydoMS+pKb`HVCai)s>j9#I5 zhH8tQw`9j}aU{KO7Duyf(0camk8G=^t2M0nN6_x3>i{Pv8(VX=Py0&TR<>sl|Gds} z_|^K~(|WujrXx8nJRv3|@Krjk!2$I8oD3EAi{H9FK-g-IJpC^v`N$hb4+(_IHWTF( zsIBb9o`0fZ3R!U-kZ^lfe^Az3P!={!=UDzk{4C9@X=TMBv)IV^4mE?#WPT(j&U>)V z)ZM!6v+M(P!o7#Xnl9MfOL_0M35N>4{8nUZP6Ast(K^?kFM%~TMVyRyF`}Y^D+Xoa ze&k#?3D32(j$ZLZ{8`Mrrty;T&aFT>PY&jF#h|^s$td7AkRM~_js>3o#|tk0r}OMoxkHK8Fwihe*e}; zLP&S$`$a08BKIjSgi-G&zf+)Ga1>Wk1jMKGvZPhieUs9q*Y~%~Xby^vr8Td*49MO* zYSQhFP7D{y?SqeHp7pKMb)YhyQTe3uyIO?3J<^sypjo=C$RXxSTR>JYQcesSo`^7d z-!xRnq6G3Do|FGCUC!G8I+T-fR6OUH(WP6kJTE@Tf?Z11eFXu{f82tIyW|b%PX&#f zn(V@k8{fPM34yp!Nc8xD!K(jR+lr6x8~{&ubKf4Z;C16lAcY7D4+ju)6k4G0#ZtR&4E ze$V~RA`H(y3SczwEDG0{K<4Y!$!f7sILH<>j>*NOnzC6{?b}*zXeoiaZD@#;4VhTR zHfZZ;8fR2d8Rl2@%MEz{yV#7Et!^*%%lg#xHCz~{#9^-Z$nB73?LNoJSxZR-#7C(w z?_q=3h(}RJU#@|Q^|C@xxwJPP*mcw`P%R=X(9vm*MGNSY4u`yH`Q-N`*pbrpWZ!8xb0| z+TJLky_FKNJM~})D9jT54@V%|(Jy7F_(|#aGi2p>KX+!I`NaFo!Wa!}8gEUSzr-OZ z^ahOQLSXja^cO+2Uy55y?dUADl`u`D7 zydN@|PW&4~B`jMEPW9nf)JKBUl8-lEvj-Aep+&6Ei%;SDGzDuy=*E5(KaTrsJAC%s z6|E}@krI09qQxJ{1yaocz0TE^=>Fxho5>k|2cU^}a;2g+B^HokhV67Fh>!9HD)xks z6-$4yefw}+swp0)qhJ1)o9$rC+lwAqc$^#_Zh*&^WiI?U+y{n0DtO*VW`Ve zmsSLrF#n_7hCb|=f8hz|5&-PoG_kP0Kgxe)zV0jBbAEBE@;`KpefEQmuUUnG^fvJx_x z^38&+nX9{HZiJ^8(oL{qcaPZe!U%Z&dL#()N3AQGj2{t;8h7Z$2rWv`%U>6_1nz;p z$7-mbayt8b%qUjf=mE7JQIoz0hr`_klc7ZZpQVpXKqh}v+JaJUUq;oOU)0c_52-=a zy6X^N#qhFc)1Vlp>h~B>uNPrH6{XW0T`l2?AUC76_>Vn8?~$wPS!~EBko{+@QOQf6 zDAV6?hNL7aIz1nxG(M38ax!FMrDN6`j)xDw`4h;QMKrylKWOk`R{s)cXLHoBpHY?_ z{)G@wq1`0PN~+oReO-D;hS8M^ekX*=X$rZ?JE`%hQk7g!W(6OU-2U$8M(5;-9dx zPuaL=_RV3CPC*MVSNCS-iAO%n$NeSH2^w<1f{#8qkZuCmPSK^$1i5H4(Vxd%eeAfp^`eO*U{1IDy)P3yAyUk^0fS!K);~v zrCByULaIQzHh_GI3KP{gtTtPq#2opkW+F6ccOk`|@unKJcbMYb0mml43{@HL!z$eR z*S~K@7l%~*}(~=c^w1CRk@c8uguLFE;+_xyX(FRfQsXpPLg*^($u1};| zQ9dHGk5pnQmC%Dm1wW$JHNtaj7KGR8){=jsB&^kfqAyDC07Lbnb>H^G_=!`~Kq0m7 z557SG%TlrIi+h3ITfoZC8koI&R+Yq0_<&se2KLzm7YJ~PejV-AiT{Ae335UK(x>WL z#(?L3Cbl=38l2X_;q;0;H10!IEv~fyT;~Dku0H2xNDJq;yj@~yNK7{_1@&*eswKzp z0^m7__k8lyK(MQGp#Fj%8WSKugqVx*jPHgO8`KCUQe^f>G9!I`=wa?-;qM58PFaQZ zr)@~^oJ>|AO_Ty>XJG!>)Q_zQAC!L`qBYL}*405m*$RCdHv@@`yD4aYVrYt^nnH8R(NpNE1Bh=}k z3A^zS0-sTCrrP$%Vrt0uPMr0Soh_*{TELq>r`}p&-I@;Y3+U^r9CLML2e{4+;wFPl zN&`J{G|#s1XvItC22Zq>BYH4OXF`_?8Mt5f!93L{7C0P^er|7{ zVB~So=jXkWPA54W;K(wCCPwhp~KIX-Aj{@-9I|E0{N5$xPBWVA5AQ^3OP;F zuld0j5|wE@`g8V@6Ajg7K#D3TCGVL0&ynymHzyZJA0ehyaz6li=ZCzQK+eSqZg0Ev zk44%>)N|xU@D$4f7Gj~p=L+wmR{C(0`kKsPsKdw&=#`kc>44Xy<4P^i?VF&c!Wd4| zIar|R%wN#DN2QU=5wO%izagw<(5WEe%qMz!O8+~Fxuba4i~)&D35%2K?(cs;*dNuEP+#FJ@; zh{ezEF-TYwflNorDCkx~ca0YZ%ldz+;!GpT&29nGbJQfXoLHOxXCPmW07S(5uCF8yyZwr0HR@WT(+Ve20I>&U!1O$i7oYsN zUDOmPZ-xOUIO<+s~M9@H1J+OjjKMH{2yqb(K*osy1)w;6PfUSTp@ZmxvhB*LIL#_ViogsNUL-IBX-Pa(A2g3xO zu3CumLP#Gs=WT))+`Nj*2{o6m23Y zaayay^g|I{wc5~fQa3c3*GsFFv~8(M{v|AWdVh$H4ag0kWoNAt(l2h~!c`p{S&`&T zSdIc=)@_^rmRi&_ns9u-1JXNugF4E+HPsO3DZ3#ET8t47cBx^8%2t5El+LVjd^KmA z^{N z2FEN!64lJ>OG{n#Tznn!-vtmbjvvp}?eOs8nQO{JLJ-VGp^X!eeZwWm&Kt>4@-wQ+ zALZbbMM2W!%MB=$(cwRLR$H#R!c@D#GmkNO+uS;Ns)|^};Ur zyc{e})pd;O4;g@yf%77bkY>WTCUqa2JYbI(cy;N8U}8jg*BinhjDEoMUgrjVNZ=o1 zD;^8yvxhU`kcg-Fw{e>CqVos7xUT%^5DwDLG1P1C7+$M3cyolDwmRy_{Dny}Q^c+C zY)B#o4BL((*dE>?0T9sAzjfi0rUlWW;GHf5$1@Cekq>8R%nHcEBhyd)a?zxOgpk*D z`BJdQ4?vH-5}`x`dCR8R1Tt>O#*zQS!e01x9c2uef8F$39IO242Qw~==oU&fpDxw8 zCQM6k*t@ml5T@4zq3R$|v=lzq2!s<>gK1`O9L%BdTn{R=bifaIVo1KH zWeq;e%K|=yMwMv2X78sWsU~WOT)nd`L6n6%#@vh(HSGl%H?}}3d?!3UX-g>E49n9Y ztmTes;Q3hYZGQF2!IJO7Yo-^3Zl;gX_2`JIsZg)aRqnK`F zSv*&^_fax-5`s;1Sp^(+;T)}|z0QbT`V&EfF54?9jBba5>9E2vb5l`mEG}shEO9oYvQi#h%I0lCGPKrkGCc3$e*VqAsmW9h;3h6#9tK7+0y+ho zc0upd;_rk&!HXh3HhRy&m!O7?>Mx(9L-mrxD7buxuj>8<#UaTOmlks?A7 zg~FrD&{SwX3C&MIn&u@jst{W1dOW7IZB|?uZH(UwHGGiAX11phO3>CN(238`$;ACR z9O9LkjE0-WLk02xnIGWr-6u}M)rlR=ffZGofFnkr%sfC+oQU^sZj)hlcNl#f+J7|@VZ!B z|J37U7u&Ti37N5AX-F}XU8cQI)K_ck?|V#lw+YmQPuXcoN1YM0X&_9yYr9ygnGT6& z#+SL&QXV9^rR84KkI}-gY{kKMyrPb!|_ze+%d^b^($IXYc@CjXNhm8)_aD>g1JNszle=usZaJZ4rHRb3>?c zHq?FmbS^csj)6l%yvziR!~q3~0Cr&fIMf;t=ZBT4mAl7T!lbDMOKHyA&MqXDgfIVj=iCH=KNhd5P0d=-Vc0wPpc7z1GtGlD@a0N zn)a3x`v1I*1N$8w_NyC?uMTaq`sqMO!Y96X4*Y(%?J@ewIRidP2mQF9CAr2nP}^3& z1`!1M_pZmHbdFt6C)e5h|C$pNfZ!g{Xub~)xFqeR7gX}`D8~%0OFe%J@3_5hJYa6w zI9-&Zyb}fx_{s5;b8UybXE5i2duM8fk!3Mehtg(Z+pM&vv&AM0Xb#WzAx9$3V z+B1+P_8Nair3b#mQv;ST7J9d0DP~Her zraxC0{!tAxpy(GvT=j~G?}o%a`4;=!=hlVj zc&Y}b_$TIKM$6harH;LpNCMLEQWOyPO+on&WYn993m&K}@K`T9PY>g!L65_ni0`j>k=$D6@|R7aExc z?zdCMjgoyL`Ic)Wn9&lYP-s$hdrf8JStk4WFDLQ#i4q5uWIpu2SPAc zQE8jpKP}9&NSZ!@kjc4|mdx(*FvSbdF;B$-u~=Uk?%4ZA0b&0!vzU)7v{xhC3}Xp^ zB)ybaVpc7@%NBg}S78XD_h9DPcWmCvT9BL>%)j!U)!&=k?a0;Tj>J`U*8=- zx3yK`wza>vhOkHOsrly!mNs`Cll)Nz9+$8w88R%;=wj#+QXwdW~k3s*U!h^z8=trvX_7|>d% z4&Oy~K9$U{yWQT9ap$rED*oew)jvmp3;i*of4yvJFE-|$ATuECe+s$c{z?S7UYICX zWc~Wzuw|g~YWp)i!eqzyPfZzH$F@JRSC?>reGV_Vym30$HJsizJwTN2>O(0Se-7)o z`Fz@U6XAeO6CAMFKjqnoJp#II)M+emd2VK*I!exGBVcCi(TR)L8O{ad@&q*NEKnD? z@`pvxZKF?n#8X1qDp018slq>R5lKPob;}^f%YSct9>P4tJv4$QEcM(g_Llw%{-^j7 zz)|*Z0LSdfvRVoB7e?+z(L0F3Zg$TRRk`BSh0UpRIe}g|Ptb9-mX(Y?e$LTm=Xaqr z29`ZSb(JpXf#(`Ts$tUf>Gvlo!yJ1TAHcFqc@@C`LE|rB^*0O8|KLUpe`dk2Ey;Qr z#>mN7amn*2!$eVp#xKB2LrS^hZs_D(N2?Z_{lL8hjXF5#V|b3_^vZ@OogSdeSq(XM zRZ`g`)apb$S}j=9Z=Z%Ce5j`LgpW;mwvzjqTRJ22qLD{PXRTQL^&h1B_qT$p!f>)$ zx8uw)4{FzD&#dxfoNkqFAO6hb?UzxxkJk3VDdV#rRwVkn5&rehP&k(Po(Xrqvm2GM z$ShpL)_Jf`etbDw0M1aANS2=2Hs)R&PZkU>beE#m?B?S1#eR(0&o!cvR<^f~P5fjf zjykZrQQrNoMeg1@DYR=&glfvZO9phLEHY!NAVNsfgl5ev`X~DcSB}EYzVANz5&@lp zB&Qf(Hnvz;h z_*+D4(RYbtgTP*uiy1p5g_hvu0wA9i4Xrpifi4$es1*eVoajqj$sFv0dh|SL)6i}=D*#n zkr%}sbLO{M9?ZyVc zC(yA56ArS>K1dpL6(v_aS~cpJ`k&*^CCQxv3> z+(oX&nQui|(#sA)Uxwof+6`%7TK-76n)MHu9JD$(BOSVl)wf@NuLZ~`;oDKBA6lit zOMc-*o@|?h{a^uH`|v>lheS{&Oipy;l^qc$1$_tpiSHZ8`24*Dzgs%S6x#EDnb0vm zftS05aJrpg_fQ;(_qrA{k0)Dc9hDd(?pwet+U#3$Eth(XHz~8w_s1kSp&h!d;t(`q zIiJL)bu_ppb9*=}vb+9k-}5Z73C=J>K>sUbb^JqI;Cso_uTOz`+(mD?2+f@?XYfChoSF?5NnMG4(w+NkQr_%Qet~b4!W~m z;1D;&BSYI~6tC`~qF((#Qut6bDlGlC zV=yfdk44;zTe?;hIX?K3Hvxf=%wLg|%>#gZ6>|@ayuPH~Kfp(ZPG;91FdfyE0u=ob+h~P4H1)h=9`pMG;P^C6Pm4jv{4ei zl|R^_NqiAb5}>P1X@)UHxGAFv?hkS9Rf^|ad2D5G_E#5!H^7qBYPezb=L}WwT%68> z)jxM|rTI|vEe_@+hA=j$yxhB^{1TT6p}SSM@xetj0$8-kukdVNN8wmr~bU z`2}!K20WnC1C+ukgsFM&EbhEB{vKwQExr^;hvRxE0yuK9rA2TFEGBf5M?*|x$j-8K zStSzm2ha&)u;Xn*tMFCSxj;=S;zLk~FH6rx%8*qe_^4nUg6sVjnmf3>jUq>}DPs~G z;%3OJFb>W{chxbj7EwUuyVrMBj_}!=E$9Yg1FujTPf{q*y+Yc*dECH`7pcnZ^?G z%E+z$8&}=zkf7lBQ#*{x16`&GS#Yl?$Ot!@V7`E{RC=B=Ta}ih0@-QkpmiyL+7qc5!AO&q;lCicUJ=)V6iMS zr9m4-j>cA_vD&1=l?A;$r*m~|P>zgFuZN3^PX0nFFqD3*@KPWjI%PU!mS_oYyN?|$ zbuK1%P6GZ}6;_-xDlWfayi7cRM;tAA(5dj9KI9VBgmdVJ&%4Fq$%-S4c>`1|j?h+h zsoYjVyT9ZEFdh~&`G=e83!6Z%4{yKPXD=k$TW?7&aaSo5T!6z*+MBat8A-*eUEI3^3#67v z=r_I2U6C!fgc+S%BF592=PA`tp~i6XqGr6sT(#`zJYSb1u)qXIsT6bC(#UbT>@r&Q+RT0$9% z`me73ciFSGWPUBgrJ*6QisZKr{o7@?Pku8YzLON~VZ-X^=D^!ugRV6pp{ke_rD?$N zZ*uqNZ*3FIxP^7N(pq)t(*a5Fc_A~ANmEmVK6R|SZA9X+%$1CJG%6)GhNPy|{M&z# zZ4Y4M(&&A2?a>Wbvs(dTm9>VBnYh_>ML1!~BF=V^@jsI3UBs$|f|Ch5?*L%4tNOMv zoePw*Df(VRY`jf8k-cQ|(aoFu{>{ib(RDNaD*1-k_&U%cQBjlAoA)v;8 zm!XPF&u9HqRo9?8%dW#tM#L!R#6{5iQjmLp*C#aj1F>{j4R7sz7IEaB)5fG5r@|iEbnRDE=27^D-rq0U#UEX>4Tx04R}tkv&MmKp2MKww8)i1nnT=5U@H~5ET(8twIqhgj%6h2a`+xph-iL z;^HW{799LptU9+0Yt2!cN#PL58BE>hxmNufoIcO3Wd-uJ%TeFymKWu}@PV}Pnz zMk)~(GTBuj^ok&QY0h9sVx~SPib;5muY36Tei!3e-gSSDZY5_jz$XyTGTpFUyKw>po`EZ^<*(F%=}*#Y zEiHNk^lSqc*DX!n11@)f{wG~BBu5I+^5^rw`x$*x7U;VLy4KvjHP3PS0Hmo`$s6F{ z5Ev;?_PWQrJKOvAZ%wm*Ke*j;!%@-Nd;kCd24YJ`L;(K){{a7>y{D4^000SaNLh0L z01ejw01ejxLMWSf00007bV*G`2jm435;`y9D|c=H00HVrL_t(I%Z*dNYg17eJ?FkA zZ5&FWNfw=*{ZV~4#i5QJ%zX|P3ffwsilE>mF4BS&iknX2)4Ah_T}ii zue)(RQsOU`df~%7_$;VLPv=YdPVx?Y74=T?Km5rZatF>au@g$lrbZQWeDF7V; z(sNMbz8B#o-{@tPJ8~ZiM*~ma?3v){Ru=#iC@Q5*Y!uh(_W&FRu`QXQ1+mDb*APcR zI3Ni>#7y!Bo#<0POctR;*ioc>YnZd=`jUu`#kZTk`}$#9mk53taF}~$rS%BF=l`%e z?Hj!e0equRvD?mo{1yK|0dqDxcxT@jf#+U1tdV?A-wsS^rq{|wF9l^idr)&=N;83{ z@AeN}G4MR>Qr6HNLy!w49}2Jszgi^_!FKu+4G`fGa>p0g(VX3f9?` c*U32l1AOqvxs5>?hyVZp07*qoM6N<$f+c3kQ~&?~ literal 0 HcmV?d00001 diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 22c10f5..2ede26d 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -2,6 +2,7 @@ // GPLv3 #include "ChatDataStore.h" +#include "addressbook.h" ChatDataStore* ChatDataStore::getInstance() { @@ -48,15 +49,15 @@ std::map ChatDataStore::getAllRawChatItems() return this->data; } -std::map ChatDataStore::getAllContactRequests() +std::map ChatDataStore::getAllNewContactRequests() { std::map filteredItems; for(auto &c: this->data) { if ( (c.second.isOutgoing() == false) && - (c.second.getType() == "cont") && - (c.second.getMemo().startsWith("{")) + (c.second.getType() == "cont") + ) { filteredItems[c.first] = c.second; @@ -65,6 +66,23 @@ std::map ChatDataStore::getAllContactRequests() return filteredItems; } +std::map ChatDataStore::getAllOldContactRequests() +{ + std::map filteredItems; + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + for(auto &c: this->data) + { + if ( + (c.second.isOutgoing() == false) && + (c.second.getType() == "cont") && + (p.getPartnerAddress() == c.second.getRequestZaddr()) + ) + { + filteredItems[c.first] = c.second; + } + } + return filteredItems; +} std::map ChatDataStore::getAllMemos() { diff --git a/src/DataStore/ChatDataStore.h b/src/DataStore/ChatDataStore.h index 444c704..7fb0998 100644 --- a/src/DataStore/ChatDataStore.h +++ b/src/DataStore/ChatDataStore.h @@ -22,7 +22,8 @@ class ChatDataStore void setData(QString key, ChatItem value); ChatItem getData(QString key); std::map getAllRawChatItems(); - std::map getAllContactRequests(); + std::map getAllNewContactRequests(); + std::map getAllOldContactRequests(); std::map getAllMemos(); QString dump(); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 1e72714..b669302 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -10,7 +10,6 @@ #include "addressbook.h" #include "ui_memodialog.h" #include "ui_contactrequest.h" -#include "addressbook.h" #include #include #include "DataStore/DataStore.h" @@ -97,7 +96,7 @@ void MainWindow::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); { - for (auto &c : DataStore::getChatDataStore()->getAllContactRequests()) + for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) { QStandardItem* Items = new QStandardItem(c.second.getAddress()); @@ -109,18 +108,17 @@ void MainWindow::renderContactRequest(){ QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { - for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){//this->chatItems){ + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ QModelIndex index = requestContact.requestContact->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); - if (c.second.isOutgoing() == false) { - if (label_contact == c.second.getAddress()) { - if(c.second.getMemo().startsWith("{")){ + if ((c.second.isOutgoing() == false) && (label_contact == c.second.getAddress()) && (c.second.getType() == "cont")) + + { - }else{ QStandardItem* Items = new QStandardItem(c.second.getMemo()); - contactMemo->appendRow(Items); + contactMemo->appendRow(Items); requestContact.requestMemo->setModel(contactMemo); requestContact.requestMemo->show(); @@ -128,11 +126,11 @@ void MainWindow::renderContactRequest(){ requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestCID->setText(c.second.getCid()); requestContact.requestMyAddr->setText(c.second.getAddress()); - } + }else{} } - } - } + + }); QObject::connect(requestContact.pushButton, &QPushButton::clicked, [&] () { @@ -173,7 +171,6 @@ void MainWindow::renderContactRequest(){ QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); }); - dialog.exec(); } @@ -425,7 +422,8 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { } void::MainWindow::addContact() { - + + Ui_Dialog request; QDialog dialog(this); request.setupUi(&dialog); @@ -434,24 +432,31 @@ void::MainWindow::addContact() { bool sapling = true; rpc->createNewZaddr(sapling, [=] (json reply) { QString myAddr = QString::fromStdString(reply.get()[0]); - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + request.myzaddr->setText(myAddr); ui->listReceiveAddresses->insertItem(0, myAddr); ui->listReceiveAddresses->setCurrentIndex(0); - qDebug() << "new generated myAddr" << myAddr; - request.myzaddr->setText(myAddr); + }); + + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); request.cid->setText(cid); - }); + + QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { + QString cid = request.cid->text(); auto addr = request.zaddr->text().trimmed(); QString newLabel = request.labelRequest->text().trimmed(); auto myAddr = request.myzaddr->text().trimmed(); + // ChatModel->addSendRequest(myAddr, cid, addr); + + + QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); if (addr.isEmpty() || newLabel.isEmpty()) @@ -490,15 +495,24 @@ void::MainWindow::addContact() { return; }); - dialog.exec(); } + + // Create a Tx for a contact Request Tx MainWindow::createTxForSafeContactRequest() { - Tx tx; + Ui_Dialog request; + QDialog dialog(this); + request.setupUi(&dialog); + Settings::saveRestore(&dialog); + +Tx tx; + +{ + // For each addr/amt in the Chat tab { @@ -510,18 +524,14 @@ Tx MainWindow::createTxForSafeContactRequest() { amt = CAmount::fromDecimalString("0"); totalAmt = totalAmt + amt; - - for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - if (ui->contactNameMemo->text().trimmed() == c.getName()) { - - - QString cid = c.getCid(); - QString myAddr = c.getMyAddress(); + + QString cid = request.cid->text(); + QString myAddr = request.myzaddr->text().trimmed(); QString type = "cont"; - QString addr = c.getPartnerAddress(); + QString addr = request.zaddr->text().trimmed(); QString hmemo= createHeaderMemo(type,cid,myAddr); - QString memo = ui->memoTxtChat->toPlainText().trimmed(); + QString memo = request.memorequest->toPlainText().trimmed(); tx.toAddrs.push_back(ToFields{addr, amt, memo}); tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); @@ -532,19 +542,16 @@ Tx MainWindow::createTxForSafeContactRequest() { } tx.fee = Settings::getMinerFee(); - +} return tx; qDebug() << "RequestTx created"; - - } - } void MainWindow::ContactRequest() { - if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { + /* if (request.labelRequest->text().trimmed().isEmpty() || request.memorequest->toPlainText().trimmed().isEmpty()) { // auto addr = ""; // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { @@ -554,7 +561,7 @@ void MainWindow::ContactRequest() { msg.exec(); return; - } + }*/ Tx tx = createTxForSafeContactRequest(); @@ -632,7 +639,7 @@ void MainWindow::ContactRequest() { QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); } ); - + } diff --git a/src/chatmodel.h b/src/chatmodel.h index bf3e255..a96f3bd 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -19,6 +19,9 @@ #include "Chat/Helper/ChatDelegator.h" #include "Chat/Helper/ChatIDGenerator.h" +namespace Ui { + class MainWindow; +} class ChatModel { private: @@ -28,6 +31,7 @@ class ChatModel MainWindow* main; std::map cidMap; std::map requestZaddrMap; + std::map> sendrequestMap; public: ChatModel() {}; @@ -44,6 +48,7 @@ class ChatModel void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); void addrequestZaddr(QString tx, QString requestZaddr); + void addSendRequest(int i, QString myAddr, QString cid, QString addr ); QString getCidByTx(QString tx); QString getrequestZaddrByTx(QString tx); void killCidCache(); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index d2ae8ef..9ce3c22 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -14,7 +14,7 @@ Send a contact request - + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> @@ -28,7 +28,7 @@ - + @@ -185,6 +185,9 @@ + + + @@ -192,7 +195,7 @@ - + @@ -231,6 +234,13 @@ + + + + Send Contact + + + @@ -255,7 +265,7 @@ sendRequestButton clicked() Dialog - accept() + update() 536 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index de034ac..b3868d4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1011,52 +1011,45 @@ void MainWindow::setupchatTab() { auto theme = Settings::getInstance()->get_theme_name(); if (theme == "dark" || theme == "midnight") { - QPixmap send(":/icons/res/send-new-white.png"); + QPixmap send(":/icons/res/send-white.png"); QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); - QPixmap notification(":/icons/res/notification.png"); + QPixmap notification(":/icons/res/requestWhite.png"); QIcon notificationIcon(notification); ui->pushContact->setIcon(notificationIcon); - QPixmap addContact(":/icons/res/add_contact.png"); + QPixmap addContact(":/icons/res/addContactWhite.png"); QIcon addContactIcon(addContact); ui->safeContactRequest->setIcon(addContactIcon); - QPixmap newAddr(":/icons/res/add_contact.png"); + QPixmap newAddr(":/icons/res/getAddrWhite.png"); QIcon addnewAddrIcon(newAddr); ui->givemeZaddr->setIcon(addnewAddrIcon); - QPixmap sendContact(":/icons/res/upload.png"); - QIcon addSendContactIcon(sendContact); - ui->sendContact->setIcon(addSendContactIcon); }else{ - QPixmap pixmap(":/icons/res/send-new.svg"); - QIcon sendIcon(pixmap); + + QPixmap send(":/icons/res/sendBlack.png"); + QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); - QPixmap notification(":/icons/res/notification.svg"); + QPixmap notification(":/icons/res/requestBlack.png"); QIcon notificationIcon(notification); ui->pushContact->setIcon(notificationIcon); - QPixmap addContact(":/icons/res/add_contact.svg"); + QPixmap addContact(":/icons/res/addContactBlack.png"); QIcon addContactIcon(addContact); - ui->safeContactRequest->setIcon(addContact); + ui->safeContactRequest->setIcon(addContactIcon); - QPixmap newAddr(":/icons/res/add_contact.svg"); + QPixmap newAddr(":/icons/res/getAddrBlack.png"); QIcon addnewAddrIcon(newAddr); ui->givemeZaddr->setIcon(addnewAddrIcon); - - QPixmap sendContact(":/icons/res/upload.svg"); - QIcon addSendContactIcon(sendContact); - ui->sendContact->setIcon(addSendContactIcon); } QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); - QObject::connect(ui->sendContact, &QPushButton::clicked, this, &MainWindow::ContactRequest); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); diff --git a/src/mainwindow.h b/src/mainwindow.h index ff4b76a..ea0a3a4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -62,12 +62,7 @@ public: void updateLabels(); void updateTAddrCombo(bool checked); - // void renderContactRequest(); - // void setChatItem(ChatItem* item); - //void ChatItem* getChatItem(); - - // Disable recurring on mainnet void disableRecurring(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 3e82d7a..82b4260 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1409,9 +1409,21 @@ 81 + + false + font: 11pt "Noto Color Emoji"; + + QTextEdit::AutoNone + + + QTextEdit::FixedColumnWidth + + + 80 + @@ -1435,7 +1447,7 @@ - 1170 + 1160 560 91 81 @@ -1455,12 +1467,12 @@ - :/icons/res/send-new-white.png + :/icons/res/sendBlack.png - 41 + 50 49 @@ -1533,18 +1545,21 @@ 0 + + Add a new contact + - :/icons/res/add_contact.png + :/icons/res/addContactBlack.png - 43 - 49 + 50 + 45 @@ -1554,44 +1569,9 @@ - 10 - 30 - 41 - 41 - - - - - 100 - 0 - - - - false - - - - - - - :/icons/res/notification.png:/icons/res/notification.png - - - - 33 - 35 - - - - true - - - - - - 270 - 510 - 51 + 50 + 20 + 61 51 @@ -1601,18 +1581,23 @@ 0 + + Incoming contact request + + + false + - - :/icons/res/add_contact.png - + + :/icons/res/requestBlack.png:/icons/res/requestBlack.png - 43 - 49 + 50 + 45 @@ -1622,23 +1607,26 @@ - 60 - 30 - 111 - 41 + 210 + 20 + 61 + 51 + + Get a new Address + - New Addr + - :/icons/res/add_contact.png:/icons/res/add_contact.png + :/icons/res/getAddrBlack.png:/icons/res/getAddrBlack.png - 33 - 35 + 50 + 45 @@ -1648,8 +1636,8 @@ - 40 - 20 + 90 + 10 21 16 @@ -2042,7 +2030,7 @@ AddressCombo QComboBox -
addresscombo.h
+
addresscombo.h
QRCodeLabel From da65008a880a1c41e89e37930705004d27b52972 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 20 May 2020 20:58:23 +0200 Subject: [PATCH 114/253] change text with theme --- src/mainwindow.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b3868d4..e895947 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1027,6 +1027,8 @@ void MainWindow::setupchatTab() { QIcon addnewAddrIcon(newAddr); ui->givemeZaddr->setIcon(addnewAddrIcon); + ui->memoTxtChat->setTextColor("White"); + }else{ QPixmap send(":/icons/res/sendBlack.png"); @@ -1044,6 +1046,8 @@ void MainWindow::setupchatTab() { QPixmap newAddr(":/icons/res/getAddrBlack.png"); QIcon addnewAddrIcon(newAddr); ui->givemeZaddr->setIcon(addnewAddrIcon); + + ui->memoTxtChat->setTextColor("Black"); } @@ -1109,11 +1113,6 @@ void ChatMemoEdit::setMaxLen(int len) { updateDisplay(); } -void ChatMemoEdit::setSendChatButton(QPushButton* button) { - this->sendChatButton = button; -} - - void MainWindow::updateChat() { rpc->refreshChat(ui->listChat); From 69799fb81260fd9fd2f911f5daeb2c137f32f307 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 20 May 2020 23:53:39 +0200 Subject: [PATCH 115/253] fix selection on chattab --- src/DataStore/ChatDataStore.cpp | 7 +- src/Model/ChatItem.cpp | 2 +- src/chatmodel.cpp | 106 +++--- src/contactrequest.ui | 18 +- src/controller.cpp | 19 +- src/mainwindow.h | 1 + src/requestContactDialog.ui | 627 +++++++++++++++----------------- 7 files changed, 383 insertions(+), 397 deletions(-) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 2ede26d..1313103 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -52,11 +52,14 @@ std::map ChatDataStore::getAllRawChatItems() std::map ChatDataStore::getAllNewContactRequests() { std::map filteredItems; + for(auto &c: this->data) { if ( (c.second.isOutgoing() == false) && - (c.second.getType() == "cont") + (c.second.getType() == "Cont") && + (c.second.getContact() == "") + ) { @@ -74,7 +77,7 @@ std::map ChatDataStore::getAllOldContactRequests() { if ( (c.second.isOutgoing() == false) && - (c.second.getType() == "cont") && + (c.second.getType() == "Cont") && (p.getPartnerAddress() == c.second.getRequestZaddr()) ) { diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index dd43785..540c7ba 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -144,7 +144,7 @@ QString ChatItem::toChatLine() } - QString line = QString("") + myDateTime.toString("dd.MM.yyyy hh:mm"); + QString line = QString("") + myDateTime.toString("dd.MM.yyyy hh:mm"); line += QString(lock) + QString(""); line += QString("

") + _memo.toHtmlEscaped() + QString("

"); return line; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b669302..450d903 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -26,20 +26,6 @@ ChatModel::ChatModel(std::vector chatItems) this->setItems(chatItems); } -/*QString ChatModel::generateChatItemID(ChatItem item) -{ - QString key = QString::number(item.getTimestamp()) + QString("-"); - key += QString(QCryptographicHash::hash( - QString( - QString::number(item.getTimestamp()) + - item.getAddress() + - item.getContact() + - item.getMemo() - ).toUtf8() - ,QCryptographicHash::Md5).toHex()); - return key; -}*/ - std::map ChatModel::getItems() { return this->chatItems; @@ -81,10 +67,12 @@ void ChatModel::showMessages() { for(auto &c : this->chatItems) { - qDebug() << c.second.toChatLine(); + // qDebug() << c.second.toChatLine(); } } + + void MainWindow::renderContactRequest(){ @@ -95,8 +83,11 @@ void MainWindow::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); - { - for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) + // auto labels = AddressBook::getInstance()->getAllAddressLabels(); + for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) + + + // if (labels.adress() != c.second.getRequestZaddr()) { QStandardItem* Items = new QStandardItem(c.second.getAddress()); @@ -104,7 +95,17 @@ void MainWindow::renderContactRequest(){ requestContact.requestContact->setModel(contactRequest); requestContact.requestContact->show(); } - } + QStandardItemModel* contactRequestOld = new QStandardItemModel(); + + for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) + { + + QStandardItem* Items = new QStandardItem(c.second.getAddress()); + contactRequestOld->appendRow(Items); + requestContact.requestContactOld->setModel(contactRequestOld); + requestContact.requestContactOld->show(); + } + //} QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { @@ -113,7 +114,7 @@ void MainWindow::renderContactRequest(){ QString label_contact = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); - if ((c.second.isOutgoing() == false) && (label_contact == c.second.getAddress()) && (c.second.getType() == "cont")) + if ((c.second.isOutgoing() == false) && (label_contact == c.second.getAddress()) && (c.second.getType() != "Cont")) { @@ -283,7 +284,8 @@ Tx MainWindow::createTxFromChatPage() { qDebug() << "pushback chattx"; - } } + } + } tx.fee = Settings::getMinerFee(); @@ -440,16 +442,14 @@ void::MainWindow::addContact() { QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); request.cid->setText(cid); - - - - - + QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { - + + QString cid = request.cid->text(); auto addr = request.zaddr->text().trimmed(); + QString getrequest = addr; QString newLabel = request.labelRequest->text().trimmed(); auto myAddr = request.myzaddr->text().trimmed(); @@ -494,27 +494,28 @@ void::MainWindow::addContact() { ); return; + }); + + + // QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); dialog.exec(); + rpc->refreshContacts( + ui->listContactWidget + + ); } // Create a Tx for a contact Request Tx MainWindow::createTxForSafeContactRequest() { - - Ui_Dialog request; - QDialog dialog(this); - request.setupUi(&dialog); - Settings::saveRestore(&dialog); - + Tx tx; { - - // For each addr/amt in the Chat tab { CAmount totalAmt; QString amtStr = "0"; @@ -525,29 +526,40 @@ Tx tx; totalAmt = totalAmt + amt; - QString cid = request.cid->text(); - QString myAddr = request.myzaddr->text().trimmed(); - QString type = "cont"; - QString addr = request.zaddr->text().trimmed(); + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + + if (ui->contactNameMemo->text().trimmed() == c.getName()) { - QString hmemo= createHeaderMemo(type,cid,myAddr); - QString memo = request.memorequest->toPlainText().trimmed(); + QString cid = c.getCid(); + QString myAddr = c.getMyAddress(); + QString type = "Cont"; + QString addr = c.getPartnerAddress(); + + + QString hmemo= createHeaderMemo(type,cid,myAddr); + QString memo = ui->memoTxtChat->toPlainText().trimmed(); + - tx.toAddrs.push_back(ToFields{addr, amt, memo}); - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); - + // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat + + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + tx.toAddrs.push_back(ToFields{addr, amt, memo}); - qDebug() << "pushback chattx"; - - } + + + qDebug() << "pushback chattx"; + tx.fee = Settings::getMinerFee(); + + } } return tx; qDebug() << "RequestTx created"; } +} void MainWindow::ContactRequest() { @@ -671,4 +683,4 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { } return ""; -} \ No newline at end of file +} diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 9ce3c22..e099111 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -6,15 +6,15 @@ 0 0 - 780 - 416 + 777 + 427
Send a contact request - + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> @@ -185,9 +185,6 @@ - - - @@ -234,13 +231,6 @@ - - - - Send Contact - - -
@@ -265,7 +255,7 @@ sendRequestButton clicked() Dialog - update() + accept() 536 diff --git a/src/controller.cpp b/src/controller.cpp index 534fffe..db895a1 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -102,6 +102,10 @@ void Controller::setConnection(Connection* c) DataStore::getSietchDataStore()->setData("Sietch" + QString(i), zdust.toUtf8()); }); } + refreshContacts( + ui->listContactWidget + + ); } // Build the RPC JSON Parameters for this tx @@ -797,6 +801,7 @@ void Controller::refreshBalances() CAmount balAvailable = balT + balVerified; model->setAvailableBalance(balAvailable); updateUIBalances(); + }); // 2. Get the UTXOs @@ -881,8 +886,8 @@ void Controller::refreshTransactions() { confirmations, true ); - qDebug()<<"Memo : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); @@ -978,8 +983,8 @@ void Controller::refreshTransactions() { confirmations, false ); - qDebug()<< "Position : " << position; - qDebug()<<"Confirmation :" << confirmations; + // qDebug()<< "Position : " << position; + // qDebug()<<"Confirmation :" << confirmations; DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } @@ -1005,10 +1010,10 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); chat->renderChatBox(ui, ui->listChat); - refreshContacts( - ui->listContactWidget + // refreshContacts( + // ui->listContactWidget - ); + // ); }); } diff --git a/src/mainwindow.h b/src/mainwindow.h index ea0a3a4..4419fcb 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -50,6 +50,7 @@ public: QString doSendTxValidations(Tx tx); QString doSendChatTxValidations(Tx tx); QString doSendRequestTxValidations(Tx tx); + QString getCid(); void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index b862cda..d2a3b68 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -6,350 +6,325 @@ 0 0 - 1011 - 503 + 1025 + 562
Incoming contact request - - - - 9 - 9 - 256 - 461 - - - - true - - - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - false - - - QAbstractItemView::SingleSelection - - - - - - 263 - 9 - 741 - 271 - - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoEditTriggers - - - QListView::Adjust - - - 0 - - - false - - - true - - - - - - 276 - 296 - 101 - 17 - - - - Request from : - - - - - - 393 - 296 - 601 - 25 - - - - - - - 276 - 327 - 30 - 17 - - - - Cid : - - - - - - 393 - 327 - 601 - 25 - - - - - - - 276 - 358 - 71 - 17 - - - - My Zaddr : - - - - - - 393 - 358 - 601 - 25 - - - - - - - 276 - 389 - 68 - 17 - - - - Nickname - - - - - - 393 - 389 - 221 - 25 - - - - - - - 276 - 420 - 228 - 17 - - - - <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> - - - - - - 510 - 420 - 106 - 25 - - - - - Stag - - - - :/icons/res/Stag.png - - + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + - - - Elsa - - - - :/icons/res/Elsa.png - - + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + - - - Denio - - - - :/icons/res/Denio.png - - + + + + true + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + QAbstractItemView::SingleSelection + + - - - Duke - - - - :/icons/res/Duke.png - - + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + QListView::Adjust + + + 0 + + + false + + + true + + - - - Yoda - - - - :/icons/res/Yoda.png - - + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + - - - Berg - - - - :/icons/res/Berg.png - - + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + - - - Sharpee - - - - :/icons/res/Sharpee.png - - + + + + true + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + QAbstractItemView::SingleSelection + + - - - Garfield - - - - :/icons/res/Garfield.png - - + + + + Request from : + + - - - Snoopy - - - - :/icons/res/Snoopy.png - - + + - - - Popey - - - - :/icons/res/Popey.png - - + + + + Cid : + + - - - Pinguin - - - - :/icons/res/Pinguin.png - - + + - - - Mickey - - - - :/icons/res/Mickey.png - - + + + + My Zaddr : + + - - - SDLogo - - - - :/icons/res/sdlogo2.png - - + + - - - - - 300 - 470 - 80 - 25 - - - - - 100 - 0 - - - - Cancel - - - false - - - - - - 400 - 470 - 101 - 25 - - - - Add Contact - - + + + + Nickname + + + + + + + + + + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + + + + + + + + Stag + + + + :/icons/res/Stag.png + + + + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Denio + + + + :/icons/res/Denio.png + + + + + + Duke + + + + :/icons/res/Duke.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + + + + Berg + + + + :/icons/res/Berg.png + + + + + + Sharpee + + + + :/icons/res/Sharpee.png + + + + + + Garfield + + + + :/icons/res/Garfield.png + + + + + + Snoopy + + + + :/icons/res/Snoopy.png + + + + + + Popey + + + + :/icons/res/Popey.png + + + + + + Pinguin + + + + :/icons/res/Pinguin.png + + + + + + Mickey + + + + :/icons/res/Mickey.png + + + + + + SDLogo + + + + :/icons/res/sdlogo2.png + + + + + + + + + + 100 + 0 + + + + Cancel + + + false + + + + + + + Add this new Contact + + + +
- + + + cancel + clicked() + requestDialog + reject() + + + 339 + 482 + + + 505 + 251 + + + + From ca090d62ddd91f2edf27477bcda3f93d947ea2ec Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 00:08:32 +0200 Subject: [PATCH 116/253] show oldrequest information --- src/chatmodel.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 450d903..ae123a9 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -83,11 +83,8 @@ void MainWindow::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); - // auto labels = AddressBook::getInstance()->getAllAddressLabels(); for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) - - // if (labels.adress() != c.second.getRequestZaddr()) { QStandardItem* Items = new QStandardItem(c.second.getAddress()); @@ -95,17 +92,20 @@ void MainWindow::renderContactRequest(){ requestContact.requestContact->setModel(contactRequest); requestContact.requestContact->show(); } - QStandardItemModel* contactRequestOld = new QStandardItemModel(); + QStandardItemModel* contactRequestOld = new QStandardItemModel(); + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) { - + if (p.getPartnerAddress() == c.second.getRequestZaddr()) + { QStandardItem* Items = new QStandardItem(c.second.getAddress()); contactRequestOld->appendRow(Items); requestContact.requestContactOld->setModel(contactRequestOld); requestContact.requestContactOld->show(); + }else{} } - //} + QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { @@ -132,6 +132,33 @@ void MainWindow::renderContactRequest(){ + }); + + QObject::connect(requestContact.requestContactOld, &QTableView::clicked, [&] () { + + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ + QModelIndex index = requestContact.requestContactOld->currentIndex(); + QString label_contactold = index.data(Qt::DisplayRole).toString(); + QStandardItemModel* contactMemo = new QStandardItemModel(); + + if ((c.second.isOutgoing() == false) && (label_contactold == c.second.getAddress()) && (c.second.getType() != "Cont")) + + { + + QStandardItem* Items = new QStandardItem(c.second.getMemo()); + contactMemo->appendRow(Items); + requestContact.requestMemo->setModel(contactMemo); + requestContact.requestMemo->show(); + + + requestContact.requestZaddr->setText(c.second.getRequestZaddr()); + requestContact.requestCID->setText(c.second.getCid()); + requestContact.requestMyAddr->setText(c.second.getAddress()); + }else{} + } + + + }); QObject::connect(requestContact.pushButton, &QPushButton::clicked, [&] () { @@ -174,6 +201,11 @@ void MainWindow::renderContactRequest(){ }); dialog.exec(); + + rpc->refreshContacts( + ui->listContactWidget + + ); } void ChatModel::addCid(QString tx, QString cid) From 5ad5d07c1c883ca793ba319e3f203209bd3e8604 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Thu, 21 May 2020 12:12:32 +0200 Subject: [PATCH 117/253] update// created request objects to store inportant information --- silentdragon-lite.pro | 1 + src/Model/ContactRequest.cpp | 67 +++++++++++++++ src/Model/ContactRequest.h | 33 ++++++++ src/chatmodel.cpp | 156 ++++++++++++++--------------------- src/chatmodel.h | 1 + 5 files changed, 164 insertions(+), 94 deletions(-) create mode 100644 src/Model/ContactRequest.cpp create mode 100644 src/Model/ContactRequest.h diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index bb10655..86f38b0 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -79,6 +79,7 @@ SOURCES += \ src/Model/ChatItem.cpp \ src/Model/ContactRequestChatItem.cpp \ src/Model/ContactItem.cpp \ + src/Model/ContactRequest.cpp \ src/Chat/Helper/ChatIDGenerator.cpp \ src/Chat/Chat.cpp \ src/FileSystem/FileSystem.cpp \ diff --git a/src/Model/ContactRequest.cpp b/src/Model/ContactRequest.cpp new file mode 100644 index 0000000..68b4ed3 --- /dev/null +++ b/src/Model/ContactRequest.cpp @@ -0,0 +1,67 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + +#include "ContactRequest.h" + +ContactRequest::ContactRequest() {} + +ContactRequest::ContactRequest(QString sender, QString receiver, QString memo, QString cid) +{ + _senderAddress = sender; + _receiverAddress = receiver; + _memo = memo; + _cid = cid; +} + +QString ContactRequest::getSenderAddress() +{ + return _senderAddress; +} + +QString ContactRequest::getReceiverAddress() +{ + return _receiverAddress; +} + +QString ContactRequest::getMemo() +{ + return _memo; +} + +QString ContactRequest::getCid() +{ + return _cid; +} + +void ContactRequest::setSenderAddress(QString address) +{ + _senderAddress = address; +} + +void ContactRequest::setReceiverAddress(QString address) +{ + _receiverAddress = address; +} + +void ContactRequest::setMemo(QString memo) +{ + _memo = memo; +} + +void ContactRequest::setCid(QString cid) +{ + _cid = cid; +} + +QString ContactRequest::toString() +{ + return "sender: " + _senderAddress + " receiver: " + _receiverAddress + " memo: " + _memo + " cid: " + _cid; +} + +ContactRequest::~ContactRequest() +{ + _senderAddress = ""; + _receiverAddress = ""; + _memo = ""; + _cid = ""; +} \ No newline at end of file diff --git a/src/Model/ContactRequest.h b/src/Model/ContactRequest.h new file mode 100644 index 0000000..5339d5c --- /dev/null +++ b/src/Model/ContactRequest.h @@ -0,0 +1,33 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + +#ifndef CONTACTREQUEST_H +#define CONTACTREQUEST_H + +#include +using json = nlohmann::json; + +class ContactRequest +{ + private: + QString _senderAddress; + QString _receiverAddress; + QString _memo; + QString _cid; + + public: + ContactRequest(); + ContactRequest(QString sender, QString receiver, QString memo, QString cid); + QString getSenderAddress(); + QString getReceiverAddress(); + QString getMemo(); + QString getCid(); + void setSenderAddress(QString address); + void setReceiverAddress(QString contact); + void setMemo(QString memo); + void setCid(QString cid); + QString toString(); + ~ContactRequest(); +}; + +#endif \ No newline at end of file diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index ae123a9..e8f8015 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -16,6 +16,8 @@ using namespace std; +ContactRequest contactRequest = ContactRequest(); + ChatModel::ChatModel(std::map chatItems) { this->chatItems = chatItems; @@ -455,45 +457,38 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { return ""; } -void::MainWindow::addContact() { - - +void::MainWindow::addContact() +{ Ui_Dialog request; QDialog dialog(this); request.setupUi(&dialog); Settings::saveRestore(&dialog); - - bool sapling = true; - rpc->createNewZaddr(sapling, [=] (json reply) { - QString myAddr = QString::fromStdString(reply.get()[0]); - request.myzaddr->setText(myAddr); - ui->listReceiveAddresses->insertItem(0, myAddr); - ui->listReceiveAddresses->setCurrentIndex(0); - qDebug() << "new generated myAddr" << myAddr; - }); + bool sapling = true; + rpc->createNewZaddr(sapling, [=] (json reply) { + QString myAddr = QString::fromStdString(reply.get()[0]); + request.myzaddr->setText(myAddr); + ui->listReceiveAddresses->insertItem(0, myAddr); + ui->listReceiveAddresses->setCurrentIndex(0); + qDebug() << "new generated myAddr" << myAddr; + }); - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); - request.cid->setText(cid); + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + request.cid->setText(cid); - QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { - - - - QString cid = request.cid->text(); - auto addr = request.zaddr->text().trimmed(); - QString getrequest = addr; - QString newLabel = request.labelRequest->text().trimmed(); - auto myAddr = request.myzaddr->text().trimmed(); - - // ChatModel->addSendRequest(myAddr, cid, addr); - - - - QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); - - if (addr.isEmpty() || newLabel.isEmpty()) + QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { + QString cid = request.cid->text(); + QString addr = request.zaddr->text().trimmed(); + QString getrequest = addr; + QString newLabel = request.labelRequest->text().trimmed(); + QString myAddr = request.myzaddr->text().trimmed(); + contactRequest.setSenderAddress(myAddr); + contactRequest.setReceiverAddress(addr); + contactRequest.setMemo(newLabel); + contactRequest.setCid(cid); + QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); + if (addr.isEmpty() || newLabel.isEmpty()) { - QMessageBox::critical( + QMessageBox::critical( this, QObject::tr("Address or Label Error"), QObject::tr("Address or Label cannot be empty"), @@ -505,7 +500,7 @@ void::MainWindow::addContact() { // Test if address is valid. if (!Settings::isValidAddress(addr)) { - QMessageBox::critical( + QMessageBox::critical( this, QObject::tr("Address Format Error"), QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), @@ -517,80 +512,53 @@ void::MainWindow::addContact() { ///////Todo: Test if label allready exist! ////// Success, so show it - AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::information( - this, - QObject::tr("Added Contact"), - QObject::tr("successfully added your new contact").arg(newLabel), - QMessageBox::Ok - ); - return; - - - }); - - - // QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); - - dialog.exec(); - rpc->refreshContacts( - ui->listContactWidget - + AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); + QMessageBox::information( + this, + QObject::tr("Added Contact"), + QObject::tr("successfully added your new contact").arg(newLabel), + QMessageBox::Ok ); + return; + }); + + dialog.exec(); + rpc->refreshContacts(ui->listContactWidget); } // Create a Tx for a contact Request -Tx MainWindow::createTxForSafeContactRequest() { - -Tx tx; - +Tx MainWindow::createTxForSafeContactRequest() { - - { - CAmount totalAmt; - QString amtStr = "0"; - CAmount amt; - - - amt = CAmount::fromDecimalString("0"); - totalAmt = totalAmt + amt; - - - for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - - if (ui->contactNameMemo->text().trimmed() == c.getName()) { - + Tx tx; + CAmount totalAmt; + QString amtStr = "0"; + CAmount amt; + amt = CAmount::fromDecimalString("0"); + totalAmt = totalAmt + amt; + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + { + if (ui->contactNameMemo->text().trimmed() == c.getName()) + { QString cid = c.getCid(); QString myAddr = c.getMyAddress(); QString type = "Cont"; QString addr = c.getPartnerAddress(); - + qDebug() << contactRequest.toString(); + QString hmemo= createHeaderMemo(type,cid,myAddr); + QString memo = ui->memoTxtChat->toPlainText().trimmed(); + // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat - QString hmemo= createHeaderMemo(type,cid,myAddr); - QString memo = ui->memoTxtChat->toPlainText().trimmed(); - - - // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat - - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); - tx.toAddrs.push_back(ToFields{addr, amt, memo}); - - - - qDebug() << "pushback chattx"; - - - tx.fee = Settings::getMinerFee(); - + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + tx.toAddrs.push_back(ToFields{addr, amt, memo}); + qDebug() << "pushback chattx"; + tx.fee = Settings::getMinerFee(); } -} - return tx; - - qDebug() << "RequestTx created"; - -} + } + + return tx; + qDebug() << "RequestTx created"; } void MainWindow::ContactRequest() { diff --git a/src/chatmodel.h b/src/chatmodel.h index a96f3bd..e8bc3e7 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -16,6 +16,7 @@ #include "settings.h" #include "camount.h" #include "Model/ChatItem.h" +#include "Model/ContactRequest.h" #include "Chat/Helper/ChatDelegator.h" #include "Chat/Helper/ChatIDGenerator.h" From c1954633de37fe8972859020a94cb7e0dafb04f4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 16:00:25 +0200 Subject: [PATCH 118/253] merge PR, send request from Contacttab --- src/Model/ContactRequest.cpp | 28 +++++++- src/Model/ContactRequest.h | 8 ++- src/chatmodel.cpp | 122 +++++++++++++++++++++++++++-------- src/contactrequest.ui | 63 ++++++++++++++---- src/mainwindow.h | 2 + 5 files changed, 182 insertions(+), 41 deletions(-) diff --git a/src/Model/ContactRequest.cpp b/src/Model/ContactRequest.cpp index 68b4ed3..9741ba0 100644 --- a/src/Model/ContactRequest.cpp +++ b/src/Model/ContactRequest.cpp @@ -5,12 +5,14 @@ ContactRequest::ContactRequest() {} -ContactRequest::ContactRequest(QString sender, QString receiver, QString memo, QString cid) +ContactRequest::ContactRequest(QString sender, QString receiver, QString memo, QString cid, QString label, QString avatar) { _senderAddress = sender; _receiverAddress = receiver; _memo = memo; _cid = cid; + _label = label; + _avatar = avatar; } QString ContactRequest::getSenderAddress() @@ -33,6 +35,16 @@ QString ContactRequest::getCid() return _cid; } +QString ContactRequest::getLabel() +{ + return _label; +} + +QString ContactRequest::getAvatar() +{ + return _avatar; +} + void ContactRequest::setSenderAddress(QString address) { _senderAddress = address; @@ -53,9 +65,19 @@ void ContactRequest::setCid(QString cid) _cid = cid; } +void ContactRequest::setLabel(QString label) +{ + _label = label; +} + +void ContactRequest::setAvatar(QString avatar) +{ + _avatar = avatar; +} + QString ContactRequest::toString() { - return "sender: " + _senderAddress + " receiver: " + _receiverAddress + " memo: " + _memo + " cid: " + _cid; + return "sender: " + _senderAddress + " receiver: " + _receiverAddress + " memo: " + _memo + " cid: " + _cid + " label: " + _label + " avatar: " + _avatar; } ContactRequest::~ContactRequest() @@ -64,4 +86,6 @@ ContactRequest::~ContactRequest() _receiverAddress = ""; _memo = ""; _cid = ""; + _label = ""; + _avatar = ""; } \ No newline at end of file diff --git a/src/Model/ContactRequest.h b/src/Model/ContactRequest.h index 5339d5c..5335434 100644 --- a/src/Model/ContactRequest.h +++ b/src/Model/ContactRequest.h @@ -14,18 +14,24 @@ class ContactRequest QString _receiverAddress; QString _memo; QString _cid; + QString _label; + QString _avatar; public: ContactRequest(); - ContactRequest(QString sender, QString receiver, QString memo, QString cid); + ContactRequest(QString sender, QString receiver, QString memo, QString cid, QString label, QString avatar); QString getSenderAddress(); QString getReceiverAddress(); QString getMemo(); QString getCid(); + QString getLabel(); + QString getAvatar(); void setSenderAddress(QString address); void setReceiverAddress(QString contact); void setMemo(QString memo); void setCid(QString cid); + void setLabel(QString label); + void setAvatar(QString avatar); QString toString(); ~ContactRequest(); }; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index e8f8015..42a2419 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -463,6 +463,8 @@ void::MainWindow::addContact() QDialog dialog(this); request.setupUi(&dialog); Settings::saveRestore(&dialog); + + bool sapling = true; rpc->createNewZaddr(sapling, [=] (json reply) { QString myAddr = QString::fromStdString(reply.get()[0]); @@ -471,21 +473,48 @@ void::MainWindow::addContact() ui->listReceiveAddresses->setCurrentIndex(0); qDebug() << "new generated myAddr" << myAddr; }); + + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + request.cid->setText(cid); + + - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); - request.cid->setText(cid); - QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { - QString cid = request.cid->text(); - QString addr = request.zaddr->text().trimmed(); - QString getrequest = addr; - QString newLabel = request.labelRequest->text().trimmed(); + + QString addr = request.zaddr->text(); QString myAddr = request.myzaddr->text().trimmed(); + QString memo = request.memorequest->toPlainText().trimmed(); + QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); + QString label = request.labelRequest->text().trimmed(); + + contactRequest.setSenderAddress(myAddr); contactRequest.setReceiverAddress(addr); - contactRequest.setMemo(newLabel); + contactRequest.setMemo(memo); contactRequest.setCid(cid); - QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); + contactRequest.setAvatar(avatar); + contactRequest.setLabel(label); + + }); + + QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact); + QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact); + + dialog.exec(); + + rpc->refreshContacts(ui->listContactWidget); + +} + +void MainWindow::saveandsendContact() +{ + this->ContactRequest(); + QString addr = contactRequest.getReceiverAddress(); + QString newLabel = contactRequest.getLabel(); + QString myAddr = contactRequest.getSenderAddress(); + QString cid = contactRequest.getCid(); + QString avatar = contactRequest.getAvatar(); + if (addr.isEmpty() || newLabel.isEmpty()) { QMessageBox::critical( @@ -520,42 +549,83 @@ void::MainWindow::addContact() QMessageBox::Ok ); return; - }); - - dialog.exec(); - rpc->refreshContacts(ui->listContactWidget); + + + } +void MainWindow::saveContact() +{ + QString addr = contactRequest.getReceiverAddress(); + QString newLabel = contactRequest.getLabel(); + QString myAddr = contactRequest.getSenderAddress(); + QString cid = contactRequest.getCid(); + QString avatar = contactRequest.getAvatar(); + + if (addr.isEmpty() || newLabel.isEmpty()) + { + QMessageBox::critical( + this, + QObject::tr("Address or Label Error"), + QObject::tr("Address or Label cannot be empty"), + QMessageBox::Ok + ); + return; + } + + // Test if address is valid. + if (!Settings::isValidAddress(addr)) + { + QMessageBox::critical( + this, + QObject::tr("Address Format Error"), + QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), + QMessageBox::Ok + ); + return; + } + + ///////Todo: Test if label allready exist! + + ////// Success, so show it + AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); + QMessageBox::information( + this, + QObject::tr("Added Contact"), + QObject::tr("successfully added your new contact").arg(newLabel), + QMessageBox::Ok + ); + return; + +} // Create a Tx for a contact Request Tx MainWindow::createTxForSafeContactRequest() { Tx tx; +{ CAmount totalAmt; QString amtStr = "0"; CAmount amt; amt = CAmount::fromDecimalString("0"); totalAmt = totalAmt + amt; - for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - { - if (ui->contactNameMemo->text().trimmed() == c.getName()) - { - QString cid = c.getCid(); - QString myAddr = c.getMyAddress(); + + QString cid = contactRequest.getCid(); + QString myAddr = contactRequest.getSenderAddress(); QString type = "Cont"; - QString addr = c.getPartnerAddress(); - qDebug() << contactRequest.toString(); + QString addr = contactRequest.getReceiverAddress(); + QString hmemo= createHeaderMemo(type,cid,myAddr); - QString memo = ui->memoTxtChat->toPlainText().trimmed(); + QString memo = contactRequest.getMemo(); // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); qDebug() << "pushback chattx"; tx.fee = Settings::getMinerFee(); - } - } + +} return tx; qDebug() << "RequestTx created"; @@ -563,7 +633,7 @@ Tx MainWindow::createTxForSafeContactRequest() void MainWindow::ContactRequest() { - /* if (request.labelRequest->text().trimmed().isEmpty() || request.memorequest->toPlainText().trimmed().isEmpty()) { + if (contactRequest.getReceiverAddress().isEmpty() || contactRequest.getMemo().isEmpty()) { // auto addr = ""; // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { @@ -573,7 +643,7 @@ void MainWindow::ContactRequest() { msg.exec(); return; - }*/ + } Tx tx = createTxForSafeContactRequest(); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index e099111..5f4d6ec 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -14,21 +14,21 @@ Send a contact request
- + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> - + <html><head/><body><p>Please insert a Nickname for your contact :</p></body></html> - + @@ -162,44 +162,54 @@ - + - + <html><head/><body><p>Please insert the Address of your contact :</p></body></html> - + - + + + + Insert a memo for the request + + + + Your HushChat Address - + + + + - + The Conversation ID - + - + @@ -215,7 +225,36 @@ + + + + Qt::Horizontal + + + + 278 + 20 + + + + + + + + 100 + 0 + + + + Only add this contact + + + false + + + + @@ -224,7 +263,7 @@ - Add Contact + Add Contact & send request false diff --git a/src/mainwindow.h b/src/mainwindow.h index 4419fcb..445e3f6 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -56,6 +56,8 @@ public: bool isWebsocketListening(); void createWebsocket(QString wormholecode); void stopWebsocket(); + void saveContact(); + void saveandsendContact(); void balancesReady(); From 3b4cb1c39a917d6ec6ff48896ce63aeac439439a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 16:21:03 +0200 Subject: [PATCH 119/253] add indonesian language --- application.qrc | 1 + res/silentdragonlite_id.qm | Bin 0 -> 42472 bytes res/silentdragonlite_id.ts | 2002 ++++++++++++++++++++++++++++++++++++ silentdragon-lite.pro | 1 + 4 files changed, 2004 insertions(+) create mode 100644 res/silentdragonlite_id.qm create mode 100644 res/silentdragonlite_id.ts diff --git a/application.qrc b/application.qrc index d2fde2d..63d9c5d 100644 --- a/application.qrc +++ b/application.qrc @@ -21,6 +21,7 @@ res/silentdragonlite_it.qm res/silentdragonlite_hr.qm res/silentdragonlite_fa.qm + res/silentdragonlite_id.qm
res/css/blue.css diff --git a/res/silentdragonlite_id.qm b/res/silentdragonlite_id.qm new file mode 100644 index 0000000000000000000000000000000000000000..a4a9338ae93d9212378b4a6c8aff5890536748d4 GIT binary patch literal 42472 zcmc(I3z%G0mF`Zu`c?hPi_pXvPeSMpq0{Mv03jrSPIu=)l1`@|2>}OF-BsOPq`Io8 zs_srlhCx6cg6LInfI-JmRFoNDR2&sSMj1wwLB?UOkC{P7alBU@ok5ft?-lR=?{&^T z`&6CkZsvNw`)N2;)#t3e*4k^WyLoyj!lBugdkE=g9TmPNjC=sniW`RBF#4u1Q>Pz_kn4r*VCkQhP7N z^--lR{g6^O?Nw@j7T2eg>fMa%kCi%dt5UhRQb*sT)XjG(b$LOlTO76UiVxzR(^TYv zk0>=-ry~FTok~UiR<8R#EZ3QztH`&1PpP|aQkB~;R%+F>TsvcOz4{fo-u*dMd89|F z_!Fvf>=nR!Syg8KNU1A6sw(g6R%-n_Rpk@-eSC?kd@`Zb@qShL^}kkXwdJUH;Saz`tLqE3Uc*_`FYD)%&DU zt&3IW?sm}iah3ZG=)2`v_12s3SE}kS)$c!jOsTUrs_$Oat5m~``r+q*$Cj_FACF=F znw0ug<0W|h(glnD6ysm_;)0bwY*gyveG4wQXGW=sUoS|keNCy0{$Rnio8rLtQw#2> z9#`tBXBIpZy;iBq{$|0KuU@3o8~<^^zds9pp8Kj?kDprb%at!FRa>>-w+kU7?>N42 z$=kjRK0dwB+51b-_g%T3^YX&8?!$P;zPoVqZ-CeE1q-kEF8+S{3Ax^V{=zp`d|0Ws zU$8Lyj^~tm=g`9GEq|p{PxHc?S3IUv;};g*`TR=Ib9CXy$mi-S7e0T^x0O0`VBz!6 zEmZ38pDcXoLeRH6vhYWzexTHw-cix;D)3nL8Mz*L09X9JY_g*D;yaft!tYl+AKCOK$mxm=k;D6bsMJt5h2EVVx$T#~#r$uLyzc?`1mP|FWT{i3ZN$9( zW8|r3z$z{nkq7+B=m>U08YH%e_iX?W){=5VmdN?#iJ{excMQzpXs}LM`~PpmOAA ze-8P2sB-*K*ty($D{sFC@_Y76m3N%?UZrl`Q+e0uTa+5uQ+dyoS1NU~x$+}l0)6NI zsPYrHeOalozo~pU4SwzWdgUjd`FEujw^ly-_@|V*QdNE_{sE=_TfFkw{m|zvAE;Wo z{Bug(w!EtQBaq`gpRPLb4$RNizN)uY0p86cRoC44dHjB?>h0$~58Jx1>ZZGHRO(Z_i<32>@^QuUREpu6|Ns&7uW zE45>D)l0vBno?a~tolVC@bCS6_1V{8+zWnQz43Nj7xu~Zf(xq8y&Zgh%crX^Iuqlc zJzCwf;_o5H2dWQr0p9hOR$p;_2kiJiR9}7Sli=U`t0yxL;l2-4zx@`>%kO=(`hgvI z{;uy;KY05OFu}^brsUfA4!QO{BG+3VsDAL@z`vPyRzLLDxIee1`jHsqe9e>9fAI>& zJMGHqzt!VBSN*Me%wJn)^{eZSfsRzo!UxZUynU!1xnb-(EBFv!_7U zy)_f9`1^TlYfjwC#^QEVuUx)YCeDwjqU4MGbD|Pt$%Hf(i(BN_qU@}kK?|+??#;|d>^|ZdTt~FdtDLTRs;UMxe(p< zE3D5~zbm@)DD2i7&WOhT*A~d>vS{-1^_cIq(Hs8-&mX-sdTZhZrB=Td{lkwghMoOM z^g|m#*ZFUaKKv=*+4}S7XYYIp>(qnMFWf!|dw6g3i5-2A=Pl8vwmzfOhOb4xdK-SP zd^Gy<$~~Bu@6|2%%(YlQuB@x)b6pK}%Wr-W^8Bs3ov(ci_VZ13hqhJ2K76yTZ^t5~ z-qTk%wj_@ExVLUPiu*5&)ZO$NzAt=Cu3JA_cl&)KkmvW*-SaBozTqo%-|p$bdVHkr z`)Aw_f8afJ-`^SmKF`;^)(p9R-yhd6_}7;J=Y{&M&3D4yHrDt2$8$>EzPG;r$Q@Wu z57+mItIswpxe?Tc;sC0Yu~!Y#6MvEmp;~*Ogsqr`D?k} z_Eh6d_nZMfeW&qV-#8O+n;V~h7V@#OzVRCk(98DSjW6hHMdSCD4nQxqHvaF8YoQO1 zH8m~LRpG#!5x^L_lAO;?{tW8L_druVG52EOS_ za-FJ>>+LT$-SgXSrJR2I%t zoGiVx>Dv{J(4)Ghf8KMWQV0G_uGemE`X7Vu$9n2C{o9M+b7WIese7j?U>NIFr%I`q zn!vw84SrBn_*dN-kLMEkJb0uQxu17sGA9mZ;)&D(J{MI7@Wil6sFZoC@<41jkt+Yp z++!`-6-&j^BZ>TAY&ezhN2^zts!8BTOvlZ5Rh<)=$#j7OmV3}q11gEf5-P0m%-PZ#;qF=GiqFuNa!(@*RTma4fuWfm%N(B9XS=pFEjct zWBA0`OygV5Q1r&WR3es7IABa7=fs?;SSlHJvax)AI+Kf&#^Uj}lu(xj!{dOQ2ZcE> zJ&RAtGL$wS)r2|SiILn)mTY%~_OPK=g%A@a%uO!PzFE-DsiPn~r6r{RCi65Ih4F;5dCLasm5}I^NBPp<0m{WFHhU<#6EK>~OlU;P zqp=s$nE|DFOmnLiv=jJ7?v1;gNaHWGFSIRU;b?5PL_XbG za8g)poK*4z#q!jKn7qRl}des6-hry*u%br)YbPi`G#e5f06V(r7X(SB=l`Wmw ztX_(X!Sn7O(2kYNy1OTy428W#-+dCWY5Hjw@?bxgF-}k)eoJcp(c)2<6PP+5i{_S| zli5tJ;6Oi}Y%V!PlW`(36N=cHlA+4$#!?S372C;<=dj>}O%#dU4HU7MTg2|h%2@91 zy&xf_vew;u6Dhqi7c+7NVDAMZ@{nAb%OpOHXg2wR)X=hbGC%HgC-WoT+E+ArK`2Kt z`Y_-G-3%AX(Zq1x^)ZTZX#p<%cyFQXza$f-S|f1OzSsdndZ}41`_Ewmg96X)9viW1P#YVPK5D$ zi3_~|!Ab)1m?b*3fKs5z3&m@p>M%33pd$?S%W6C3r2yJfYN!630G@HRQGcU$#UZNv zOBS?<0T=@gJJcFbBmCkbzDD1Z$6c}{d)P22$QC;=+Q^r+j^`N%wWIdozl4(mwpE8pdClu0dF#ALzGi-8titlk z=#iF#Gth?_;jC~mfd&{kZa@_2z)&T#Nyu!NY|R}V7F)_@J9fp`EqbNRSoVvfGLCgx zhT%_yjk>Z3hWLM!F<1_Ry%z&JUVIt`YB@Y>Iyn?m%i}jd>OEu_NrwSwMwBa7nOZR` zh{2g`=(0CIa+*9$h9%q%LuQwa0MMbYpu>I8Hv#sDTgS+Uz89ySen`MEHk3Qwc;m6W zGn`1I;Xov&l9|aoJp0LfLL$kc)wHb$0e|q>hFa_m1#O*7mxDcLKA~9DF0~U7pq0^J z0sp1X$pyzvpx|4pI!kTBf1Pl@RIN5#IaAUXFxLpJT{&$%Yf~!?O;Q}z)nPN!s3SOz z85GiLS2)9-p=^4~72P7&%o<$k^y08ruNh&_FVbT&xJiL#jBK8)>SDr1XMKv9wl%;4 z@m%7XX=ERL8cW9Ujd>9rb{pWU0X&^4IQhw}_B|&iQ-x$Ug`hzAl?e4Hw&`_5Vh{)8 z$m%c&@ok4zGruBheGbFIWfH+ zI~jgSc48PrbMYjBF%alG!AsqgmNStVhVSgO#Im6-@p?=i%{Z6b3?R(l6E)mXU4YCq z4qX>!5_}gKuwmYHqG}|S%noN_Zjz`-wU+~i2h$P(Gwt<&GvgVJFw*A-z!j1(038+v zbUM;nlZTCtIG~-85_N__s-F^T*0>GpG+g3jHif7@hd?zQYSEWi!xR9}4oqt`pu)*y zsP!vN;?OVkqGra^!6eQSNutDc4yUkzRxph2dLTqmOsR9!F2nDtu0k$#&aSy0I9T++ z!MPsjD|(Bwyq{&x~W z%j_)tdjlcbog5uaj=+M=cjI>blo+cMK%VguBP1_*L-Rsw z$^18F-(b|CF+$>uYkC;rgMYEli40J7|jGdHBQZ5DB1x2>)_h2 z_8In`CIe+-GaP5{(7;}2sDEFWj?`NtY%|Z-$@7?jZPBo&Mzv;fqRDOMpQUh;)`8tY z_ZwH1O=>fY+(GDI64%WLy7>zQNc2Yht@H7nVTJ@9LY*xxn|h`axf!f)>B4v$f?~HO zvuX2&gRz+nn>#jbhRk3wKOcpR^68Q`vz#X&9Sq(@z(c3a@M4LZBN37 zZJ>k2T4Mk%bpcwwK&bc8Y;J#^EUprGc^I>6^K$Spe%%NLy93`8q=3jU6Ep2JXEqJ_xQ`F8l9 z?FLBnfM|A^$!LZX%hVCe5=>N?B$EM9e;|W}FkjFqov_i@>WV}bM37uMZCu)f|9$!s zm|(zxQMnVC&aPOfKe)!_3*$fKomIgvk{A!zwl8OVFYKCs*(0OKZoJ<-K>2N{^rIOGw z#fNaOe~k`|j1j`Pk^%8@BDN1xdk|@&9Mh;_bgn6ihIVN&WF?Amgr?eHT;H2GS(wd1 zUJHfdluv<4;%m$eZf`6#g%uzKw*{q<9J6nfD6Zq20nQ8Of}D^6>46b`P#UuEf zqt3%!jNO>QrQ%blMO%W&5Al5%77%~>;uj^|m| z&oj+lV3yG`^wH>Ecr)9avo=M0k$T66&Cw{};HTaC!89u-=Q$&p^k~ve=Q6*7#Vx^l z;*1t)NOL}0Cg--K)EF9!YmI#ikqEf16fjR0i}i~pi#aS`8iePJiM?m!myD%{Z#qQn zvlLF_KMo!^6V%W!JQ|^IA{*K^80>2f>GpwGXkubL9^%ycZ4gA3#Z0e|$*I>i*8n`t zYahrv@eC`JNS}{{u170f=u9Y-_qrMZ4;8f8+%4J?x^J|5UTvyHoHwo{)>^U%g&${} z<*639Ze>=KEL6#F4H4m{3VKRd%oAp|ye^1h1*VF#zF#&90n&b^Yh$2~A!Zs#DEV<| z^>D22hR|4R_v^+!Si0{NTFiW|4&Y>sZmM8^@{tP#muNSy1}OADI6JobNajWELwVg$ae+$(lHBxj-J*0{H!-D9U?hjN0%$P8R_M&IEnA;8V4;mLbYN7d6j?hF`0S*6(t|FY&=J zOT+3!7{x6b|DqTN43u@;i=ce>elfthRbV%)34@xQA5@G}+}go$QS8y;Qn?qG;73C$%^pM?D-?|X>r3=X&W0UE?9hU>GC~E(7zJxX?eliXIq_$q zk$OifH)gD055CP})yxR!mzl_5WjZSTN^Y(N1=TRNOZuEcaiM`O7%&hxiHL)H#(H80<^u^;zqeKk)+*nto>)Ja4)?#&n|*v~MG3FbeV;H>7` zD85-84tRog$&NsMizPmv__Q?Y6cY+R7d!-u2DL4Ab3{G^+v+80(6#2|$CHUv91hy3 z+cqI#Y#1qv0;JgDQLTp<3=NDZ{Q=YrVl@Nq*kOYOm#Np?5?dTkk86wcdYNsnlr{?f zN-2q8)>4a80~-g(>L6DG-B^0zLxP71gEA^{G6d_eAcS;zR!`R8umGVQSnh(DnVKBF z`$2*5hUF)_d3lGX!t(a>P7H2)8ezf=qHx!zN2{Z$Im6?GN3XNrq3N3?P;-g)XbTw{ zTlR2Za$+Ku3tjh{p$dLsfjMf{J?zHj`T^A6Xr;=P6`GMqnIDK#W_?gTy;2O)ldzj+Ye4?_s#ilLKbB7LjTust-9d9BW5G2Ug`UZ$H>3r2@t8(mhL zuVTN4R^LX|enQ}Q3#SMf7hf7tcE6ZrWTW0)AO}s^6c;w*(Y5mo4;%8NpzQu3<`qg& zQnr2UFw1bcb`H=QETT#Q!srr*+X5|-TWS1EK@S=NT1+N>{bt`Ybt{cXv7U!QO!s(> zqV+hRfYitHp~8Jf8Quq-eDYNidc>V`MAfvz9^o%lk)2zd73L?1Cl@=RnBqsQMG)l^ zVUZhB==T+?(`yZ~BM9B1?6__+JLVjebSAT)H@bwrKBrhan(#4ZpobptyF;ewgd!cHdotv!wahvjn9p_0`w zSq|=uDrviA-w;>lU`4zKzXhvNiwFH$kE06>VbGS8LNnS@Z$Su6AuO{Vrn8{YGLP5k z$FrEZ@V2G68<2~zPi#yfD_&fp8+ku*5 zi}tc7AO<_EBIdaW@8MZwCSk>p*vX7)?MK3A!f9pvzim4ee&@xpiNcPPEi`#MLT!FK zX!Z+l{#xa$wxqV)!kyv9(xEg{y7X5wNGj>tTiAp!2SRC~qLC-0{{TLdFTP0E59xLa z$Lt#_b}s7G5v`fDhkmBI>IhuI@Dk-({Q#v@8ZZ6S2|WvGE%f^pmK;gs^4w%X)}f04jXBBff4^%jbl>I!$S_QetxSkxdazc<~yda^5KTD5fQj_p50kr3&tWu#iqfG}K zvutU?7;I_5qJUvX0- ztF_@ge}juNTZ2>BEft^fcW;G>d`A(p>05A#peG_CS#G4${gD_Vpc950l^<|^!U|IQbu$5yP<6Bf042< zM{mKRB7q?5#b=mP2=(-E8YM@|(pI@le!DJ~`MLi+dRqPaTXiu}MS zL1-Al0th!ICuuweQSM-_ZovSBO_{npzz&-Qb80hK7mPHDN-jowHWU#bQ27$V!z|7B z%VH_6DW`@`QcB}Q_pBR}W+y&ZD^`BH-dwCr&dOS|3axgSVevL43y)#b$y~7azs%Em#6qU&)hI{RZ0)U9 z63BnxRM~#mb}WTd1iKDuIrW$cZ%GX1(@xu$9!X7Nag+4D>*N|3UZ%p0$}tjEdzdg)aCm| z;pH&cjJN6dEG}Y|Pi3Z&K$%F6aXYxAv<9*{Hi-EdcdxBthEB*pEQ|i^F>lX6yRNh} z9n=6|^dNzZMAKJO~PM;5h5j!P?7GAMD^{E=`|IS589#9{{fQG;ct9qIBwf zhHx-?k>bY|iJ+nEOn0U>>@>3?6G?C1oo$MEC`wz)&W^n}%{Ehuhte|K+;eq{_K_tA zOaGR^V*+#Lsl$Fvt*lcNauMx);DE$wEId;^JhNMzxV8%*6o0Q(z`;QjY&4y~Sb9vu zyB$a=WTsgda8D%3JE%YAbOI>J^EuKe8%!l*P9F1`E=Ui6gYyI?#xpX}OAhKSAJ|Ra zB|tKAX2=$;lF|`HrS+)kbk&qJ(^rs8Dw9QaNpFb@%n|4gz;g=A4aP2bR$9bg|z%v3%Shc2AUqpJ;b2(7LY_+2i!A_%&*#Nql!$^&6&DAMSU$ z5OK|h*7ab&?4flOp4IzP1QMMFPD`*p7?e#i*DLPwPA&-&u9P|?G@hk0wb$B;w10pt zm%8iia6b`u^q~{lXa|HC+pn-knX-W96}l5H|Hb-e$FVhh?+xVW;xNMt~W6~04HlVw4C0+ zf}KFqD}nSux?~lXL;xqsTiNK%*q_<$vdy!}B!6)ul zJ%A_oj3?6d&djz=ia3>pzif3ERuPDaU2XpYgC)NscE@ew8mf17FIXnp7?ZrRg z<39XC?sjRO4}qsN5k1zNbm9r{)o^cDpeV*ug(S3YMQFx&OAh&Hclr+WbPn`5yE?n} zJNpKmp+0Azr)#Lc=fE)?VwKPDLE!BYv7+QdtgR*Vv_bXU5Z1&xB01I z7rf-+Jc|)XxR@bM^G^ZOGzd#W2WZ9|(UkjT=;DyM-fOzU1{Iy)uI3N;qUn!7XHJ@d zBhKJS?K4*&J~Vt4PD9i8M13O6oz>2$KBi*<&0gsT_O}x)cY(C)m@>i5 zXkexwX(KSMyTD~S7(93aK~Kyqtq_jzGl+sgp1(E9clk??5<2IsO{QfHay&sJfGF2H z7ESlxy7hJ~zX29}Lw9EoG3p*`Hk2vROtH9AEiQ)Or9R;aY@ABsI2^5(E|5I331f+i zOC)LTQz8Of-wMkmU5ezDM-{c0JoR^bdh5YHP^x!&8JTW&V|$0EHaPnx^geX%2rWU4 z#}kR`E_Na~o)LKid6@^9t9Pv6SGNNcv=`y+C(90Cesnz*)RaPB?m>t8Xz!*B{N3|{ zZ%0^uwV3W;9{(V3hAOY>$s@94TsV1djz2MxmCd&S3J109dJQzbW|-XK}8(!U#gT3Cr4oh(eETgKb(XA)FE4QCf1#ZaoRa~=^9pdke=dfp8+ ztP^;OV@zyW45KE6`BZj}Je+pPB$_@HOiAZe(~KR` z;QKoA0C2!^Q^}E1>$Sq=wV%@9puuJwJBl{FH~~HIqTUT!mgLk3Va4k|H6j4`b)WbU zczUy5252BQ!oZ7wdW#yDWY3gXg)Spz%jIN+jcDc2M>vY#RcbI+KsH3ObkQFp@kmjo zV*R5wYrB!N+&Gw=DCPfhL@cr*adk4b-Jnt5Eh?Sz&e#nQxCW7ryK>>_&^6CMTIw!h z-U8trM-%|a9e)&n4HjVTx+?=*|E`@GGt62U2I2{KfH8nK9*<%|vJY7u>5K`CyWA%o zFiSiIB}lriJEYWez)P_Mj)x(O7wS*$RP*Dt8()oNC6fkZ!$E{T|&l3L&;#wWM|-g zpTh5f=4wW(&UMS{P?H=zeI;Y#@mH=GVpMt9p3RPOTR_Q(Ktj|I+zEp7ZoVE4gl>

d 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 Ncr$(OhNZBF{tup&v5o)$ literal 0 HcmV?d00001 diff --git a/res/silentdragonlite_id.ts b/res/silentdragonlite_id.ts new file mode 100644 index 0000000..54163a4 --- /dev/null +++ b/res/silentdragonlite_id.ts @@ -0,0 +1,2002 @@ + + + + + AddressBookModel + + + Label + Label + + + + Address + Alamat + + + + BalancesTableModel + + + Address + Alamat + + + + Amount + Jumlah + + + + ConnectionDialog + + + SilentDragonLite + SilentDragonLite + + + + Starting Up + Memulai + + + + Controller + + + Wallet Password + Password Alamat + + + + Your wallet is encrypted. +Please enter your wallet password + Wallet Anda terkunci. Mohon masukkan Password Alamat Anda + + + + + Wallet Decryption Failed + Gagal Mengdeskripsi Dompet + + + + Please enter a valid password + Mohon Masukkan Password yang benar + + + + Failed to unlock wallet + Gagal Membuka Dompet + + + + CreateWalletForm + + + Form + Form + + + + Restore wallet from seed + Mengembalikan Dompet menggunakan Seed + + + + Restore an existing wallet, using the 24-word seed. + Mengembalikan Dompet menggunakan 24 Kata Seed + + + + Create a new Wallet + Membuat Dompet Baru + + + + Create a new wallet with a randomly generated seed. + Membuat Dompet baru dengan Seed acak + + + + MainWindow + + + SilentDragonLite + SilentDragonLite + + + + Balance + Balance + + + + Summary + Ringkasan + + + + Shielded + Shielded + + + + Notarized + Notarized + + + + Transparent + Transparan + + + + Total + Total + + + + Your node is still syncing, balances may not be updated. + Node anda masih Menyinkronisasi, balance mungkin tidak di perbarui + + + + Some transactions are not yet confirmed. Balances may change. + Beberapa transaksi belum di konfirmasi. Balance bisa berubah + + + + Address Balances + Alamat balance + + + + + Send + Kirim + + + + Total notarized funds available: + Total Biaya yang tersedia + + + + Send To + Kirim ke + + + + Recipient + Penerima + + + + + + + + Address + Alamat + + + + + Address Book + Buku Alamat + + + + + + + Amount + Jumlah + + + + Max Available + Tersedia Maksimal + + + + + + + Memo + Memo + + + + Add Recipient + Tambah Penerima + + + + Recurring payment + Pembayaran Berulang + + + + Every month, starting 12-May-2012, for 6 payments + Setiap Bulan, Mulai 12-Mei-2012, untuk 6 Pembayaran + + + + Edit Schedule + Sunting Jadwal + + + + + Miner Fee + Bayaran Penambang + + + + 0 + 0 + + + + Cancel + Batalkan + + + + Receive + Terima + + + + Address Type + Jenis Alamat + + + + z-Addr + z-Addr + + + + t-Addr + t-Addr + + + + Next Address + Alamat Berikutnya + + + + Information about Hush + Informasi Tentang Hush + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> + + + + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> + <html><head/><body><p align="center">|</p></body></html> + + + + Next Halving + Halving Berikutnya + + + + Difficulty + Difficulty + + + + Last Notarized Block + Notarized Block Terakhir kali + + + + Total Supply + Total Suplai + + + + Longestchain + Longestchain + + + + BlockHeight + BlockHeight + + + + Supply zAddr + zAddr Suplai + + + + Supply tAddr + tAddr Suplai + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> + + + + + Market Cap + Kapitalisasi Pasar + + + + Volume on Exchanges + Volume di Pasar + + + + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> + + + + View All Addresses + Lihat semua Alamat + + + + Label + Label + + + + Update Label + Perbarui Label + + + + Address balance + Alamat balance + + + + Optional + Pilihan + + + + + Export Private Key + Mengekspor Private Key + + + + Your node is still syncing, balances may not be updated + Node anda masih Menyinkron, Balance mungkin tidak di perbarui + + + + Transactions + Transaksi + + + + + + + + + + + + + + + Loading... + Memuat... + + + + Version hushlightd + Version hushlightd + + + + Vendor + Vendor + + + + &File + &File + + + + &Help + &Help + + + + &Apps + &Apps + + + + &Edit + &Edit + + + + E&xit + E&xit + + + + &About + &About + + + + &Settings + &Settings + + + + Ctrl+P + Ctrl+P + + + + &Send DenioD Feedback + &Send DenioD Feedback + + + + &Hush Discord + &Hush Discord + + + + &Hush Website + &Hush Website + + + + Check github.com for &updates + Lihat github.com for &updates + + + + &Export all private keys + &Export semua Private Keys + + + + Address &book + Alamat &book + + + + Ctrl+B + Ctrl+B + + + + &Export seed phrase + &Export Kata Seed + + + + + Export transactions + Ekspor Transaksi + + + + Pay hush &URI... + Pay hush &URI... + + + + Connect mobile &app + Sambung ke Mobile &app + + + + Ctrl+M + Ctrl+M + + + + &Recurring Payments + &Recurring Payments + + + + Request hush... + Meminta Hush + + + + File a bug... + File-nya Bug + + + + Encrypt Wallet + Enkripsi Dompet + + + + Remove Wallet Encryption + Menghilangkan Enkripsi Dompet + + + + Rescan + Re-scan + + + + Wallet is already encrypted + Domper sudah di Enkripsi + + + + Your wallet is already encrypted with a password. +Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. + Dompet anda sudah di Enkripsi menggunakan Password. +Mohon Gunakan 'Hapus Enkripsi Dompet' Jika anda ingin menghapus Enkripsi Dompet Anda + + + + Passwords don't match + Passwords don't match + + + + Error was: + + Error: + + + + Wallet Encrypted + Dompet ter-Enkripsi + + + + Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. + Dompet berhasil di Enkripsi! Password akan dibutuhkan untuk mengirim dana atau mengeskpor Private Keys + + + + + Wallet Encryption Failed + Enkripsi Dompet Gagal + + + + Wallet is not encrypted + Dompet tidak di Enkripsi + + + + Your wallet is not encrypted with a password. + Dompet anda tidak di Enkripsi dengan Password + + + + Wallet Password + Password Dompet + + + + Please enter your wallet password + Mohon masukkan Password Dompet Anda + + + + + + Wallet Decryption Failed + Deskripsi Dompet Gagal + + + + Please enter a password to decrypt your wallet! + Mohon masukkan Password anda untuk mengdekripsi Dompet ! + + + + Wallet Encryption Removed + Enrkipsi Dompet di Hapus + + + + Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. + Dompet anda berhasil di Dekripsi! Anda tidak perlu lagi Password untuk mengirim Dana atau Mengekspor Private Keys + + + + + Copy txid + Copy txid + + + + + Copy block explorer link + Copy Link block explorer + + + + View tx on block explorer + Lihat TX di Block Explorer + + + + Refresh + Segarkan + + + + Restart + Mengulang + + + + Please restart Silentdragonlite to have the theme apply + Mohon Restart Silentdragonlite untuk menampilkan Tema yang di pilih + + + + Currency Change + Ubah Mata Uang + + + + Some feedback about SilentDragonlite or Hush... + Beberapa feedback tentang SilentDragonlite atau Hush + + + + This change can take a few seconds. + Perubahan ini bisa membutuhkan beberapa detik + + + + or SilentDragonLite + atau SilentDragonLite + + + + Send DenioD some private and shielded feedback about + Kirim DenioD beberapa feedback tentang Privasi dan Shielded + + + + Paste HUSH URI + Paste HUSH URI + + + + Error paying HUSH URI + Error membayar HUSH URI + + + + URI should be of the form 'hush:<addr>?amt=x&memo=y + URI harus berada di Form 'hush:<addr>?amt=x&memo=y + + + + Error + Error + + + + Error exporting transactions, file was not saved + Error mengeskpor transaksi, File mungkin tidak disimpan + + + + This is your wallet seed. Please back it up carefully and safely. + Ini adalah Dompet seed anda. Mohon di back up dengan hati hati dan aman + + + + + Save File + Simpan file + + + + + Unable to open file + Tidak bisa membuka File + + + + Error getting private keys + Error mendapatkan Private Keys + + + + Error loading private keys: + Error memuat Private Keys + + + + These are all the private keys for all the addresses in your wallet + Ini adalah semua private keys untuk semua alamat di dompet Anda + + + + Private key for + Private key untuk + + + + + Copy address + Copy Alamat + + + + + + Copied to clipboard + Ter copy di Clipboard + + + + Get private key + Dapatkan Private Key + + + + + View on block explorer + Lihat di block explorer + + + + View Payment Request + Lihat Permintaan bayaran + + + + View Memo + Lihat memo + + + + Reply to + Balas ke + + + + Created new t-Addr + Membuat t-Addr baru + + + + Copy Address + Copy Alamat + + + + Address has been previously used + Alamat sebelumnya sudah digunakan + + + + Address is unused + Alamat belum digunakan + + + + Cannot support multiple addresses + Tidak mendukung Alamat Ganda + + + + Recurring payments doesn't currently support multiple addresses + Pembayaran Berulang doesn't Belum mendukung Alamat Ganda + + + + Recipient + Penerima + + + + Only z-addresses can have memos + Hanya z-Addresess yang mempunya memos + + + + Memos can only be used with z-addresses + Memo hanya bisa di gunakan untuk z-Addresses + + + + The memo field can only be used with a z-address. + + Memo hanya bisa digunakan untuk z-Address + + + + +doesn't look like a z-address + doesn't kelihatannya bukan z-Address + + + + Transaction Error + Transaksi Error + + + + Please wait... + Mohon tunggu... + + + + Computing your transaction + Mengkomputasi transaksi Anda + + + + Done! + Selesai! + + + + Recipient Address + Alamat Penerima + + + + is Invalid + Tidak valid + + + + Amount for address '%1' is invalid! + Jumlah untuk alamat '%1' Tidak valid! + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 5 confirmations before they can be spent + Tidak memiliki dana yang cukup untuk melakukan transaksi ini +Memiliki: %1 +Membutuhkan: %2 + +Note: Dana membutuhkan 5 konfirmasi sebelum mereka bisa digunakan + + + + MemoDialog + + + + Memo + Memo + + + + Include Reply Address + Masukkan Alamat Balasan + + + + MemoEdit + + + Reply to + Balas ke + + + + MigrationDialog + + + Migration Turnstile + Migrasi Turnstile + + + + Migration History + Sejarah Migrasi + + + + Migrated Amount + Jumlah yang di migrasi + + + + Unmigrated Amount + Jumlah yang tidak di migrasi + + + + Sprout -> Sapling migration enabled + Sprout -> Sapling migration diaktifkan + + + + If enabled, hushd will slowly migrate your Sprout shielded funds to your Sapling address. + Jika di aktifkan, Hushd bisa perlahan memigrasikan dana Sprout yang terlindungi Anda ke Sapling Adress. + + + + MobileAppConnector + + + Connect Mobile App + Sambung ke Aplikasi Mobile + + + + Scan this QRCode from your silentdragon companion app to connect your phone + Scan QRCode dari Silentdragon kompani anda untuk menyambung ke Hp + + + + QR Code + Kode QR + + + + Connection String + String Koneksi + + + + Allow connections over the internet via silentdragon wormhole + Memperbolehkan Koneksi ke Internet menggunakan Silentdragon Wormhole + + + + silentdragon Companion App + Silentdragon Aplikasi Kompani + + + + Disconnect + Disconnect + + + + + TextLabel + Label Teks + + + + Last seen: + Terakhir Kali dilihat + + + + Connection type: + Tipe koneksi + + + + NewSeedForm + + + Form + Form + + + + This is your new wallet's seed phrase. PLEASE BACK IT UP SECURELY. + Ini adalah Dompet baru Anda's seed phrase. MOHON DI BACK UP SECARA AMAN + + + + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it + Seed Phrase adalah salah satu jalan untuk mengembalikan dompet. Jika anda melupakan Seec phrase, TIDAK ADA CARA UNTUK MENGEMBALIKAN DOMPET DAN DANA di dalamnya + + + + NewSeedPage + + + Error creating a wallet + Error membuat dompet + + + + Failed to save wallet + Gagal menyimpan Dompet + + + + Couldn't save the wallet + Couldn't save the wallet + + + + PrivKey + + + Private Keys + Private Keys + + + + QObject + + + Pick + Pilih + + + + Address or Label Error + Alamat atau Label Error + + + + Address or Label cannot be empty + Alamat atau Label tidak bisa kosong + + + + Address Format Error + Format Alamat Error + + + + %1 doesn't seem to be a valid hush address. + %1 doesn't kelihatannya bukan Alamat HUSH yang valid + + + + Label Error + Label error + + + + The label '%1' already exists. Please remove the existing label. + Label nya '%1' sudah ada. Mohon hapus label yang sudah digunakan + + + + Import Address Book + Impor Buku Alamat + + + + Unable to open file + Tidak bisa membuka file + + + + Address Book Import Done + Buku Alamat selesai di Impor + + + + Imported %1 new Address book entries + Ter-Impor%1 Buku Alamat Baru + + + + Copy address + Copy Alamat + + + + Copied to clipboard + Ter-copy ke Clipboard + + + + Delete label + Delet Label + + + + Attempting to initialize library with + Mencoba untuk menginilisiasi Library dengan + + + + Using existing wallet. + Menggunakan Dompet yang sudah ada + + + + Create/restore wallet. + Buat/mengembalikan Dompet + + + + + Connection Error + Koneksi error + + + + + + Transaction Error + Transaksi Error + + + + There was an error sending the transaction. The error was: + Ada error dalam mengirim transaksi. Error nya: + + + + + No Connection + Tidak ada Koneksi + + + + There was an error connecting to hushd. The error was + Ada error dalam mengkoneksikan ke Hushd. Error nya: + + + + + + Tx + Tx + + + + + + failed + Gagal + + + + + The transaction with id + Transaksi dengan ID + + + + + failed. The error was + Gagal. Error nya: + + + + Update Available + Pembaruan tersedia + + + + A new release v%1 is available! You have v%2. + +Would you like to visit the releases page? + Rilis Pembaruan v%1 telah tersedia! Versi Anda Sekarang v%2. + +Maukah anda mengunjungi laman pembaruan ini + + + + No updates available + Tidak ada Pembaruan tersedia + + + + You already have the latest release v%1 + Anda sudah memiliki Versi terbaru dari v%1 + + + + Please wait for SilentDragonLite to exit + Mohon tunggu untuk SilentDragonLite untuk keluar + + + + Waiting for hushd to exit + Menunggu untuk hushd untuk keluar + + + + No hush price was available to convert from USD + Tidak ada harga hush yang tersedia untuk di konversikan ke USD + + + + View on block explorer + Lihat di block explorer + + + + View Error + Lihat error + + + + Reported Error + Error yang di laporkan + + + + + Are you sure you want to delete the recurring payment? + Apakah Anda yakin untuk menghapus Pembayaran berulang? + + + + All future payments will be cancelled. + Semua Pembayaran nantinya akan di batalkan + + + + Tx submitted (right click to copy) txid: + Tx di berikan (pencet kanan untuk copy) txid: + + + + Type + Tipe + + + + Address + Alamat + + + + Date/Time + Tanggal/Waktu + + + + Confirmations + Konfirmasi + + + + Amount + Jumlah + + + + Connected directly + Terkoneksi langsung + + + + Connected over the internet via silentdragon wormhole service + Terkoneksi langsung ke Internet via Silentdragon wormhole service + + + + + Node is still syncing. + Node masih menyinkron + + + + + No sapling or transparent addresses with enough balance to spend. + Tidak ada sapling atau transparan address dengan balance yang cukup untuk digunakan + + + + RecurringDialog + + + Dialog + Dialog + + + + View + Lihat + + + + Delete + Delet + + + + RecurringListViewModel + + + Amount + Jumlah + + + + Schedule + Jadwal + + + + Payments Left + Pembayaran tersisa + + + + Next Payment + Pembayaran Selanjutnya + + + + To + Kepada + + + + Every + Setiap + + + + None + None + + + + RecurringPayments + + + Payments + Pembayaran + + + + RecurringPaymentsListViewModel + + + Date + Tanggal + + + + Status + Status + + + + Txid + Txid + + + + Not due yet + Belum Jatuh Tempo + + + + Pending + Pending + + + + Skipped + Dilewati + + + + Paid + Ter-bayar + + + + Error + Error + + + + + Unknown + Tidak diketahui + + + + RecurringPending + + + Dialog + Dialog + + + + No payments will be processed. You can manually pay them from the Recurring Payments Dialog box + Tidak ada transaksi yang akan di proses. Anda bisa secara manual membayar mereka dari Pembayaran Berulang Kotak Dialog + + + + Schedule + Jadwal + + + + How should silentdragon proceed? + Bagaimana Silentdragon harus diproses? + + + + Pay All in 1 Tx + Bayar semua dengan 1 Tx + + + + Only the latest pending payment will be processed. All previous pending payments will be skipped + Hanya Pembayaran pending terakhir kali yang akan di proses. Semua Pembayaran pending yang dulu akan di lewati + + + + Pay Latest Only + Bayar terakhir kali saja + + + + Pay None + Tidak membayar + + + + All pending payments collected, added up and paid in a single transaction + Semua pembayaran pending di kumpulkan, Di tambahkan dan di Bayar dalam satu transaksi + + + + Description + Dekripsi + + + + To + Kepada + + + + The following recurring payment has multiple payments pending + Pembayaran Berulang yang ini mempunyai pembayaran ganda yang pending + + + + RequestDialog + + + Payment Request + Permintaan bayaran + + + + AddressBook + Buku Alamat + + + + Request From + Meminta dari + + + + My Address + Alamat saya + + + + Amount in + Dalam Jumlah + + + + z address + Alamat z + + + + Amount + Jumlah + + + + The recipient will see this address in the "to" field when they pay your request. + Penerima akan melihat alamat di "to" laha saat mereka membayar permintaan anda + + + + Amount USD + Jumlah USD + + + + Memo + Memo + + + + TextLabel + Label Teks + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Permintaan Pembayaran dari Alamat Sapling. Anda'akan mengirim sebuah 0.0001 hush untuk transaksi kepada alamat menggunakan hush payment URI. Memo nya akan di masukkan ke dalam transaksi apabila alamat tersebut membayar anda + + + + Error paying hush URI + Error membayar hush URI + + + + URI should be of the form 'hush:<addr>?amt=x&memo=y + URI seharusnya berdasarkan form 'hush:<addr>?amt=x&memo=y + + + + Pay To + Bayar Ke + + + + Pay + Bayar + + + + You are paying a payment request. Your address will not be visible to the person requesting this payment. + Anda membayar sebua permintaan pembayaran. Alamat anda tidak akan terlihat kepada orang yang melakukan permintaan ini + + + + Can only request from Sapling addresses + Hanya bisa di minta dari Alamat Sapling + + + + RestoreSeedForm + + + Form + Form + + + + Please enter your 24-word seed below + Mohon masukkan 24-word seed anda berikut + + + + Wallet Seed + Dompet seed + + + + Wallet Birthday + Ulang tahun Dompet + + + + 0 + 0 + + + + Wallet birthday is the block height at which the wallet had the first transaction. If you don't know this, you can leave it as "0" (It'll take longer to rescan) + Ulang Tahun Dompet adalah block height dimana dompet itu melakukan transaksi pertamanya. Jika anda don't tidak tahu ini, Anda bisa tinggalkan ini seperti "0" (It'ini akan memakan beberpa waktu untuk rescan) + + + + RestoreSeedPage + + + + Failed to restore wallet + Gagal untuk mengembalikan Dompet + + + + SilentDragonLite needs 24 words to restore wallet + SilentDragonLite membutuhkan 24 kata untuk mengembalikan dompet + + + + Failed to parse wallet birthday + Gagal menguraikan Ulang tahun dompet + + + + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. + Tidak'mengerti Ulang tahun Dompet. Ini seharusnya merupakan Block Height dimana dompet anda untuk rescan. Anda bisa tinggalkan sebagai '0'Jika anda'tidak tahu apa yang seharusnya terjadi. + + + + Couldn't restore the wallet + Tidak'bisa mengembalikan dompett + + + + Failed to save wallet + Gagal menyimpan dompet + + + + Couldn't save the wallet + Tidak'bisa menyimpan dompet + + + + Settings + + + Settings + Konfigurasi + + + + Connection + Koneksi + + + + Lightwallet Server + Server Lightwallet + + + + Options + Options + + + + default + default + + + + blue + biru + + + + light + terang + + + + dark + Gelap + + + + Fetch hush prices + Menangkap harga hush + + + + Check github for updates at startup + Periksa github untuk pembaruan dan permulaan + + + + Connect to github on startup to check for updates + Sambung ke github untuk permulaan untuk memeriksa pembaruan + + + + Theme + Tema + + + + Connect to the internet to fetch hush prices + Sambung ke internet untuk mengambil harga hush + + + + Currency + Mata uang + + + + AUD + AUD + + + + BTC + BTC + + + + CAD + CAD + + + + CHF + CHF + + + + CNY + CNY + + + + EUR + EUR + + + + GBP + GBP + + + + INR + INR + + + + RUB + RUB + + + + USD + USD + + + + ViewAddressesDialog + + + All Addresses + Semua Alamat + + + + Export All Keys + Mengekspor semua Keys + + + + ViewAllAddressesModel + + + Address + Alamat + + + + Balance (%1) + Balance (%1) + + + + about + + + About + Tentang + + + + addressBook + + + Address Book + Buku Alamat + + + + Add New Address + Tambah Alamat Baru + + + + Address (z-Addr or t-Addr) + Alamat (z-Addr or t-Addr) + + + + Label + Label + + + + Add to Address Book + Tambahkan ke Buku Alamat + + + + Import Address Book + Impor Buku Alamat + + + + confirm + + + Confirm Transaction + Konfirmasi Transaksi + + + + To + Kepada + + + + Recurring Payment + Pembayaran berulang + + + + TextLabel + Label Teks + + + + You are sending a transaction while your node is still syncing. This may not work. + Anda sedang mengirim transaksi saat node anda masih menyinkronisasi. Ini tidak akan bekerja + + + + createhushConf + + + Configure hush.conf + configure hush.conf + + + + Your hush node will be configured for you automatically + Node Hush Andan akan di konfigurasikan untuk Anda secara otomatis + + + + Show Advanced Configuration + Tampilkan Konfigurasi tambahan + + + + Allow connections to the internet to check for updates, get hush prices etc... + Perbolehkan koneksi ke internet untuk memerika pembaruan, mendapatkan harga hush dll + + + + Use custom datadir + Gunakan custom datadir + + + + Choose directory + Pilih direktori + + + + Please note that you'll need to already have a Tor service configured on port 9050 + Mohon ketahui bahwa Anda'akan membutuhkan Tor service di konfigurasikan di port 9050 + + + + Connect to the internet for updates and price feeds + Sambungkan ke Internet untuk pembaruan dan berita harga + + + + Please choose a directory to store your wallet.dat and blockchain + Mohon pilih direktori untuk menyimpan wallet.dat anda dan blockchain + + + + Connect over Tor + Sambung menggunakan Tor + + + + encryptionDialog + + + Encrypt Your Wallet + Enkripsi Dompet anda + + + + Encryption Password: + Enkripsi Password + + + + Confirm Password: + Konfirmasi Passowrd + + + + Passwords don't match + Passwords tidak'tepat + + + + WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. + PERINGATAN: Jika anda lupa password anda, salah satu cara untuk mengembalikan dompet adalah dari Seed phrase + + + + newRecurringDialog + + + Edit Schedule + Sunting Jadwal + + + + Payment Description + Deskripsi Pembayaran + + + + Schedule + Jadwal + + + + Next Payment + Pembayaran selanjutnya + + + + Amount + Jumlah + + + + Memo + Memo + + + + To + Kepada + + + + From + Dari + + + + Number of payments + Angka Pembayaran + + + \ No newline at end of file diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index cc9092d..6e9d880 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -129,6 +129,7 @@ TRANSLATIONS = res/silentdragonlite_es.ts \ res/silentdragonlite_hr.ts \ res/silentdragonlite_sr.ts \ res/silentdragonlite_fa.ts \ + res/silentdragonlite_id.ts \ res/silentdragonlite_tr.ts include(singleapplication/singleapplication.pri) From ee672cfcca1e6a091b62219e3a4603aa80d3c100 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 17:41:12 +0200 Subject: [PATCH 120/253] contact gui fix --- src/chatmodel.cpp | 11 +- src/contactrequest.ui | 150 +++++++++++++++++++----- src/mainwindow.ui | 227 +----------------------------------- src/requestContactDialog.ui | 144 ++++++++++++----------- 4 files changed, 206 insertions(+), 326 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 42a2419..29ba9c9 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -127,7 +127,6 @@ void MainWindow::renderContactRequest(){ requestContact.requestZaddr->setText(c.second.getRequestZaddr()); - requestContact.requestCID->setText(c.second.getCid()); requestContact.requestMyAddr->setText(c.second.getAddress()); }else{} } @@ -152,9 +151,8 @@ void MainWindow::renderContactRequest(){ requestContact.requestMemo->setModel(contactMemo); requestContact.requestMemo->show(); - - requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestCID->setText(c.second.getCid()); + requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); }else{} } @@ -468,14 +466,15 @@ void::MainWindow::addContact() bool sapling = true; rpc->createNewZaddr(sapling, [=] (json reply) { QString myAddr = QString::fromStdString(reply.get()[0]); + rpc->refreshAddresses(); request.myzaddr->setText(myAddr); ui->listReceiveAddresses->insertItem(0, myAddr); ui->listReceiveAddresses->setCurrentIndex(0); - qDebug() << "new generated myAddr" << myAddr; + qDebug() << "new generated myAddr add Contact" << myAddr; }); QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); - request.cid->setText(cid); + @@ -483,7 +482,7 @@ void::MainWindow::addContact() QString addr = request.zaddr->text(); QString myAddr = request.myzaddr->text().trimmed(); - QString memo = request.memorequest->toPlainText().trimmed(); + QString memo = request.memorequest->text().trimmed(); QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); QString label = request.labelRequest->text().trimmed(); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 5f4d6ec..8667057 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -10,25 +10,31 @@ 427 + + + 780 + 427 + + Send a contact request - + - <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + <html><head/><body><p align="right"><span style=" font-weight:600; text-decoration: underline;">Choose a avatar for your contact :</span></p></body></html> - <html><head/><body><p>Please insert a Nickname for your contact :</p></body></html> + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Please insert a Nickname for your contact :</span></p></body></html> - + @@ -168,49 +174,120 @@ - <html><head/><body><p>Please insert the Address of your contact :</p></body></html> + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Please insert the Address of your contact :</span></p></body></html> - - - - - - - Insert a memo for the request + + + + + 650 + 25 + + + + + 650 + 25 + - Your HushChat Address + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address :</span></p></body></html> - - - - - - - - + + + + + 650 + 25 + + + + + 650 + 25 + + - The Conversation ID + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> - - + + + + Qt::Vertical + + + + 20 + 148 + + + + + + - + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request</span></p></body></html> + + + + + + + + 500 + 71 + + + + + 500 + 71 + + + + Qt::NoContextMenu + + + false + + + Qt::ImhSensitiveData + + + 512 + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + false + + + Add some memo to your request + + + true + + + 80 + 25 + + 100 @@ -220,6 +297,9 @@ Cancel + + false + false @@ -240,6 +320,12 @@ + + + 152 + 25 + + 100 @@ -249,13 +335,22 @@ Only add this contact + + false + false - + + + + 188 + 25 + + 100 @@ -265,6 +360,9 @@ Add Contact & send request + + false + false diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 82b4260..1ce2a50 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1569,7 +1569,7 @@ - 50 + 0 20 61 51 @@ -1607,7 +1607,7 @@ - 210 + 70 20 61 51 @@ -1633,229 +1633,6 @@ true - - - - 90 - 10 - 21 - 16 - - - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 239 - 41 - 41 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 239 - 41 - 41 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - - - 190 - 190 - 190 - - - - - - - 190 - 190 - 190 - - - - - - - 239 - 41 - 41 - - - - - - - 190 - 190 - 190 - - - - - - - 204 - 0 - 0 - - - - - - - 204 - 0 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - - - 12 - - - - Qt::LeftToRight - - - 1 - - - Qt::AutoText - - diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index d2a3b68..7e676e7 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -14,10 +14,26 @@ Incoming contact request - - + + - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + My Zaddr : + + + + + + + true + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + QAbstractItemView::SingleSelection @@ -44,6 +60,16 @@ + + + + + + + Give a Nickname: + + + @@ -72,13 +98,6 @@ - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> - - - @@ -86,66 +105,10 @@ - - - - true - - - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - false - - - QAbstractItemView::SingleSelection - - - - - + + - Request from : - - - - - - - - - - Cid : - - - - - - - - - - My Zaddr : - - - - - - - - - - Nickname - - - - - - - - - - <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> @@ -283,6 +246,19 @@ + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + + + + + @@ -294,6 +270,9 @@ Cancel + + false + false @@ -304,6 +283,33 @@ Add this new Contact + + false + + + + + + + Request from : + + + + + + + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + + + + + + + + + + Cid : + From 7e0748dd24dd0ae9253b1891e243c79abb9dab10 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 20:31:54 +0200 Subject: [PATCH 121/253] set maxLen for Chatmessages --- src/Chat/Chat.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- src/Chat/Chat.h | 2 +- src/chatmodel.cpp | 4 ++-- src/controller.cpp | 6 +++--- src/controller.h | 2 +- src/mainwindow.cpp | 39 ++++++--------------------------------- src/mainwindow.h | 17 +++++++++++------ src/mainwindow.ui | 23 ++++++++++++++++++++++- 8 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index c7d6637..d6c8445 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -6,8 +6,49 @@ #include "../DataStore/DataStore.h" Chat::Chat() {} -void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view) +ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QTextEdit(parent) { + QObject::connect(this, &QTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); +} + +void ChatMemoEdit::updateDisplay() { + QString txt = this->toPlainText(); + if (lenDisplayLabel) + lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); + + if (txt.toUtf8().size() <= maxlen) { + // Everything is fine + if (sendChatButton) + sendChatButton->setEnabled(true); + + if (lenDisplayLabel) + lenDisplayLabel->setStyleSheet(""); + } + else { + // Overweight + if (sendChatButton) + sendChatButton->setEnabled(false); + + if (lenDisplayLabel) + lenDisplayLabel->setStyleSheet("color: red;"); + } +} + +void ChatMemoEdit::setMaxLen(int len) { + this->maxlen = len; + updateDisplay(); +} + +void ChatMemoEdit::SetSendChatButton(QPushButton* button) { + this->sendChatButton = button; +} + +void ChatMemoEdit::setLenDisplayLabel(QLabel* label) { + this->lenDisplayLabel = label; +} + +void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) { + QStandardItemModel *chat = new QStandardItemModel(); // ui->lcdNumber->setStyleSheet("background-color: red"); // ui->lcdNumber->setPalette(Qt::red); diff --git a/src/Chat/Chat.h b/src/Chat/Chat.h index 526aa36..efe5b56 100644 --- a/src/Chat/Chat.h +++ b/src/Chat/Chat.h @@ -28,7 +28,7 @@ class Chat // Chat Controller public: Chat(); //QString zaddr(); - void renderChatBox(Ui::MainWindow* ui, QListView *view); // action + void renderChatBox(Ui::MainWindow* ui, QListView *view, QLabel *label); // action // void renderContactRequest(); /*void triggerRequest(); void showMessages(); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 29ba9c9..349f8be 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -308,7 +308,7 @@ Tx MainWindow::createTxFromChatPage() { QString memo = ui->memoTxtChat->toPlainText().trimmed(); - // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); @@ -326,7 +326,7 @@ Tx MainWindow::createTxFromChatPage() { qDebug() << "ChatTx created"; } -void MainWindow::sendChatButton() { +void MainWindow::sendChat() { ////////////////////////////Todo: Check if a Contact is selected////////// diff --git a/src/controller.cpp b/src/controller.cpp index db895a1..8c3b603 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1009,7 +1009,7 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); - chat->renderChatBox(ui, ui->listChat); + chat->renderChatBox(ui, ui->listChat,ui->memoSize); // refreshContacts( // ui->listContactWidget @@ -1017,9 +1017,9 @@ void Controller::refreshTransactions() { }); } -void Controller::refreshChat(QListView *listWidget) +void Controller::refreshChat(QListView *listWidget, QLabel *label) { - chat->renderChatBox(ui, listWidget); + chat->renderChatBox(ui, listWidget, label); } diff --git a/src/controller.h b/src/controller.h index cfd3bbb..b34aeb4 100644 --- a/src/controller.h +++ b/src/controller.h @@ -74,7 +74,7 @@ public: void refreshGBPCAP(); void refreshAUDCAP(); - void refreshChat(QListView *listWidget); + void refreshChat(QListView *listWidget, QLabel *label); void refreshContacts(QListView *listWidget); void executeStandardUITransaction(Tx tx); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e895947..4f0f08f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -50,6 +50,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->memoTxtChat->setAutoFillBackground(false); ui->memoTxtChat->setPlaceholderText("Send Message"); ui->memoTxtChat->setTextColor(Qt::white); + + // Status Bar setupStatusBar(); @@ -1053,7 +1055,7 @@ void MainWindow::setupchatTab() { - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); @@ -1078,45 +1080,16 @@ void MainWindow::setupchatTab() { }); - +ui->memoTxtChat->setLenDisplayLabel(ui->memoSize);// Todo -> activate lendisplay for chat } -ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { - QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); -} -void ChatMemoEdit::updateDisplay() { - QString txt = this->toPlainText(); - if (lenDisplayLabel) - lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); - - if (txt.toUtf8().size() <= maxlen) { - // Everything is fine - if (sendChatButton) - sendChatButton->setEnabled(true); - - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet(""); - } - else { - // Overweight - if (sendChatButton) - sendChatButton->setEnabled(false); - - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet("color: red;"); - } -} - -void ChatMemoEdit::setMaxLen(int len) { - this->maxlen = len; - updateDisplay(); -} void MainWindow::updateChat() { - rpc->refreshChat(ui->listChat); + rpc->refreshChat(ui->listChat,ui->memoSize); rpc->refresh(true); + } diff --git a/src/mainwindow.h b/src/mainwindow.h index 445e3f6..85f4feb 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -58,6 +58,8 @@ public: void stopWebsocket(); void saveContact(); void saveandsendContact(); + void setMaxLen(int len); + void updateDisplay(); void balancesReady(); @@ -108,7 +110,7 @@ private: void setuphushdTab(); void setupchatTab(); void renderContactRequest(); - void setLenDisplayLabel(QLabel* label); + // void setLenDisplayLabel(QLabel* label); void updateContacts(); void updateChat(); @@ -130,9 +132,11 @@ private: void cancelButton(); void sendButton(); - void sendChatButton(); + void sendChat(); void addContact(); void ContactRequest(); + + void addAddressSection(); void maxAmountChecked(int checked); @@ -171,6 +175,7 @@ private: WSServer* wsserver = nullptr; WormholeClient* wormhole = nullptr; + Controller* rpc = nullptr; QCompleter* labelCompleter = nullptr; @@ -182,15 +187,14 @@ private: QMovie* loadingMovie; }; -class ChatMemoEdit : public QPlainTextEdit +class ChatMemoEdit : public QTextEdit { public: ChatMemoEdit(QWidget* parent); void setMaxLen(int len); - - void setSendChatButton(QPushButton* button); - void includeReplyTo(QString replyToAddress); + void setLenDisplayLabel(QLabel* label); + void SetSendChatButton(QPushButton* button); void updateDisplay(); private: @@ -199,4 +203,5 @@ private: QPushButton* sendChatButton = nullptr; }; + #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1ce2a50..399e3e9 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1400,7 +1400,7 @@ <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> - + 340 @@ -1633,6 +1633,22 @@ true + + + + 1160 + 540 + 91 + 17 + + + + 0 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + @@ -1819,6 +1835,11 @@ QLabel

fillediconlabel.h
+ + ChatMemoEdit + QTextEdit +
mainwindow.h
+
Address1 From 747580151ac4999280391232d466b4d73a384692 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 21:32:45 +0200 Subject: [PATCH 122/253] change some gui elements --- src/Chat/Chat.cpp | 10 ++--- src/Chat/Helper/ChatDelegator.h | 2 +- src/DataStore/ChatDataStore.cpp | 1 + src/chatmodel.cpp | 4 +- src/controller.cpp | 2 +- src/mainwindow.cpp | 4 +- src/mainwindow.ui | 76 +++++++++++++++++++++++++++------ 7 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index d6c8445..30a827d 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -50,9 +50,6 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) { QStandardItemModel *chat = new QStandardItemModel(); - // ui->lcdNumber->setStyleSheet("background-color: red"); - // ui->lcdNumber->setPalette(Qt::red); - // ui->lcdNumber->display("1"); DataStore::getChatDataStore()->dump(); // test to see if the chat items in datastore are correctly dumped to json for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) { @@ -63,7 +60,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) if ( (p.getName() == ui->contactNameMemo->text().trimmed()) && (p.getPartnerAddress() == c.second.getAddress()) && - (c.second.isOutgoing() == true)) + (c.second.isOutgoing() == true)) { QStandardItem *Items = new QStandardItem(c.second.toChatLine()); @@ -81,8 +78,9 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) if ( (p.getName() == ui->contactNameMemo->text().trimmed()) && (p.getMyAddress() == c.second.getAddress()) && - (c.second.isOutgoing() == false)) - + (c.second.isOutgoing() == false) && + (c.second.getCid() == p.getCid()) + ) { QStandardItem *Items1 = new QStandardItem(c.second.toChatLine()); Items1->setData(INCOMING, Qt::UserRole + 1); diff --git a/src/Chat/Helper/ChatDelegator.h b/src/Chat/Helper/ChatDelegator.h index 6e3e676..10b45e5 100644 --- a/src/Chat/Helper/ChatDelegator.h +++ b/src/Chat/Helper/ChatDelegator.h @@ -37,7 +37,7 @@ class ListViewDelegate : public QAbstractItemDelegate inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; }; -inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.6) +inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(7), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) { } diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 1313103..21ddef9 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -96,6 +96,7 @@ std::map ChatDataStore::getAllMemos() (c.second.getMemo().startsWith("{") == false) && (c.second.getMemo().isEmpty() == false) + ) { diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 349f8be..28f7dfe 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -125,7 +125,7 @@ void MainWindow::renderContactRequest(){ requestContact.requestMemo->setModel(contactMemo); requestContact.requestMemo->show(); - + requestContact.requestCID->setText(c.second.getCid()); requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); }else{} @@ -617,7 +617,7 @@ Tx MainWindow::createTxForSafeContactRequest() QString hmemo= createHeaderMemo(type,cid,myAddr); QString memo = contactRequest.getMemo(); - // ui->memoSizeChat->setLenDisplayLabel();// Todo -> activate lendisplay for chat + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); diff --git a/src/controller.cpp b/src/controller.cpp index 8c3b603..d3c05fe 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1009,7 +1009,7 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); - chat->renderChatBox(ui, ui->listChat,ui->memoSize); + chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); // refreshContacts( // ui->listContactWidget diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4f0f08f..0e231f4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1080,14 +1080,14 @@ void MainWindow::setupchatTab() { }); -ui->memoTxtChat->setLenDisplayLabel(ui->memoSize);// Todo -> activate lendisplay for chat +ui->memoTxtChat->setLenDisplayLabel(ui->memoSizeChat); } void MainWindow::updateChat() { - rpc->refreshChat(ui->listChat,ui->memoSize); + rpc->refreshChat(ui->listChat,ui->memoSizeChat); rpc->refresh(true); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 399e3e9..2d85bd5 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1506,16 +1506,16 @@ - Qt::ScrollBarAlwaysOff + Qt::ScrollBarAsNeeded - Qt::ScrollBarAlwaysOff + Qt::ScrollBarAsNeeded QAbstractScrollArea::AdjustToContents - QAbstractItemView::NoEditTriggers + QAbstractItemView::AllEditTriggers QListView::Adjust @@ -1533,12 +1533,24 @@ - 270 - 580 + 10 + 20 51 51 + + + 51 + 51 + + + + + 51 + 51 + + 100 @@ -1569,12 +1581,24 @@ - 0 + 80 20 - 61 + 51 51 + + + 51 + 51 + + + + + 51 + 51 + + 100 @@ -1607,12 +1631,24 @@ - 70 + 150 20 - 61 + 51 51 + + + 51 + 51 + + + + + 51 + 51 + + Get a new Address @@ -1633,15 +1669,18 @@ true - + - 1160 - 540 + 1140 + 640 91 17 + + QFrame::Sunken + 0 / 512 @@ -1649,6 +1688,17 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + listContactWidget + label_39 + contactNameMemo + contactNameMemo_3 + safeContactRequest + pushContact + givemeZaddr + memoSizeChat + listChat + memoTxtChat + sendChatButton @@ -1838,7 +1888,7 @@ ChatMemoEdit QTextEdit -
mainwindow.h
+
mainwindow.h
From 1a36a7f3c404373dd63c44ff5d6377e9c5bb7918 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 21:44:21 +0200 Subject: [PATCH 123/253] try catch myZaddr --- src/addressbook.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index b557dd9..f51e279 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -144,22 +144,35 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) // Connect the dialog's closing to updating the label address completor QObject::connect(&d, &QDialog::finished, [=] (auto) { parent->updateLabels(); }); + Controller* rpc = parent->getRPC(); bool sapling = true; + try + { rpc->createNewZaddr(sapling, [=] (json reply) { QString myAddr = QString::fromStdString(reply.get()[0]); QString message = QString("New Chat Address for your partner: ") + myAddr; QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + + rpc->refreshAddresses(); parent->ui->listReceiveAddresses->insertItem(0, myAddr); parent->ui->listReceiveAddresses->setCurrentIndex(0); - qDebug() << "new generated myAddr" << myAddr; + qDebug() << " new Addr in Addressbook" << myAddr; ab.cid->setText(cid); ab.addr_chat->setText(myAddr); }); - model.updateUi(); //todo fix updating gui after adding - //rpc->refresh(true); + } + + catch(...) + { + + + qDebug() << QString("Caught something nasty with myZaddr Addressbook"); + } + + // model.updateUi(); //todo fix updating gui after adding // If there is a target then make it the addr for the "Add to" button if (target != nullptr && Settings::isValidAddress(target->text())) From eae77fb8aa8087f0fec0f4d0b8420373302b5d0c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 21 May 2020 22:19:31 +0200 Subject: [PATCH 124/253] fix windows icons --- application.qrc | 5 +- src/Model/ChatItem.cpp | 4 +- src/chatmodel.cpp | 2 + src/requestContactDialog.ui | 215 ++++++++++++++++++++++++------------ 4 files changed, 149 insertions(+), 77 deletions(-) diff --git a/application.qrc b/application.qrc index 7ab9af5..bf9a3b9 100644 --- a/application.qrc +++ b/application.qrc @@ -38,9 +38,8 @@ res/message-icon.svg res/lock.svg res/lock.png - res/lock_green.svg - res/lock_blue.svg - res/unlocked.svg + res/lock_green.png + res/unlocked.png res/getAddrWhite.png res/send-white.png res/requestWhite.png diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index 540c7ba..fff8f9a 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -137,10 +137,10 @@ QString ChatItem::toChatLine() myDateTime.setTime_t(_timestamp); if (_confirmations == 0){ - lock = " "; + lock = " "; }else{ - lock = " "; + lock = " "; } diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 28f7dfe..d3abd34 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -126,6 +126,7 @@ void MainWindow::renderContactRequest(){ requestContact.requestMemo->show(); requestContact.requestCID->setText(c.second.getCid()); + requestContact.requestCID->setVisible(false); requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); }else{} @@ -152,6 +153,7 @@ void MainWindow::renderContactRequest(){ requestContact.requestMemo->show(); requestContact.requestCID->setText(c.second.getCid()); + requestContact.requestCID->setVisible(false); requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); }else{} diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 7e676e7..2eb4bc0 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -6,38 +6,28 @@ 0 0 - 1025 - 562 + 812 + 495
+ + + 812 + 495 + + Incoming contact request - - + + - My Zaddr : + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> - - - - true - - - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - false - - - QAbstractItemView::SingleSelection - - - - + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> @@ -46,6 +36,12 @@ + + + 256 + 231 + + true @@ -60,18 +56,14 @@ - - - - - - - Give a Nickname: - - - - + + + + 521 + 231 + + Qt::ScrollBarAlwaysOff @@ -98,22 +90,112 @@ - - + + - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + 256 + 192 + + + + true + + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + QAbstractItemView::SingleSelection - + + + + Request from : + + + + + + + + 351 + 25 + + + + + 351 + 25 + + + + + + + + My Zaddr : + + + + + + + + 351 + 25 + + + + + 351 + 25 + + + + + + + + Give a Nickname: + + + + + + + + + + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + + + + + + + 106 + 25 + + + + + 106 + 25 + + Stag @@ -246,21 +328,14 @@ - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> - - - - - - - - - - + + + + 80 + 25 + + 100 @@ -278,8 +353,14 @@ - + + + + 153 + 25 + + Add this new Contact @@ -288,27 +369,17 @@ - - + + - Request from : + - - + + - <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> - - - - - - - - - - Cid : + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> From 200a7cfb6d233ada287e1339f086097376d854a2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 22 May 2020 19:15:56 +0200 Subject: [PATCH 125/253] set conf to 1 to send funds --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- src/controller.cpp | 16 ++++++++++------ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index b48d1b4..07f7981 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=e368816c6d12267f25fbebec0aaac4c15d62d2a3)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=e368816c6d12267f25fbebec0aaac4c15d62d2a3#e368816c6d12267f25fbebec0aaac4c15d62d2a3" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592#fb07cae93c706cce929beef98690109e5f2d7592" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=e368816c6d12267f25fbebec0aaac4c15d62d2a3)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 9784a1a..1d49baf 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "e368816c6d12267f25fbebec0aaac4c15d62d2a3" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "fb07cae93c706cce929beef98690109e5f2d7592" } diff --git a/src/controller.cpp b/src/controller.cpp index d3c05fe..8007205 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -140,7 +140,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) DataStore::getSietchDataStore()->clear(); // clears the datastore // Dust amt/memo, construct the JSON - for(uint8_t i = 0; i < 10; i++) + for(uint8_t i = 0; i < 8; i++) { dust.at(i)["amount"] = 0; dust.at(i)["memo"] = ""; @@ -166,9 +166,8 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) dust.at(3), dust.at(4), dust.at(5), - dust.at(6), - dust.at(7), - dust.at(8) + dust.at(6) + }) ; } @@ -305,6 +304,7 @@ void Controller::getInfoThenRefresh(bool force) QString chainName = Settings::getInstance()->isTestnet() ? "test" : "main"; main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")"); + // use currency ComboBox as input if (Settings::getInstance()->get_currency_name() == "USD") @@ -322,6 +322,8 @@ void Controller::getInfoThenRefresh(bool force) " $ " + (QLocale(QLocale::English).toString(cap,'f', 2)) ); + + } else if (Settings::getInstance()->get_currency_name() == "EUR") { @@ -614,7 +616,7 @@ void Controller::processUnspent(const json& reply, QMap* balan QString txid = QString::fromStdString(it["created_in_txid"]); CAmount amount = CAmount::fromqint64(it["value"].get()); - bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations + bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 1 confirmations bool pending = !it["unconfirmed_spent"].is_null(); unspentOutputs->push_back( @@ -648,7 +650,9 @@ void Controller::updateUIBalances() CAmount balAvailable = balT + balVerified; if (balZ < 0) balZ = CAmount::fromqint64(0); - + double price = (Settings::getInstance()->getBTCPrice() / 1000); + // ui->PriceMemo->setText(" The price of \n one HushChat \n Message is :\n BTC " + (QLocale(QLocale::English).toString(price, 'f',8)) + //+ " Messages left :" + ((balTotal.toDecimalhushString()) /0.0001) ); // Balances table ui->balSheilded->setText(balZ.toDecimalhushString()); ui->balVerified->setText(balVerified.toDecimalhushString()); From 4a5cb7f144ca7006edc5de59f01cd74f743944fa Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 22 May 2020 19:16:10 +0200 Subject: [PATCH 126/253] set a new version --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index f3c7693..875d8ab 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define APP_VERSION "1.2.2" +#define APP_VERSION "1.3-Chat-Alpha" From 29a86b852b62e02a59e0d689180f7852e5f68a01 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.com> Date: Fri, 22 May 2020 19:23:29 +0200 Subject: [PATCH 127/253] update// added clear --- src/Model/ContactRequest.cpp | 7 ++++++- src/Model/ContactRequest.h | 1 + src/chatmodel.cpp | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Model/ContactRequest.cpp b/src/Model/ContactRequest.cpp index 9741ba0..3ad804f 100644 --- a/src/Model/ContactRequest.cpp +++ b/src/Model/ContactRequest.cpp @@ -80,7 +80,7 @@ QString ContactRequest::toString() return "sender: " + _senderAddress + " receiver: " + _receiverAddress + " memo: " + _memo + " cid: " + _cid + " label: " + _label + " avatar: " + _avatar; } -ContactRequest::~ContactRequest() +void ContactRequest::clear() { _senderAddress = ""; _receiverAddress = ""; @@ -88,4 +88,9 @@ ContactRequest::~ContactRequest() _cid = ""; _label = ""; _avatar = ""; +} + +ContactRequest::~ContactRequest() +{ + clear(); } \ No newline at end of file diff --git a/src/Model/ContactRequest.h b/src/Model/ContactRequest.h index 5335434..930ad56 100644 --- a/src/Model/ContactRequest.h +++ b/src/Model/ContactRequest.h @@ -33,6 +33,7 @@ class ContactRequest void setLabel(QString label); void setAvatar(QString avatar); QString toString(); + void clear(); ~ContactRequest(); }; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index d3abd34..91e46d5 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -515,6 +515,7 @@ void MainWindow::saveandsendContact() QString myAddr = contactRequest.getSenderAddress(); QString cid = contactRequest.getCid(); QString avatar = contactRequest.getAvatar(); + contactRequest.clear(); if (addr.isEmpty() || newLabel.isEmpty()) { From fe8a52b9c7ed2c8bc55050fe52fda77a81825d2d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 23 May 2020 11:30:27 +0200 Subject: [PATCH 128/253] add crypto_generichash for pw --- src/mainwindow.cpp | 68 ++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0e231f4..9af5c43 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -22,6 +22,8 @@ #include "chatmodel.h" #include "requestdialog.h" #include "websockets.h" +#include "sodium.h" +#include "sodium/crypto_generichash_blake2b.h" #include using json = nlohmann::json; @@ -251,17 +253,23 @@ void MainWindow::closeEvent(QCloseEvent* event) { QMainWindow::closeEvent(event); } +void dump_hex_buff(unsigned char buf[], unsigned int len) +{ + int i; + for (i=0; igetModel()->getEncryptionStatus(); + /* auto encStatus = rpc->getModel()->getEncryptionStatus(); if (encStatus.first) { QMessageBox::information(this, tr("Wallet is already encrypted"), tr("Your wallet is already encrypted with a password.\nPlease use 'Remove Wallet Encryption' if you want to remove the wallet encryption."), QMessageBox::Ok ); return; - } + }*/ QDialog d(this); Ui_encryptionDialog ed; @@ -278,12 +286,13 @@ void MainWindow::encryptWallet() { ed.lblPasswordMatch->setText(tr("Passwords don't match")); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } + }; QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); - ed.txtPassword->setText(""); + /* ed.txtPassword->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); auto fnShowError = [=](QString title, const json& res) { @@ -291,32 +300,43 @@ void MainWindow::encryptWallet() { tr("Error was:\n") + QString::fromStdString(res.dump()), QMessageBox::Ok ); - }; + };*/ if (d.exec() == QDialog::Accepted) { - rpc->encryptWallet(ed.txtPassword->text(), [=](json res) { - if (isJsonResultSuccess(res)) { - // Save the wallet - rpc->saveWallet([=] (json reply) { - if (isJsonResultSuccess(reply)) { - QMessageBox::information(this, tr("Wallet Encrypted"), - tr("Your wallet was successfully encrypted! The password will be needed to send funds or export private keys."), - QMessageBox::Ok - ); - } else { - fnShowError(tr("Wallet Encryption Failed"), reply); - } - }); + QString str = ed.txtPassword->text(); // data comes from a db in my case + int length = str.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, str.toLocal8Bit(), length +1); + + #define MESSAGE ((const unsigned char *) sequence) + #define MESSAGE_LEN length + + + + qDebug()<<"Generating cryptographic key from password: " <refresh(true); - } else { - fnShowError(tr("Wallet Encryption Failed"), res); - } - }); - } } +} +//The following snippet demonstrates how to calculate the hash of a very long message using the init/update/final interface: + + + void MainWindow::removeWalletEncryption() { // Check if wallet is already encrypted auto encStatus = rpc->getModel()->getEncryptionStatus(); From 52f7a64417d74264a2d7f9cae9cd49d12041f423 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 23 May 2020 11:38:58 +0200 Subject: [PATCH 129/253] add qdebugs --- src/mainwindow.cpp | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9af5c43..128d4c8 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -261,15 +261,6 @@ void dump_hex_buff(unsigned char buf[], unsigned int len) } void MainWindow::encryptWallet() { - // Check if wallet is already encrypted - /* auto encStatus = rpc->getModel()->getEncryptionStatus(); - if (encStatus.first) { - QMessageBox::information(this, tr("Wallet is already encrypted"), - tr("Your wallet is already encrypted with a password.\nPlease use 'Remove Wallet Encryption' if you want to remove the wallet encryption."), - QMessageBox::Ok - ); - return; - }*/ QDialog d(this); Ui_encryptionDialog ed; @@ -292,18 +283,9 @@ void MainWindow::encryptWallet() { QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); - /* ed.txtPassword->setText(""); - ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); - - auto fnShowError = [=](QString title, const json& res) { - QMessageBox::critical(this, title, - tr("Error was:\n") + QString::fromStdString(res.dump()), - QMessageBox::Ok - ); - };*/ - if (d.exec() == QDialog::Accepted) { - QString str = ed.txtPassword->text(); // data comes from a db in my case + + QString str = ed.txtPassword->text(); // data comes from user inputs int length = str.length(); char *sequence = NULL; @@ -313,8 +295,6 @@ void MainWindow::encryptWallet() { #define MESSAGE ((const unsigned char *) sequence) #define MESSAGE_LEN length - - qDebug()<<"Generating cryptographic key from password: " < Date: Sat, 23 May 2020 12:21:49 +0200 Subject: [PATCH 130/253] debug password --- src/mainwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 128d4c8..42b511c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -295,10 +295,10 @@ void MainWindow::encryptWallet() { #define MESSAGE ((const unsigned char *) sequence) #define MESSAGE_LEN length - qDebug()<<"Generating cryptographic key from password: " < Date: Sat, 23 May 2020 12:44:13 +0200 Subject: [PATCH 131/253] encrypt addresslabels --- src/mainwindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 42b511c..9138c7c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -307,6 +307,11 @@ void MainWindow::encryptWallet() { qDebug()<<"secret key generated:\n"; dump_hex_buff(hash,crypto_secretstream_xchacha20poly1305_KEYBYTES); + + QString source_file = "/home/denio/.local/share/Hush/SilentDragonLite/addresslabel.dat"; + QString target_file = "/home/denio/.local/share/Hush/SilentDragonLite/addresslabel-encrypt.dat"; + + FileEncryption::encrypt(target_file, source_file, hash); d.exec(); From a72ba09ee3680741347fb9cd81efc7cdbbf9695a Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.found> Date: Sat, 23 May 2020 15:23:07 +0200 Subject: [PATCH 132/253] update// added some stuff --- .gdb_history | 6 ++++ peda-session-SilentDragonLite.txt | 2 +- silentdragon-lite.pro | 3 +- src/Crypto/FileEncryption.cpp | 48 +++++++++++++++++++------------ src/Crypto/FileEncryption.h | 6 ++++ src/Crypto/passwd.cpp | 39 +++++++++++++++++++++++++ src/Crypto/passwd.h | 14 +++++++++ src/FileSystem/FileSystem.cpp | 8 ++++++ 8 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 src/Crypto/passwd.cpp create mode 100644 src/Crypto/passwd.h diff --git a/.gdb_history b/.gdb_history index 4e303b8..06f6849 100644 --- a/.gdb_history +++ b/.gdb_history @@ -48,3 +48,9 @@ b FileSystem::writeContacts r n q +r +b FileEncryption::encrypt +r +s +n +q diff --git a/peda-session-SilentDragonLite.txt b/peda-session-SilentDragonLite.txt index f57fa7c..6f620bf 100644 --- a/peda-session-SilentDragonLite.txt +++ b/peda-session-SilentDragonLite.txt @@ -1,2 +1,2 @@ -break FileSystem::writeContacts +break FileEncryption::encrypt diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 86f38b0..7d3a281 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -83,7 +83,8 @@ SOURCES += \ src/Chat/Helper/ChatIDGenerator.cpp \ src/Chat/Chat.cpp \ src/FileSystem/FileSystem.cpp \ - src/Crypto/FileEncryption.cpp + src/Crypto/FileEncryption.cpp \ + src/Crypto/passwd.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/Crypto/FileEncryption.cpp b/src/Crypto/FileEncryption.cpp index 0100585..fae9bbc 100644 --- a/src/Crypto/FileEncryption.cpp +++ b/src/Crypto/FileEncryption.cpp @@ -7,42 +7,48 @@ void FileEncryption::showConfig() int FileEncryption::encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) { - unsigned char buf_in[FILEENCRYPTION_CHUNK_SIZE]; - unsigned char buf_out[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; + unsigned char plain_data[FILEENCRYPTION_CHUNK_SIZE]; + unsigned char cipher_data[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; - crypto_secretstream_xchacha20poly1305_state st; - FILE *fp_t, *fp_s; - unsigned long long out_len; + crypto_secretstream_xchacha20poly1305_state state; + FILE *target, *source; + unsigned long long cipher_len; size_t rlen; int eof; unsigned char tag; - fp_s = fopen(source_file.toStdString().c_str(), "rb"); - fp_t = fopen(target_file.toStdString().c_str(), "wb"); - crypto_secretstream_xchacha20poly1305_init_push(&st, header, key); - fwrite(header, 1, sizeof header, fp_t); + if(!FileEncryption::exists(source_file.toStdString())) + { + qDebug() << "File not exits" << source_file; + return -1; + } + + source = fopen(source_file.toStdString().c_str(), "rb"); + target = fopen(target_file.toStdString().c_str(), "wb"); + crypto_secretstream_xchacha20poly1305_init_push(&state, header, key); + fwrite(header, 1, sizeof header, target); do { - rlen = fread(buf_in, 1, sizeof buf_in, fp_s); - eof = feof(fp_s); + rlen = fread(plain_data, 1, sizeof plain_data, source); + eof = feof(source); tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0; crypto_secretstream_xchacha20poly1305_push( - &st, - buf_out, - &out_len, - buf_in, + &state, + cipher_data, + &cipher_len, + plain_data, rlen, NULL, 0, tag ); - fwrite(buf_out, 1, (size_t) out_len, fp_t); + fwrite(cipher_data, 1, (size_t) cipher_len, target); } while (! eof); - fclose(fp_t); - fclose(fp_s); + fclose(target); + fclose(source); return 0; } @@ -59,6 +65,12 @@ int FileEncryption::decrypt(QString target_file, QString source_file, const unsi int ret = -1; unsigned char tag; + if(!FileEncryption::exists(source_file.toStdString())) + { + qDebug() << "File not exits" << source_file; + return -1; + } + fp_s = fopen(source_file.toStdString().c_str(), "rb"); fp_t = fopen(target_file.toStdString().c_str(), "wb"); fread(header, 1, sizeof header, fp_s); diff --git a/src/Crypto/FileEncryption.h b/src/Crypto/FileEncryption.h index 6db8977..c7a09d5 100644 --- a/src/Crypto/FileEncryption.h +++ b/src/Crypto/FileEncryption.h @@ -3,11 +3,17 @@ #include #include #include +#include #define FILEENCRYPTION_CHUNK_SIZE 4096 class FileEncryption { + private: + inline static bool exists (const std::string& name) { + std::ifstream f(name.c_str()); + return f.good(); + } public: static void showConfig(); static int encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); diff --git a/src/Crypto/passwd.cpp b/src/Crypto/passwd.cpp new file mode 100644 index 0000000..83d5b27 --- /dev/null +++ b/src/Crypto/passwd.cpp @@ -0,0 +1,39 @@ +#include "passwd.h" + +void PASSWD::show_hex_buff(unsigned char buf[]) +{ + int i; + for (uint8_t i=0; i < crypto_secretstream_xchacha20poly1305_KEYBYTES; i++) + printf("%02X ", buf[i]); + printf("\n"); +} + +const unsigned char* PASSWD::hash(QString password) +{ + /*std::string data = password.toStdString(); + + unsigned char hash[crypto_generichash_BYTES]; + + crypto_generichash(hash, sizeof hash, + (const unsigned char*)data.c_str(), data.size(), + NULL, 0); + + //qDebug() << PASSWD::convertToHexString(hash); + return (const unsigned char*)hash;*/ + + int length = password.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, password.toLocal8Bit(), length +1); + + #define MESSAGE ((const unsigned char *) sequence) + #define MESSAGE_LEN length + + qDebug()<<"Generating cryptographic key from password: " < +#include +#include + +class PASSWD +{ + public: + static void show_hex_buff(unsigned char buf[]); + static const unsigned char* hash(QString); +}; + +#endif \ No newline at end of file diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index d560d98..74a0440 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -2,6 +2,7 @@ #include #include +#include "../Crypto/passwd.h" FileSystem::FileSystem() { @@ -85,6 +86,13 @@ void FileSystem::writeContactsOldFormat(QString file, QList contact QList FileSystem::readContactsOldFormat(QString file) { + const unsigned char* data=PASSWD::hash(QString("Hello world")); + PASSWD::show_hex_buff((unsigned char*) data); + QString source_file = "/tmp/addresslabels.dat"; + QString target_file = "/tmp/addresslabels.dat.enc"; + FileEncryption::encrypt(target_file, source_file, data); + FileEncryption::decrypt("/tmp/addresslabels.dat.dec", target_file, data); + QList contacts; QFile _file(file); if (_file.exists()) From 6c3065684798252946de771b340e9447ab55c293 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.found> Date: Sat, 23 May 2020 19:36:04 +0200 Subject: [PATCH 133/253] update// addedh better stuff --- src/Crypto/passwd.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Crypto/passwd.cpp b/src/Crypto/passwd.cpp index 83d5b27..160e631 100644 --- a/src/Crypto/passwd.cpp +++ b/src/Crypto/passwd.cpp @@ -31,8 +31,21 @@ const unsigned char* PASSWD::hash(QString password) #define MESSAGE_LEN length qDebug()<<"Generating cryptographic key from password: " < Date: Sat, 23 May 2020 19:50:36 +0200 Subject: [PATCH 134/253] update// added really goody stuff :D --- src/FileSystem/FileSystem.cpp | 7 ------ src/mainwindow.cpp | 46 ++++++++++++----------------------- 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 74a0440..2a60de1 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -86,13 +86,6 @@ void FileSystem::writeContactsOldFormat(QString file, QList contact QList FileSystem::readContactsOldFormat(QString file) { - const unsigned char* data=PASSWD::hash(QString("Hello world")); - PASSWD::show_hex_buff((unsigned char*) data); - QString source_file = "/tmp/addresslabels.dat"; - QString target_file = "/tmp/addresslabels.dat.enc"; - FileEncryption::encrypt(target_file, source_file, data); - FileEncryption::decrypt("/tmp/addresslabels.dat.dec", target_file, data); - QList contacts; QFile _file(file); if (_file.exists()) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9138c7c..a2566ad 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -25,6 +25,9 @@ #include "sodium.h" #include "sodium/crypto_generichash_blake2b.h" #include +#include "FileSystem/FileSystem.h" +#include "Crypto/passwd.h" +#include "Crypto/FileEncryption.h" using json = nlohmann::json; @@ -283,39 +286,20 @@ void MainWindow::encryptWallet() { QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); - if (d.exec() == QDialog::Accepted) { - - QString str = ed.txtPassword->text(); // data comes from user inputs - int length = str.length(); - - char *sequence = NULL; - sequence = new char[length+1]; - strncpy(sequence, str.toLocal8Bit(), length +1); + if (d.exec() == QDialog::Accepted) + { + const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); + PASSWD::show_hex_buff((unsigned char*) key); + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + QString source_file = dir.filePath("addresslabels.dat"); + QString target_enc_file = dir.filePath("addresslabels.dat.enc"); + QString target_dec_file = dir.filePath("addresslabels.dat.dec"); + FileEncryption::encrypt(target_enc_file, source_file, key); + FileEncryption::decrypt(target_dec_file, target_enc_file, key); - #define MESSAGE ((const unsigned char *) sequence) - #define MESSAGE_LEN length + d.exec(); - qDebug()<<"Generating cryptographic key from password: " < Date: Sat, 23 May 2020 20:43:42 +0200 Subject: [PATCH 135/253] gui element to decrypt --- src/mainwindow.cpp | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a2566ad..3fae23e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -293,18 +293,51 @@ void MainWindow::encryptWallet() { auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); QString source_file = dir.filePath("addresslabels.dat"); QString target_enc_file = dir.filePath("addresslabels.dat.enc"); - QString target_dec_file = dir.filePath("addresslabels.dat.dec"); + //QString target_dec_file = dir.filePath("addresslabels.dat.dec"); FileEncryption::encrypt(target_enc_file, source_file, key); - FileEncryption::decrypt(target_dec_file, target_enc_file, key); + // FileEncryption::decrypt(target_dec_file, target_enc_file, key); - d.exec(); + d.exec(); } } void MainWindow::removeWalletEncryption() { - // Check if wallet is already encrypted + QDialog d(this); + Ui_encryptionDialog ed; + ed.setupUi(&d); + + // Handle edits on the password box + auto fnPasswordEdited = [=](const QString&) { + // Enable the OK button if the passwords match. + if (!ed.txtPassword->text().isEmpty() && + ed.txtPassword->text() == ed.txtConfirmPassword->text()) { + ed.lblPasswordMatch->setText(""); + ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + } else { + ed.lblPasswordMatch->setText(tr("Passwords don't match")); + ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + } + + }; + + QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); + QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); + + if (d.exec() == QDialog::Accepted) + { + const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); + PASSWD::show_hex_buff((unsigned char*) key); + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + QString target_enc_file = dir.filePath("addresslabels.dat.enc"); + QString target_dec_file = dir.filePath("addresslabels.dat"); + FileEncryption::decrypt(target_dec_file, target_enc_file, key); + + d.exec(); + + } + /*// Check if wallet is already encrypted auto encStatus = rpc->getModel()->getEncryptionStatus(); if (!encStatus.first) { QMessageBox::information(this, tr("Wallet is not encrypted"), @@ -317,6 +350,8 @@ void MainWindow::removeWalletEncryption() { bool ok; QString password = QInputDialog::getText(this, tr("Wallet Password"), tr("Please enter your wallet password"), QLineEdit::Password, "", &ok); + + qDebug() << password; // If cancel was pressed, just return if (!ok) { @@ -356,7 +391,7 @@ void MainWindow::removeWalletEncryption() { QMessageBox::Ok ); } - }); + }); */ } void MainWindow::setupStatusBar() { From 5bb1634311768889640a34c9a5e3d8262dcd1b74 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 23 May 2020 21:27:46 +0200 Subject: [PATCH 136/253] check for fileencryption before sdl start --- src/mainwindow.cpp | 14 +++++++++++++- src/mainwindow.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3fae23e..08b0bf5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -56,7 +56,12 @@ MainWindow::MainWindow(QWidget *parent) : ui->memoTxtChat->setPlaceholderText("Send Message"); ui->memoTxtChat->setTextColor(Qt::white); - + + // Check for encryption + if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("addresslabels.dat.enc"))) + { + this->removeWalletEncryption(); + } // Status Bar setupStatusBar(); @@ -185,6 +190,12 @@ MainWindow::MainWindow(QWidget *parent) : createWebsocket(wormholecode); } } + +bool MainWindow::fileExists(QString path) +{ + QFileInfo check_file(path); + return (check_file.exists() && check_file.isFile()); +} void MainWindow::createWebsocket(QString wormholecode) { qDebug() << "Listening for app connections on port 8777"; @@ -332,6 +343,7 @@ void MainWindow::removeWalletEncryption() { auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); QString target_enc_file = dir.filePath("addresslabels.dat.enc"); QString target_dec_file = dir.filePath("addresslabels.dat"); + FileEncryption::decrypt(target_dec_file, target_enc_file, key); d.exec(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 85f4feb..9a6f02f 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -100,6 +100,7 @@ private slots: private: + bool fileExists(QString path); void closeEvent(QCloseEvent* event); From e4dce6b06bc0b892422505777834c16b2fd5323e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 23 May 2020 22:50:50 +0200 Subject: [PATCH 137/253] encrypt wallet.dat also and check for it - work in progress --- src/mainwindow.cpp | 125 ++++++++++++++++++++++----------------------- src/mainwindow.h | 1 + 2 files changed, 61 insertions(+), 65 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 08b0bf5..88b33dd 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -60,7 +60,7 @@ MainWindow::MainWindow(QWidget *parent) : // Check for encryption if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("addresslabels.dat.enc"))) { - this->removeWalletEncryption(); + this->removeWalletEncryptionStartUp(); } // Status Bar @@ -302,16 +302,16 @@ void MainWindow::encryptWallet() { const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); PASSWD::show_hex_buff((unsigned char*) key); auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString source_file = dir.filePath("addresslabels.dat"); QString target_enc_file = dir.filePath("addresslabels.dat.enc"); - //QString target_dec_file = dir.filePath("addresslabels.dat.dec"); + QString sourceWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); + QString target_encWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat.enc"); + FileEncryption::encrypt(target_enc_file, source_file, key); - // FileEncryption::decrypt(target_dec_file, target_enc_file, key); - - d.exec(); - + FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); } - + d.exec(); } void MainWindow::removeWalletEncryption() { @@ -341,69 +341,64 @@ void MainWindow::removeWalletEncryption() { const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); PASSWD::show_hex_buff((unsigned char*) key); auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - QString target_enc_file = dir.filePath("addresslabels.dat.enc"); - QString target_dec_file = dir.filePath("addresslabels.dat"); + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); + QString target_decaddr_file = dir.filePath("addresslabels.dat"); + QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat.enc"); + QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); - FileEncryption::decrypt(target_dec_file, target_enc_file, key); + + FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); + FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); - d.exec(); + } - /*// Check if wallet is already encrypted - auto encStatus = rpc->getModel()->getEncryptionStatus(); - if (!encStatus.first) { - QMessageBox::information(this, tr("Wallet is not encrypted"), - tr("Your wallet is not encrypted with a password."), - QMessageBox::Ok - ); - return; + d.exec(); +} + +void MainWindow::removeWalletEncryptionStartUp() { + QDialog d(this); + Ui_encryptionDialog ed; + ed.setupUi(&d); + + // Handle edits on the password box + auto fnPasswordEdited = [=](const QString&) { + // Enable the OK button if the passwords match. + if (!ed.txtPassword->text().isEmpty() && + ed.txtPassword->text() == ed.txtConfirmPassword->text()) { + ed.lblPasswordMatch->setText(""); + ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + } else { + ed.lblPasswordMatch->setText(tr("Passwords don't match")); + ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + } + + }; + + QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); + QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); + + if (d.exec() == QDialog::Accepted) + { + const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); + PASSWD::show_hex_buff((unsigned char*) key); + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); + QString target_decaddr_file = dir.filePath("addresslabels.dat"); + QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat.enc"); + QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); + + + FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); + QThread::sleep(1); + FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); + + + } - - bool ok; - QString password = QInputDialog::getText(this, tr("Wallet Password"), - tr("Please enter your wallet password"), QLineEdit::Password, "", &ok); - - qDebug() << password; - - // If cancel was pressed, just return - if (!ok) { - return; - } - - if (password.isEmpty()) { - QMessageBox::critical(this, tr("Wallet Decryption Failed"), - tr("Please enter a password to decrypt your wallet!"), - QMessageBox::Ok - ); - return; - } - - rpc->removeWalletEncryption(password, [=] (json res) { - if (isJsonResultSuccess(res)) { - // Save the wallet - rpc->saveWallet([=] (json reply) { - if(isJsonResultSuccess(reply)) { - QMessageBox::information(this, tr("Wallet Encryption Removed"), - tr("Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys."), - QMessageBox::Ok - ); - } else { - QMessageBox::critical(this, tr("Wallet Decryption Failed"), - QString::fromStdString(reply["error"].get()), - QMessageBox::Ok - ); - } - }); - - // And then refresh the UI - rpc->refresh(true); - } else { - QMessageBox::critical(this, tr("Wallet Decryption Failed"), - QString::fromStdString(res["error"].get()), - QMessageBox::Ok - ); - } - }); */ + } void MainWindow::setupStatusBar() { diff --git a/src/mainwindow.h b/src/mainwindow.h index 9a6f02f..7384fc2 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -130,6 +130,7 @@ private: void encryptWallet(); void removeWalletEncryption(); + void removeWalletEncryptionStartUp(); void cancelButton(); void sendButton(); From b03b926052cae5f9976e85b061b6dfce19b4b70f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 23 May 2020 23:13:58 +0200 Subject: [PATCH 138/253] new window for startup encryption process --- src/startupencryption.ui | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/startupencryption.ui diff --git a/src/startupencryption.ui b/src/startupencryption.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/src/startupencryption.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From 4ea9a5e493c3c598da152bf2a84cbd793675daf8 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 23 May 2020 23:14:17 +0200 Subject: [PATCH 139/253] new window for startup encryption process --- silentdragon-lite.pro | 1 + src/encryption.ui | 124 +++++++++++++++--------------- src/mainwindow.cpp | 3 +- src/startupencryption.ui | 158 +++++++++++++++++++++++++++++++++------ 4 files changed, 200 insertions(+), 86 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 7d3a281..4fe9ad0 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -133,6 +133,7 @@ FORMS += \ src/confirm.ui \ src/privkey.ui \ src/memodialog.ui \ + src/startupencryption.ui \ src/viewalladdresses.ui \ src/connection.ui \ src/addressbook.ui \ diff --git a/src/encryption.ui b/src/encryption.ui index b4ab606..27c25a0 100644 --- a/src/encryption.ui +++ b/src/encryption.ui @@ -13,7 +13,46 @@ Encrypt Your Wallet - + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your password, the only way to recover the wallet is from the seed phrase. If you dont have Backup your seed phrase, please do it now!</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -21,6 +60,19 @@ + + + + color: red; + + + Passwords don't match + + + Qt::AlignCenter + + + @@ -28,6 +80,13 @@ + + + + QLineEdit::Password + + + @@ -42,47 +101,14 @@ - - - - color: red; - - - Passwords don't match - - - Qt::AlignCenter - - - - - - - QLineEdit::Password - - - - + Qt::Horizontal - - - - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - - - Qt::AlignCenter - - - true - - - - + Qt::Horizontal @@ -95,32 +121,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 88b33dd..8985b3f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -21,6 +21,7 @@ #include "ui_requestContactDialog.h" #include "chatmodel.h" #include "requestdialog.h" +#include "ui_startupencryption.h" #include "websockets.h" #include "sodium.h" #include "sodium/crypto_generichash_blake2b.h" @@ -359,7 +360,7 @@ void MainWindow::removeWalletEncryption() { void MainWindow::removeWalletEncryptionStartUp() { QDialog d(this); - Ui_encryptionDialog ed; + Ui_startup ed; ed.setupUi(&d); // Handle edits on the password box diff --git a/src/startupencryption.ui b/src/startupencryption.ui index fb923db..6abdad1 100644 --- a/src/startupencryption.ui +++ b/src/startupencryption.ui @@ -1,10 +1,8 @@ - - - - - Dialog - - + + + startup + + 0 0 @@ -12,40 +10,155 @@ 300 - - Dialog + + SDL Startup Decryption - - + + - 30 - 240 + 50 + 260 341 32 - + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + 10 + 229 + 127 + 25 + + + + Confirm Password: + + + + + + 10 + 166 + 382 + 3 + + + + Qt::Horizontal + + + + + + 162 + 229 + 230 + 25 + + + + QLineEdit::Password + + + + + + 10 + 58 + 382 + 56 + + + + <html><head/><body><p>If you have forgotten your password, restore your wallet with your seed!</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + 10 + 260 + 382 + 3 + + + + Qt::Horizontal + + + + + + 10 + 198 + 146 + 25 + + + + Encryption Password: + + + + + + 10 + 175 + 382 + 17 + + + + color: red; + + + Passwords don't match + + + Qt::AlignCenter + + + + + + 162 + 198 + 230 + 25 + + + + QLineEdit::Password + + - buttonBox accepted() - Dialog + startup accept() - + 248 254 - + 157 274 @@ -54,14 +167,14 @@ buttonBox rejected() - Dialog + startup reject() - + 316 260 - + 286 274 @@ -69,4 +182,3 @@ - From e2d6cb01c6da3127aaf2964bf3d03bd01716c265 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 08:49:22 +0200 Subject: [PATCH 140/253] add startup check for encryption, encrypt if sdl close --- src/Crypto/passwd.cpp | 58 ++++++------ src/Crypto/passwd.h | 2 +- src/encryption.ui | 27 +++--- src/mainwindow.cpp | 205 +++++++++++++++++++++++++++++++++++------- 4 files changed, 226 insertions(+), 66 deletions(-) diff --git a/src/Crypto/passwd.cpp b/src/Crypto/passwd.cpp index 160e631..98996b0 100644 --- a/src/Crypto/passwd.cpp +++ b/src/Crypto/passwd.cpp @@ -8,19 +8,9 @@ void PASSWD::show_hex_buff(unsigned char buf[]) printf("\n"); } -const unsigned char* PASSWD::hash(QString password) +const unsigned char* PASSWD::key(QString password) { - /*std::string data = password.toStdString(); - - unsigned char hash[crypto_generichash_BYTES]; - - crypto_generichash(hash, sizeof hash, - (const unsigned char*)data.c_str(), data.size(), - NULL, 0); - - //qDebug() << PASSWD::convertToHexString(hash); - return (const unsigned char*)hash;*/ - + int length = password.length(); char *sequence = NULL; @@ -29,24 +19,42 @@ const unsigned char* PASSWD::hash(QString password) #define MESSAGE ((const unsigned char *) sequence) #define MESSAGE_LEN length + + unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_hash_sha256(hash, MESSAGE, MESSAGE_LEN); + + qDebug()<<"Generating SaltHash from password: " < Encrypt Your Wallet - + @@ -27,7 +27,7 @@ - + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your password, the only way to recover the wallet is from the seed phrase. If you dont have Backup your seed phrase, please do it now!</p></body></html> @@ -53,14 +53,21 @@ - + Qt::Horizontal - + + + + <html><head/><body><p>10 letters minimum</p></body></html> + + + + color: red; @@ -73,42 +80,42 @@ - + Encryption Password: - + QLineEdit::Password - + Confirm Password: - + QLineEdit::Password - + Qt::Horizontal - + Qt::Horizontal diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8985b3f..e7d175b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -36,6 +36,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { + // Include css QString theme_name; try @@ -53,17 +54,16 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); - ui->memoTxtChat->setAutoFillBackground(false); - ui->memoTxtChat->setPlaceholderText("Send Message"); - ui->memoTxtChat->setTextColor(Qt::white); - - - // Check for encryption - if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("addresslabels.dat.enc"))) + // Check for encryption + if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"))) { this->removeWalletEncryptionStartUp(); } + ui->memoTxtChat->setAutoFillBackground(false); + ui->memoTxtChat->setPlaceholderText("Send Message"); + ui->memoTxtChat->setTextColor(Qt::white); + // Status Bar setupStatusBar(); @@ -263,6 +263,69 @@ void MainWindow::closeEvent(QCloseEvent* event) { // Let the RPC know to shut down any running service. rpc->shutdownhushd(); + +// Check is encryption is ON for SDl + if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"))) + + { + + + // delete old file before + + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QFile file1(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); + file1.remove(); + + // Encrypt our wallet.dat + QString str = "123";///just for testing. We set the user pw here + // QString str = ed.txtPassword->text(); // data comes from user inputs + int length = str.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, str.toLocal8Bit(), length +1); + + #define MESSAGE ((const unsigned char *) sequence) + #define MESSAGE_LEN length + + unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN); + + #define PASSWORD sequence + #define KEY_LEN crypto_box_SEEDBYTES + + + + /////////we use the Hash of the Password as Salt, not perfect but still a good solution. + + unsigned char key[KEY_LEN]; + + if (crypto_pwhash + (key, sizeof key, PASSWORD, strlen(PASSWORD), hash, + crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE, + crypto_pwhash_ALG_DEFAULT) != 0) { + /* out of memory */ +} + + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + // auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QString source_file = dir.filePath("addresslabels.dat"); + QString target_enc_file = dir.filePath("addresslabels.dat.enc"); + QString sourceWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); + QString target_encWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); + + FileEncryption::encrypt(target_enc_file, source_file, key); + FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); + + } +///////////////// we rename the plaintext wallet.dat to Backup, for testing. + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QFile file1(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + file1.remove(); + QFile file(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + file.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + // Bubble up if (event) QMainWindow::closeEvent(event); @@ -282,14 +345,17 @@ void MainWindow::encryptWallet() { ed.setupUi(&d); // Handle edits on the password box + + auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. + QString password = ed.txtPassword->text(); if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text()) { + ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 10) { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { - ed.lblPasswordMatch->setText(tr("Passwords don't match")); + ed.lblPasswordMatch->setText(tr("Passwords don't match or You have entered too few letters (10 minimum)")); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } @@ -300,19 +366,49 @@ void MainWindow::encryptWallet() { if (d.exec() == QDialog::Accepted) { - const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); - PASSWD::show_hex_buff((unsigned char*) key); + + QString str = ed.txtPassword->text(); // data comes from user inputs + int length = str.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, str.toLocal8Bit(), length +1); + + #define MESSAGE ((const unsigned char *) sequence) + #define MESSAGE_LEN length + + unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN); + + #define PASSWORD sequence + #define KEY_LEN crypto_box_SEEDBYTES + + + + /////////we use the Hash of the Password as Salt, not perfect but still a good solution. + + unsigned char key[KEY_LEN]; + + if (crypto_pwhash + (key, sizeof key, PASSWORD, strlen(PASSWORD), hash, + crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE, + crypto_pwhash_ALG_DEFAULT) != 0) { + /* out of memory */ +} + + qDebug()<<"Generating cryptographic key from password: " <text()); - PASSWD::show_hex_buff((unsigned char*) key); + QString str = ed.txtPassword->text(); // data comes from user inputs + int length = str.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, str.toLocal8Bit(), length +1); + + #define MESSAGE ((const unsigned char *) sequence) + #define MESSAGE_LEN length + + unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN); + + #define PASSWORD sequence + #define KEY_LEN crypto_box_SEEDBYTES + + + + /////////we use the Hash of the Password as Salt, not perfect but still a good solution. + + unsigned char key[KEY_LEN]; + + if (crypto_pwhash + (key, sizeof key, PASSWORD, strlen(PASSWORD), hash, + crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE, + crypto_pwhash_ALG_DEFAULT) != 0) { + /* out of memory */ +} auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); QString target_decaddr_file = dir.filePath("addresslabels.dat"); - QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat.enc"); + QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); @@ -354,8 +477,7 @@ void MainWindow::removeWalletEncryption() { - } - d.exec(); + } } void MainWindow::removeWalletEncryptionStartUp() { @@ -367,11 +489,11 @@ void MainWindow::removeWalletEncryptionStartUp() { auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text()) { + ed.txtPassword->text() == ed.txtConfirmPassword->text()) { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { - ed.lblPasswordMatch->setText(tr("Passwords don't match")); + ed.lblPasswordMatch->setText(tr("Passwords don't match or under-lettered")); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } @@ -382,22 +504,45 @@ void MainWindow::removeWalletEncryptionStartUp() { if (d.exec() == QDialog::Accepted) { - const unsigned char* key=PASSWD::hash(ed.txtPassword->text()); - PASSWD::show_hex_buff((unsigned char*) key); + QString str = ed.txtPassword->text(); // data comes from user inputs + int length = str.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, str.toLocal8Bit(), length +1); + + #define MESSAGE ((const unsigned char *) sequence) + #define MESSAGE_LEN length + + unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_hash_sha256(hash,MESSAGE, MESSAGE_LEN); + + #define PASSWORD sequence + #define KEY_LEN crypto_box_SEEDBYTES + + + + /////////we use the Hash of the Password as Salt, not perfect but still a good solution. + + unsigned char key[KEY_LEN]; + + if (crypto_pwhash + (key, sizeof key, PASSWORD, strlen(PASSWORD), hash, + crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE, + crypto_pwhash_ALG_DEFAULT) != 0) { + /* out of memory */ + } auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); + QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); QString target_decaddr_file = dir.filePath("addresslabels.dat"); - QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat.enc"); - QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); - FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); - QThread::sleep(1); + // QThread::sleep(1); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); - - - } } From 833ed7fc97cf91d779b4c11d813b57f1cf2e8d7b Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 09:10:39 +0200 Subject: [PATCH 141/253] new gui elements for encryption --- src/removeencryption.ui | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/removeencryption.ui diff --git a/src/removeencryption.ui b/src/removeencryption.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/src/removeencryption.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From feb745457be289b60039095ba5e402ae18314a48 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 09:11:12 +0200 Subject: [PATCH 142/253] new gui elements for encryption --- silentdragon-lite.pro | 1 + src/encryption.ui | 10 +-- src/mainwindow.cpp | 39 +++++---- src/removeencryption.ui | 171 ++++++++++++++++++++++++++++++++++------ 4 files changed, 173 insertions(+), 48 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 4fe9ad0..89c9012 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -143,6 +143,7 @@ FORMS += \ src/requestContactDialog.ui \ src/newrecurring.ui \ src/requestdialog.ui \ + src/removeencryption.ui \ src/recurringmultiple.ui \ src/chatbubbleme.ui \ src/chatbubblepartner.ui diff --git a/src/encryption.ui b/src/encryption.ui index e0b3e2f..ae2643b 100644 --- a/src/encryption.ui +++ b/src/encryption.ui @@ -30,7 +30,7 @@ - <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your password, the only way to recover the wallet is from the seed phrase. If you dont have Backup your seed phrase, please do it now!</p></body></html> + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase the only way to recover the wallet is from the seed phrase. If you dont have Backup your seed phrase, please do it now!</p></body></html> Qt::AlignCenter @@ -63,7 +63,7 @@ - <html><head/><body><p>10 letters minimum</p></body></html> + <html><head/><body><p>16 letters minimum</p></body></html> @@ -73,7 +73,7 @@ color: red; - Passwords don't match + Passphrase don't match Qt::AlignCenter @@ -83,7 +83,7 @@ - Encryption Password: + Encryption Passphrase: @@ -97,7 +97,7 @@ - Confirm Password: + Confirm Passphrase: diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e7d175b..fd5be39 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -21,7 +21,8 @@ #include "ui_requestContactDialog.h" #include "chatmodel.h" #include "requestdialog.h" -#include "ui_startupencryption.h" +#include "ui_startupencryption.h" +#include "ui_removeencryption.h" #include "websockets.h" #include "sodium.h" #include "sodium/crypto_generichash_blake2b.h" @@ -268,18 +269,16 @@ void MainWindow::closeEvent(QCloseEvent* event) { if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"))) { - - // delete old file before auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QFile file1(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); - file1.remove(); + QFile fileoldencryption(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); + fileoldencryption.remove(); - // Encrypt our wallet.dat - QString str = "123";///just for testing. We set the user pw here - // QString str = ed.txtPassword->text(); // data comes from user inputs - int length = str.length(); + // Encrypt our wallet.dat + QString str = "123";///just for testing. We set the user pw here + // QString str = ed.txtPassword->text(); // data comes from user inputs + int length = str.length(); char *sequence = NULL; sequence = new char[length+1]; @@ -309,7 +308,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { } auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - // auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + // auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString source_file = dir.filePath("addresslabels.dat"); QString target_enc_file = dir.filePath("addresslabels.dat.enc"); QString sourceWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); @@ -318,14 +317,16 @@ void MainWindow::closeEvent(QCloseEvent* event) { FileEncryption::encrypt(target_enc_file, source_file, key); FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); - } -///////////////// we rename the plaintext wallet.dat to Backup, for testing. - auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QFile file1(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); - file1.remove(); + ///////////////// we rename the plaintext wallet.dat to Backup, for testing. + + QFile fileoldbackup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + fileoldbackup.remove(); QFile file(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); file.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + } + + // Bubble up if (event) QMainWindow::closeEvent(event); @@ -351,11 +352,11 @@ void MainWindow::encryptWallet() { // Enable the OK button if the passwords match. QString password = ed.txtPassword->text(); if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 10) { + ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { - ed.lblPasswordMatch->setText(tr("Passwords don't match or You have entered too few letters (10 minimum)")); + ed.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)")); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } @@ -413,7 +414,7 @@ void MainWindow::encryptWallet() { void MainWindow::removeWalletEncryption() { QDialog d(this); - Ui_encryptionDialog ed; + Ui_removeencryption ed; ed.setupUi(&d); // Handle edits on the password box @@ -475,8 +476,6 @@ void MainWindow::removeWalletEncryption() { FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); - - } } diff --git a/src/removeencryption.ui b/src/removeencryption.ui index fb923db..15f4f30 100644 --- a/src/removeencryption.ui +++ b/src/removeencryption.ui @@ -1,10 +1,8 @@ - - - - - Dialog - - + + + removeencryption + + 0 0 @@ -12,40 +10,168 @@ 300 - - Dialog + + Remove your Wallet encryption - - + + - 30 - 240 + 50 + 260 341 32 - + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + 260 + 170 + 133 + 23 + + + + <html><head/><body><p>16 letters minimum</p></body></html> + + + + + + 10 + 229 + 157 + 25 + + + + Confirm Passphrase: + + + + + + 10 + 164 + 382 + 3 + + + + Qt::Horizontal + + + + + + 173 + 229 + 219 + 25 + + + + QLineEdit::Password + + + + + + 10 + 56 + 382 + 56 + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If yo remove your encryption, all your Data is Plaintext on your Disk!</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + 10 + 260 + 382 + 3 + + + + Qt::Horizontal + + + + + + 10 + 198 + 157 + 25 + + + + Encryption Passphrase: + + + + + + 10 + 175 + 243 + 17 + + + + color: red; + + + Passphrase don't match + + + Qt::AlignCenter + + + + + + 173 + 198 + 219 + 25 + + + + QLineEdit::Password + + - buttonBox accepted() - Dialog + removeencryption accept() - + 248 254 - + 157 274 @@ -54,14 +180,14 @@ buttonBox rejected() - Dialog + removeencryption reject() - + 316 260 - + 286 274 @@ -69,4 +195,3 @@ - From c12a4ffe73ba0969d23b412403709cb33ec14459 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 09:39:50 +0200 Subject: [PATCH 143/253] use userpw for encryption at sdl close --- src/mainwindow.cpp | 15 ++++++++++++++- src/mainwindow.h | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fd5be39..5bb0740 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -276,7 +276,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { fileoldencryption.remove(); // Encrypt our wallet.dat - QString str = "123";///just for testing. We set the user pw here + QString str = this->getPassword(); // QString str = ed.txtPassword->text(); // data comes from user inputs int length = str.length(); @@ -351,6 +351,7 @@ void MainWindow::encryptWallet() { auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. QString password = ed.txtPassword->text(); + this->setPassword(password); if (!ed.txtPassword->text().isEmpty() && ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { ed.lblPasswordMatch->setText(""); @@ -546,6 +547,18 @@ void MainWindow::removeWalletEncryptionStartUp() { } +QString MainWindow::getPassword() +{ + + return _password; +} + +void MainWindow::setPassword(QString password) +{ + + _password = password; +} + void MainWindow::setupStatusBar() { // Status Bar loadingLabel = new QLabel(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 7384fc2..e80af01 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -51,6 +51,8 @@ public: QString doSendChatTxValidations(Tx tx); QString doSendRequestTxValidations(Tx tx); QString getCid(); + QString getPassword(); + void setPassword(QString Password); void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); @@ -120,6 +122,7 @@ private: void setupStatusBar(); void clearSendForm(); + QString _password; Tx createTxFromSendPage(); bool confirmTx(Tx tx, RecurringPaymentInfo* rpi); From 06b3f0370f9de519c5cc9e3cd9849eb098003a6d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 09:55:01 +0200 Subject: [PATCH 144/253] use userpw for encryption at sdl close --- src/mainwindow.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5bb0740..49f4f72 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -477,6 +477,9 @@ void MainWindow::removeWalletEncryption() { FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); + QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); + filencrypted.remove(); + } } @@ -486,6 +489,8 @@ void MainWindow::removeWalletEncryptionStartUp() { ed.setupUi(&d); // Handle edits on the password box + QString password = ed.txtPassword->text(); + auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. if (!ed.txtPassword->text().isEmpty() && @@ -506,7 +511,7 @@ void MainWindow::removeWalletEncryptionStartUp() { { QString str = ed.txtPassword->text(); // data comes from user inputs int length = str.length(); - + this->setPassword(str); char *sequence = NULL; sequence = new char[length+1]; strncpy(sequence, str.toLocal8Bit(), length +1); From 0071ee1f093ce4399c5fe6522485eeceb4356897 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 12:35:20 +0200 Subject: [PATCH 145/253] check for wrong password --- src/mainwindow.cpp | 75 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 49f4f72..ee93f6f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -466,21 +466,46 @@ void MainWindow::removeWalletEncryption() { crypto_pwhash_ALG_DEFAULT) != 0) { /* out of memory */ } - auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); - QString target_decaddr_file = dir.filePath("addresslabels.dat"); - QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); - QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); - - - FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); - FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); filencrypted.remove(); + { + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); + QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); + QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); + QString target_decaddr_file = dir.filePath("addresslabels.dat"); + + FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); + FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); + } + + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + + if (filencrypted.size() > 0) + { + + QMessageBox::information(this, tr("Wallet Encryption Success"), + QString("SDL is ready to Rock"), + QMessageBox::Ok + ); + }else{ + + qDebug()<<"verschlüsselung gescheitert "; + + QMessageBox::critical(this, tr("Wallet Encryption Failed"), + QString("false password please try again"), + QMessageBox::Ok + ); + this->removeWalletEncryptionStartUp(); + } + + } + } void MainWindow::removeWalletEncryptionStartUp() { @@ -532,12 +557,15 @@ void MainWindow::removeWalletEncryptionStartUp() { unsigned char key[KEY_LEN]; - if (crypto_pwhash + if (crypto_pwhash (key, sizeof key, PASSWORD, strlen(PASSWORD), hash, crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE, crypto_pwhash_ALG_DEFAULT) != 0) { /* out of memory */ } + + + { auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); @@ -546,8 +574,31 @@ void MainWindow::removeWalletEncryptionStartUp() { QString target_decaddr_file = dir.filePath("addresslabels.dat"); FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); - // QThread::sleep(1); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); + + } + + auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + + if (filencrypted.size() > 0) + { + + QMessageBox::information(this, tr("Wallet Encryption Success"), + QString("SDL is ready to Rock"), + QMessageBox::Ok + ); + }else{ + + qDebug()<<"verschlüsselung gescheitert "; + + QMessageBox::critical(this, tr("Wallet Encryption Failed"), + QString("false password please try again"), + QMessageBox::Ok + ); + this->removeWalletEncryptionStartUp(); + } + } } From d5138b8fa247a55635f67ca7ecabf86f01d42b4f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 13:15:57 +0200 Subject: [PATCH 146/253] prevent to open sdl without pw --- src/mainwindow.cpp | 73 +++++++++++++++++++++++++---------------- src/mainwindow.h | 2 ++ src/removeencryption.ui | 2 +- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ee93f6f..681391a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -252,6 +252,10 @@ void MainWindow::doClose() { closeEvent(nullptr); } +void MainWindow::doClosePw() { + closeEventpw(nullptr); +} + void MainWindow::closeEvent(QCloseEvent* event) { QSettings s; @@ -261,8 +265,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { s.sync(); - // Let the RPC know to shut down any running service. - rpc->shutdownhushd(); + // Check is encryption is ON for SDl @@ -318,27 +321,30 @@ void MainWindow::closeEvent(QCloseEvent* event) { FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); ///////////////// we rename the plaintext wallet.dat to Backup, for testing. - - QFile fileoldbackup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); - fileoldbackup.remove(); + QFile file(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); file.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); } - + // Let the RPC know to shut down any running service. + rpc->shutdownhushd(); // Bubble up if (event) QMainWindow::closeEvent(event); } -void dump_hex_buff(unsigned char buf[], unsigned int len) -{ - int i; - for (i=0; ishutdownhushd(); + + // Bubble up + if (event) + QMainWindow::closeEvent(event); } + void MainWindow::encryptWallet() { QDialog d(this); @@ -351,7 +357,7 @@ void MainWindow::encryptWallet() { auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. QString password = ed.txtPassword->text(); - this->setPassword(password); + if (!ed.txtPassword->text().isEmpty() && ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { ed.lblPasswordMatch->setText(""); @@ -371,6 +377,7 @@ void MainWindow::encryptWallet() { QString str = ed.txtPassword->text(); // data comes from user inputs int length = str.length(); + this->setPassword(str); char *sequence = NULL; sequence = new char[length+1]; @@ -399,8 +406,6 @@ void MainWindow::encryptWallet() { /* out of memory */ } - qDebug()<<"Generating cryptographic key from password: " <text(); auto fnPasswordEdited = [=](const QString&) { // Enable the OK button if the passwords match. if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text()) { + ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { @@ -466,11 +472,9 @@ void MainWindow::removeWalletEncryption() { crypto_pwhash_ALG_DEFAULT) != 0) { /* out of memory */ } + - QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); - filencrypted.remove(); - - { + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); @@ -481,29 +485,35 @@ void MainWindow::removeWalletEncryption() { FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); - } + - auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); if (filencrypted.size() > 0) { - QMessageBox::information(this, tr("Wallet Encryption Success"), + QMessageBox::information(this, tr("Wallet decryption Success"), QString("SDL is ready to Rock"), QMessageBox::Ok - ); + ); + + filencrypted.remove(); + }else{ qDebug()<<"verschlüsselung gescheitert "; QMessageBox::critical(this, tr("Wallet Encryption Failed"), - QString("false password please try again"), + QString("false password, please try again"), QMessageBox::Ok ); this->removeWalletEncryptionStartUp(); } + }else{ + + this->doClosePw(); } } @@ -514,12 +524,12 @@ void MainWindow::removeWalletEncryptionStartUp() { ed.setupUi(&d); // Handle edits on the password box - QString password = ed.txtPassword->text(); auto fnPasswordEdited = [=](const QString&) { + QString password = ed.txtPassword->text(); // Enable the OK button if the passwords match. if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text()) { + ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { @@ -580,6 +590,8 @@ void MainWindow::removeWalletEncryptionStartUp() { auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + if (filencrypted.size() > 0) { @@ -587,7 +599,9 @@ void MainWindow::removeWalletEncryptionStartUp() { QMessageBox::information(this, tr("Wallet Encryption Success"), QString("SDL is ready to Rock"), QMessageBox::Ok - ); + ); + + backup.remove(); }else{ qDebug()<<"verschlüsselung gescheitert "; @@ -599,8 +613,11 @@ void MainWindow::removeWalletEncryptionStartUp() { this->removeWalletEncryptionStartUp(); } + }else{ + + this->doClosePw(); } - + } QString MainWindow::getPassword() diff --git a/src/mainwindow.h b/src/mainwindow.h index e80af01..7ec42ba 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -88,6 +88,7 @@ public: Logger* logger; void doClose(); + void doClosePw(); QString createHeaderMemo(QString type, QString cid, QString zaddr, int version, int headerNumber); public slots: @@ -104,6 +105,7 @@ private: bool fileExists(QString path); void closeEvent(QCloseEvent* event); + void closeEventpw(QCloseEvent* event); void setupSendTab(); diff --git a/src/removeencryption.ui b/src/removeencryption.ui index 15f4f30..77d7239 100644 --- a/src/removeencryption.ui +++ b/src/removeencryption.ui @@ -181,7 +181,7 @@ buttonBox rejected() removeencryption - reject() + close() 316 From 79aecae12ea603fc29e02b7723e23d5978627392 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 13:25:12 +0200 Subject: [PATCH 147/253] rename to .backup at sdl end --- src/mainwindow.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 681391a..cd2bd34 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -266,7 +266,8 @@ void MainWindow::closeEvent(QCloseEvent* event) { s.sync(); - + // Let the RPC know to shut down any running service. + rpc->shutdownhushd(); // Check is encryption is ON for SDl if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"))) @@ -324,10 +325,10 @@ void MainWindow::closeEvent(QCloseEvent* event) { QFile file(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); file.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + } - // Let the RPC know to shut down any running service. - rpc->shutdownhushd(); + // Bubble up if (event) @@ -591,6 +592,7 @@ void MainWindow::removeWalletEncryptionStartUp() { auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + if (filencrypted.size() > 0) From 309c1acbcc5ac274b5893014f39a8e6f569d2694 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 15:24:06 +0200 Subject: [PATCH 148/253] some gui fixes --- src/mainwindow.cpp | 58 ++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cd2bd34..a8c5e03 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -323,10 +323,10 @@ void MainWindow::closeEvent(QCloseEvent* event) { ///////////////// we rename the plaintext wallet.dat to Backup, for testing. - QFile file(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); - file.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); - - + QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile address(dir.filePath("addresslabels.dat")); + wallet.remove(); + address.remove(); } @@ -416,6 +416,11 @@ void MainWindow::encryptWallet() { FileEncryption::encrypt(target_enc_file, source_file, key); FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); + + QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile address(dir.filePath("addresslabels.dat")); + wallet.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBackup")); + address.rename(dir.filePath("addresslabels.datBackup")); } } @@ -424,12 +429,11 @@ void MainWindow::removeWalletEncryption() { Ui_removeencryption ed; ed.setupUi(&d); - // Handle edits on the password box - QString password = ed.txtPassword->text(); - auto fnPasswordEdited = [=](const QString&) { + auto fnPasswordEdited = [=](const QString&) { + QString password = ed.txtPassword->text(); // Enable the OK button if the passwords match. if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { + ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { @@ -485,17 +489,15 @@ void MainWindow::removeWalletEncryption() { FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); - - - - QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); + QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); - if (filencrypted.size() > 0) + if (wallet.size() > 0) { QMessageBox::information(this, tr("Wallet decryption Success"), - QString("SDL is ready to Rock"), + QString("Successfully delete the encryption"), QMessageBox::Ok ); @@ -506,15 +508,12 @@ void MainWindow::removeWalletEncryption() { qDebug()<<"verschlüsselung gescheitert "; QMessageBox::critical(this, tr("Wallet Encryption Failed"), - QString("false password, please try again"), + QString("False password, please try again"), QMessageBox::Ok ); - this->removeWalletEncryptionStartUp(); + this->removeWalletEncryption(); } - }else{ - - this->doClosePw(); } } @@ -590,20 +589,29 @@ void MainWindow::removeWalletEncryptionStartUp() { } auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); - QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP")); + QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + //QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP"));*/ - - - if (filencrypted.size() > 0) + if (wallet.size() > 0) { + if (fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup"))) + + { + + QMessageBox::warning(this, tr("You have still Plaintextdata on your disk!"), + QString("WARNING: Delete it only if you have a backup of your Wallet Seed."), + QMessageBox::Ok + ); + // backup.remove(); + + } QMessageBox::information(this, tr("Wallet Encryption Success"), QString("SDL is ready to Rock"), QMessageBox::Ok ); - backup.remove(); + }else{ qDebug()<<"verschlüsselung gescheitert "; From c79bf0046d8dd0e5e6b3bdb4b8f03519b1f76f36 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 16:51:55 +0200 Subject: [PATCH 149/253] fix for win --- src/mainwindow.cpp | 54 ++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a8c5e03..1f16a60 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -33,6 +33,19 @@ using json = nlohmann::json; + + +#ifdef Q_OS_WIN +auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat"); +auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet-enc.dat"); +auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.datBackup"); +#endif +#ifdef Q_OS_UNIX +auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.dat"); +auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); +auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup"); +#endif + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -56,7 +69,10 @@ MainWindow::MainWindow(QWidget *parent) : logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log")); // Check for encryption - if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"))) + + + + if(fileExists(dirwalletenc)) { this->removeWalletEncryptionStartUp(); } @@ -270,13 +286,13 @@ void MainWindow::closeEvent(QCloseEvent* event) { rpc->shutdownhushd(); // Check is encryption is ON for SDl - if(fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"))) + if(fileExists(dirwalletenc)) { // delete old file before - auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QFile fileoldencryption(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); + //auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); + QFile fileoldencryption(dirwalletenc); fileoldencryption.remove(); // Encrypt our wallet.dat @@ -315,15 +331,15 @@ void MainWindow::closeEvent(QCloseEvent* event) { // auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString source_file = dir.filePath("addresslabels.dat"); QString target_enc_file = dir.filePath("addresslabels.dat.enc"); - QString sourceWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); - QString target_encWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); + QString sourceWallet_file = dirwallet; + QString target_encWallet_file = dirwalletenc; FileEncryption::encrypt(target_enc_file, source_file, key); FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); ///////////////// we rename the plaintext wallet.dat to Backup, for testing. - QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile wallet(dirwallet); QFile address(dir.filePath("addresslabels.dat")); wallet.remove(); address.remove(); @@ -411,15 +427,15 @@ void MainWindow::encryptWallet() { auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); QString source_file = dir.filePath("addresslabels.dat"); QString target_enc_file = dir.filePath("addresslabels.dat.enc"); - QString sourceWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); - QString target_encWallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); + QString sourceWallet_file = dirwallet; + QString target_encWallet_file = dirwalletenc; FileEncryption::encrypt(target_enc_file, source_file, key); FileEncryption::encrypt(target_encWallet_file, sourceWallet_file, key); - QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile wallet(dirwallet); QFile address(dir.filePath("addresslabels.dat")); - wallet.rename(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBackup")); + wallet.rename(dirwalletbackup); address.rename(dir.filePath("addresslabels.datBackup")); } } @@ -482,16 +498,16 @@ void MainWindow::removeWalletEncryption() { auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); - QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); + QString target_encwallet_file = dirwalletenc; + QString target_decwallet_file = dirwallet; QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); QString target_decaddr_file = dir.filePath("addresslabels.dat"); FileEncryption::decrypt(target_decwallet_file, target_encwallet_file, key); FileEncryption::decrypt(target_decaddr_file, target_encaddr_file, key); - QFile filencrypted(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat")); - QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile filencrypted(dirwalletenc); + QFile wallet(dirwallet); if (wallet.size() > 0) { @@ -578,8 +594,8 @@ void MainWindow::removeWalletEncryptionStartUp() { { auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QString target_encwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); - QString target_decwallet_file = dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat"); + QString target_encwallet_file = dirwalletenc; + QString target_decwallet_file = dirwallet; QString target_encaddr_file = dir.filePath("addresslabels.dat.enc"); QString target_decaddr_file = dir.filePath("addresslabels.dat"); @@ -589,12 +605,12 @@ void MainWindow::removeWalletEncryptionStartUp() { } auto dirHome = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - QFile wallet(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.dat")); + QFile wallet(dirwallet); //QFile backup(dirHome.filePath(".silentdragonlite/silentdragonlite-wallet.datBACKUP"));*/ if (wallet.size() > 0) { - if (fileExists(QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup"))) + if (fileExists(dirwalletbackup)) { From f9d89197532053729c0cd237ca3cf8d0003ea26e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 24 May 2020 20:55:56 +0200 Subject: [PATCH 150/253] rename of chatmemoedit --- src/Chat/Chat.cpp | 34 ++++++++++++++++++---------------- src/chatmodel.cpp | 1 - src/mainwindow.cpp | 2 +- src/mainwindow.h | 14 +++++++------- src/memodialog.ui | 2 +- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index 30a827d..f76222d 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -7,43 +7,43 @@ Chat::Chat() {} ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QTextEdit(parent) { - QObject::connect(this, &QTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); + QObject::connect(this, &QTextEdit::textChanged, this, &ChatMemoEdit::updateDisplayChat); } -void ChatMemoEdit::updateDisplay() { +void ChatMemoEdit::updateDisplayChat() { QString txt = this->toPlainText(); - if (lenDisplayLabel) - lenDisplayLabel->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlen)); + if (lenDisplayLabelchat) + lenDisplayLabelchat->setText(QString::number(txt.toUtf8().size()) + "/" + QString::number(maxlenchat)); - if (txt.toUtf8().size() <= maxlen) { + if (txt.toUtf8().size() <= maxlenchat) { // Everything is fine if (sendChatButton) sendChatButton->setEnabled(true); - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet(""); + if (lenDisplayLabelchat) + lenDisplayLabelchat->setStyleSheet(""); } else { // Overweight if (sendChatButton) sendChatButton->setEnabled(false); - if (lenDisplayLabel) - lenDisplayLabel->setStyleSheet("color: red;"); + if (lenDisplayLabelchat) + lenDisplayLabelchat->setStyleSheet("color: red;"); } } -void ChatMemoEdit::setMaxLen(int len) { - this->maxlen = len; - updateDisplay(); +void ChatMemoEdit::setMaxLenChat(int len) { + this->maxlenchat = len; + updateDisplayChat(); } void ChatMemoEdit::SetSendChatButton(QPushButton* button) { this->sendChatButton = button; } -void ChatMemoEdit::setLenDisplayLabel(QLabel* label) { - this->lenDisplayLabel = label; +void ChatMemoEdit::setLenDisplayLabelChat(QLabel* label) { + this->lenDisplayLabelchat = label; } void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) @@ -93,5 +93,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) ui->listChat->setModel(chat); } } - } -} \ No newline at end of file + } +} + + \ No newline at end of file diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 91e46d5..0e636b2 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -8,7 +8,6 @@ #include "ui_mainwindow.h" #include "ui_requestContactDialog.h" #include "addressbook.h" -#include "ui_memodialog.h" #include "ui_contactrequest.h" #include #include diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1f16a60..4f6c428 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1365,7 +1365,7 @@ void MainWindow::setupchatTab() { }); -ui->memoTxtChat->setLenDisplayLabel(ui->memoSizeChat); +ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 7ec42ba..fb08fdb 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -60,8 +60,8 @@ public: void stopWebsocket(); void saveContact(); void saveandsendContact(); - void setMaxLen(int len); - void updateDisplay(); + // void setmaxlenChat(int len); + // void updateDisplay(); void balancesReady(); @@ -199,14 +199,14 @@ class ChatMemoEdit : public QTextEdit public: ChatMemoEdit(QWidget* parent); - void setMaxLen(int len); - void setLenDisplayLabel(QLabel* label); + void setMaxLenChat(int len); + void setLenDisplayLabelChat(QLabel* label); void SetSendChatButton(QPushButton* button); - void updateDisplay(); + void updateDisplayChat(); private: - int maxlen = 512; - QLabel* lenDisplayLabel = nullptr; + int maxlenchat = 512; + QLabel* lenDisplayLabelchat = nullptr; QPushButton* sendChatButton = nullptr; }; diff --git a/src/memodialog.ui b/src/memodialog.ui index 1c144e0..d365221 100644 --- a/src/memodialog.ui +++ b/src/memodialog.ui @@ -74,7 +74,7 @@ MemoEdit QPlainTextEdit -
memoedit.h
+
memoedit.h
From 68b509f7a6ae91904d9b8f79cfd33890740b35c3 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 25 May 2020 10:13:49 +0200 Subject: [PATCH 151/253] update deps --- lib/Cargo.lock | 841 ++++++++++++++++++++++++------------------------- lib/Cargo.toml | 2 +- 2 files changed, 419 insertions(+), 424 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 07f7981..3c95032 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -56,7 +56,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayref" -version = "0.3.6" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -66,31 +66,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "async-stream" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "async-stream-impl" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "async-trait" -version = "0.1.24" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -98,19 +98,14 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "autocfg" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "backtrace" -version = "0.3.43" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -119,8 +114,8 @@ name = "backtrace-sys" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -143,7 +138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bech32" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -152,14 +147,14 @@ version = "0.1.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2s_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "group 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -176,22 +171,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "blake2b_simd" -version = "0.5.10" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "blake2s_simd" -version = "0.5.10" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -226,12 +221,12 @@ name = "bs58" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bumpalo" -version = "3.1.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -255,7 +250,7 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.4" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -268,7 +263,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.50" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -281,8 +276,8 @@ name = "chrono" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -296,21 +291,21 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "core-foundation" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core-foundation-sys" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -328,10 +323,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-utils" -version = "0.7.0" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -381,14 +375,14 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dtoa" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -401,7 +395,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -410,9 +404,9 @@ name = "failure_derive" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -436,9 +430,9 @@ name = "ff_derive" version = "0.3.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ - "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -450,7 +444,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -467,8 +461,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -483,9 +477,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -514,15 +508,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-channel" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -531,26 +525,26 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-sink" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-task" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-util" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -564,12 +558,12 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.14" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -578,26 +572,26 @@ version = "0.1.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "h2" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -619,10 +613,10 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -644,9 +638,9 @@ name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -654,7 +648,7 @@ name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -668,38 +662,38 @@ name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hyper" -version = "0.13.2" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "indexmap" -version = "1.3.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -707,7 +701,7 @@ name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -720,20 +714,20 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.5" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "js-sys" -version = "0.3.35" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "json" -version = "0.12.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -752,7 +746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.70" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -771,8 +765,8 @@ name = "libsodium-sys" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -817,13 +811,13 @@ dependencies = [ "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -837,12 +831,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.3.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "miniz_oxide" -version = "0.3.6" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -858,7 +852,7 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -883,7 +877,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -918,7 +912,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -927,44 +921,44 @@ name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-bigint" -version = "0.2.6" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.42" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.11" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num_cpus" -version = "1.12.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -990,7 +984,7 @@ name = "ordered-float" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1018,7 +1012,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1036,7 +1030,7 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "1.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1045,30 +1039,30 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project" -version = "0.4.8" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-internal" -version = "0.4.8" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-lite" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1096,7 +1090,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.8" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1107,7 +1101,7 @@ name = "prost" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1116,7 +1110,7 @@ name = "prost-build" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1135,9 +1129,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1145,30 +1139,30 @@ name = "prost-types" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "protobuf" -version = "2.10.1" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "protobuf-codegen" -version = "2.10.1" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "protobuf-codegen-pure" -version = "2.10.1" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf-codegen 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1176,13 +1170,13 @@ name = "qtlib" version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30)", ] [[package]] name = "quick-error" -version = "1.2.3" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1198,7 +1192,7 @@ name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1207,7 +1201,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1221,11 +1215,11 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1268,7 +1262,7 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1300,7 +1294,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1312,7 +1306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1323,7 +1317,7 @@ name = "rand_os" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1375,12 +1369,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "redox_users" -version = "0.3.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1393,15 +1388,15 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.11" +version = "0.16.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1422,13 +1417,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rust-argon2" -version = "0.7.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1438,7 +1432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rust-embed-impl 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1448,8 +1442,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1457,7 +1451,7 @@ name = "rust-embed-utils" version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1475,25 +1469,25 @@ dependencies = [ [[package]] name = "rustls" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustls-native-certs" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1503,10 +1497,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" -version = "1.0.6" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1528,7 +1522,7 @@ name = "sct" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1537,26 +1531,28 @@ name = "secp256k1" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "security-framework" -version = "0.3.4" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "security-framework-sys" -version = "0.3.3" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1591,17 +1587,17 @@ name = "serde_derive" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.46" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1611,7 +1607,7 @@ name = "serde_yaml" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1619,7 +1615,7 @@ dependencies = [ [[package]] name = "sha2" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1634,13 +1630,13 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592#fb07cae93c706cce929beef98690109e5f2d7592" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30#91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -1650,7 +1646,7 @@ dependencies = [ "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "json 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "json 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1658,20 +1654,20 @@ dependencies = [ "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", "ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-embed 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tonic 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_client_backend 0.0.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "zcash_primitives 0.0.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -1697,7 +1693,7 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1707,7 +1703,7 @@ name = "sodiumoxide" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "libsodium-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1744,10 +1740,10 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.14" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1757,9 +1753,9 @@ name = "synstructure" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1774,7 +1770,7 @@ version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1785,8 +1781,8 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1797,7 +1793,7 @@ name = "thread-id" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1807,7 +1803,7 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1823,95 +1819,95 @@ dependencies = [ "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio" -version = "0.2.11" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-macros" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-rustls" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-util" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tonic" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tower 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-futures 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1919,18 +1915,18 @@ name = "tonic-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tower" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1947,20 +1943,20 @@ name = "tower-balance" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-ready-cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1968,12 +1964,12 @@ name = "tower-buffer" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1981,8 +1977,8 @@ name = "tower-discover" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1996,9 +1992,9 @@ name = "tower-limit" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2008,10 +2004,10 @@ name = "tower-load" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2021,8 +2017,8 @@ name = "tower-load-shed" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2032,7 +2028,7 @@ name = "tower-make" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2041,11 +2037,11 @@ name = "tower-ready-cache" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2054,9 +2050,9 @@ name = "tower-retry" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2071,8 +2067,8 @@ name = "tower-timeout" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2082,21 +2078,21 @@ name = "tower-util" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tracing" -version = "0.1.12" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2105,12 +2101,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tracing-core" -version = "0.1.9" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2118,11 +2114,11 @@ dependencies = [ [[package]] name = "tracing-futures" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2188,12 +2184,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.3.1" +version = "2.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2207,91 +2203,91 @@ dependencies = [ [[package]] name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen" -version = "0.2.58" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.58" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.58" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.58" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.58" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-webidl" -version = "0.2.58" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "web-sys" -version = "0.3.35" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webpki" -version = "0.21.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2300,7 +2296,7 @@ name = "webpki-roots" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2316,7 +2312,7 @@ name = "which" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2345,7 +2341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" -version = "0.1.3" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2370,7 +2366,7 @@ name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2386,13 +2382,13 @@ name = "zcash_client_backend" version = "0.0.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ - "bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen-pure 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf-codegen-pure 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_primitives 0.0.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", ] @@ -2403,8 +2399,8 @@ version = "0.0.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2s_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto_api_chachapoly 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2412,12 +2408,12 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2426,7 +2422,7 @@ version = "0.0.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2443,51 +2439,50 @@ dependencies = [ "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" -"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" -"checksum async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" -"checksum async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" -"checksum async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" +"checksum async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58982858be7540a465c790b95aaea6710e5139bf8956b1d1344d014fa40100b0" +"checksum async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393356ed99aa7bff0ac486dde592633b83ab02bd254d8c209d5b9f1d0f533480" +"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" +"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" -"checksum bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c" +"checksum bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0089c35ab7c6f2bc55ab23f769913f0ac65b1023e7e74638a1f43128dd5df2" "checksum bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)" = "" "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -"checksum blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" +"checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" +"checksum blake2s_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "050efd7a5bdb220988d4c5204f84ab796e778612af94275f1d39479798b39cf9" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" "checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" -"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" +"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" +"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" +"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" +"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" +"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" -"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum crypto_api 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f855e87e75a4799e18b8529178adcde6fd4f97c1449ff4821e747ff728bb102" "checksum crypto_api_chachapoly 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95b2ad7cab08fd71addba81df5077c49df208effdfb3118a1519f9cdeac5aaf2" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" +"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" @@ -2503,35 +2498,35 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures-channel 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c92c2137e8e1ebf1ac99453550ab46eb4f35c5c53476d57d75eb782fb4d71e84" -"checksum futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ccfb301b0b09e940a67376cf40d1b0ac4db9366ee737f65c02edea225057e91e" +"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" +"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0485279d763e8a3669358f500e805339138b7bbe90f5718c80eedfdcb2ea36a4" -"checksum futures-task 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cefffab2aacc73845afd3f202e09fc775a55e2e96f46c8b1a46c117ae1c126ca" -"checksum futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c3f8c59707f898b8b6f0b54c2aef5408ae90a560b7bf0fbf1b95b3c652b0171" +"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" +"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" +"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" "checksum group 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)" = "" -"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" +"checksum h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" +"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -"checksum hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" -"checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" +"checksum hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14" +"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" -"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" -"checksum json 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a38661a28126f8621fb246611288ae28935ddf180f5e21f2d0fbfe5e4131dbe" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "367647c532db6f1555d7151e619540ec5f713328235b8c062c6b4f63e84adfe3" +"checksum json 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3ca41abbeb7615d56322a984e63be5e5d0a117dfaca86c14393e32a762ccac1" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +"checksum libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" "checksum libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" "checksum libsodium-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1c344ff12b90ef8fa1f0fffacd348c1fd041db331841fec9eab23fdb991f5e73" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" @@ -2540,8 +2535,8 @@ dependencies = [ "checksum log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" "checksum log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "100052474df98158c0738a7d3f4249c99978490178b5f9f68cd835ac57adbd1b" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" -"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" @@ -2550,10 +2545,10 @@ dependencies = [ "checksum multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" -"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" -"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" +"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" +"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" @@ -2562,28 +2557,28 @@ dependencies = [ "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" -"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" -"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" -"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" +"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" +"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" +"checksum pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" "checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" "checksum prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" "checksum prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" "checksum prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" -"checksum protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6686ddd96a8dbe2687b5f2a687b2cfb520854010ec480f2d74c32e7c9873d3c5" -"checksum protobuf-codegen 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6456421eecf7fc72905868cd760c3e35848ded3552e480cfe67726ed4dbd8d23" -"checksum protobuf-codegen-pure 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7cb42d5ab6073333be90208ab5ea6ab41c8f6803b35fd773a7572624cc15c9" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +"checksum protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20" +"checksum protobuf-codegen 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12c6abd78435445fc86898ebbd0521a68438063d4a73e23527b7134e6bf58b4a" +"checksum protobuf-codegen-pure 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c1646acda5319f5b28b0bff4a484324df43ddae2c0f5a3f3e63c0b26095cd600" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" @@ -2601,37 +2596,37 @@ dependencies = [ "checksum rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" +"checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)" = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" +"checksum ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" "checksum ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" "checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" -"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" +"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rust-embed 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b18893bdbdb0fa5bce588f5d7ab4afbd0678fc879d31535912bf39b7fbc062d6" "checksum rust-embed-impl 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50633968284cfc373661345fc6382e62b738079f045738023ebc5e445cf44357" "checksum rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97655158074ccb2d2cfb1ccb4c956ef0f4054e43a2c1e71146d4991e6961e105" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -"checksum rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51ffebdbb48c14f84eba0b715197d673aff1dd22cc1007ca647e28483bbcc307" +"checksum rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" +"checksum rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" -"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" "checksum secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0344a794ff109f85547039536028e12f313178ac1545e49fdf16a530d900a7b" -"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" -"checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" +"checksum security-framework 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" +"checksum security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" +"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" -"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" +"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" @@ -2641,7 +2636,7 @@ dependencies = [ "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" @@ -2649,13 +2644,13 @@ dependencies = [ "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" -"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" -"checksum tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" -"checksum tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc" -"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" -"checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48" +"checksum tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" +"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" +"checksum tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" +"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +"checksum tonic 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4afef9ce97ea39593992cf3fa00ff33b1ad5eb07665b31355df63a690e38c736" "checksum tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0436413ba71545bcc6c2b9a0f9d78d72deb0123c6a75ccdfe7c056f9930f5e52" -"checksum tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd3169017c090b7a28fce80abaad0ab4f5566423677c9331bb320af7e49cfe62" +"checksum tower 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b299df54795e6f72bca45063b5803d1f9a1ba9b11a3c7c64d0b84519b451fdd" "checksum tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a792277613b7052448851efcf98a2c433e6f1d01460832dc60bef676bc275d4c" "checksum tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4887dc2a65d464c8b9b66e0e4d51c2fd6cf5b3373afc72805b0a60bce00446a" "checksum tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6b5000c3c54d269cc695dff28136bb33d08cbf1df2c48129e143ab65bf3c2a" @@ -2669,10 +2664,10 @@ dependencies = [ "checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" "checksum tower-timeout 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "127b8924b357be938823eaaec0608c482d40add25609481027b96198b2e4b31e" "checksum tower-util 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5702d7890e35b2aae6ee420e8a762547505dbed30c075fbc84ec069a0aa18314" -"checksum tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" +"checksum tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6de6a8590a29d3f401eab60470c699efa0adf7b4f0352055bf24df2b69849b40" "checksum tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" -"checksum tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" -"checksum tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33848db47a7c848ab48b66aab3293cb9c61ea879a3586ecfcd17302fcea0baf1" +"checksum tracing-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d7fb511ac6ca1d031c5cfc26d8c38da9d88e91d2bd5b38b60cf8dc1b8b5c211f" +"checksum tracing-futures 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "107ae59580d2a1d994b6b965b16fe94c969fe86d3f7fd2572a1ee243bcaf7f09" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" @@ -2684,17 +2679,17 @@ dependencies = [ "checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" -"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" -"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" -"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" -"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" -"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" -"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" -"checksum webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "99de4b68939a880d530aed51289a7c7baee154e3ea8ac234b542c49da7134aaf" +"checksum wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "b58e66a093a7b7571cb76409763c495b8741ac4319ac20acc2b798f6766d92ee" +"checksum wasm-bindgen-macro 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "a80f89daea7b0a67b11f6e9f911422ed039de9963dce00048a653b63d51194bf" +"checksum wasm-bindgen-macro-support 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "4f9dbc3734ad6cff6b76b75b7df98c06982becd0055f651465a08f769bca5c61" +"checksum wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "d907984f8506b3554eab48b8efff723e764ddbf76d4cd4a3fe4196bc00c49a70" +"checksum wasm-bindgen-webidl 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "f85a3825a459cf6a929d03bacb54dca37a614d43032ad1343ef2d4822972947d" +"checksum web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "2fb60433d0dc12c803b9b017b3902d80c9451bab78d27bc3210bf2a7b96593f1" +"checksum webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e664e770ac0110e2384769bcc59ed19e329d81f555916a6e072714957b81b4" "checksum webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" @@ -2702,7 +2697,7 @@ dependencies = [ "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1d49baf..8bcf505 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "fb07cae93c706cce929beef98690109e5f2d7592" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30" } From 385f864d9d6990d0a9fac01b720aef0d22a04439 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 25 May 2020 21:25:13 +0200 Subject: [PATCH 152/253] change orange color --- application.qrc | 1 + lib/Cargo.lock | 841 +++++++++++++++++++++-------------------- lib/Cargo.toml | 2 +- src/Model/ChatItem.cpp | 34 +- src/Model/ChatItem.h | 7 +- src/controller.cpp | 61 ++- src/controller.h | 5 +- src/mainwindow.ui | 3 + 8 files changed, 521 insertions(+), 433 deletions(-) diff --git a/application.qrc b/application.qrc index 2db3887..e2da53c 100644 --- a/application.qrc +++ b/application.qrc @@ -39,6 +39,7 @@ res/lock.svg res/lock.png res/lock_green.png + res/lock_orange.png res/unlocked.png res/getAddrWhite.png res/send-white.png diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 3c95032..07f7981 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -56,7 +56,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayref" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -66,31 +66,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "async-stream" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "async-stream-impl" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "async-trait" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -98,14 +98,19 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" -version = "0.3.40" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -114,8 +119,8 @@ name = "backtrace-sys" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -138,7 +143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bech32" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -147,14 +152,14 @@ version = "0.1.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2s_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "group 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -171,22 +176,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "blake2b_simd" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "blake2s_simd" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -221,12 +226,12 @@ name = "bs58" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bumpalo" -version = "2.6.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -250,7 +255,7 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -263,7 +268,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -276,8 +281,8 @@ name = "chrono" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -291,21 +296,21 @@ dependencies = [ [[package]] name = "constant_time_eq" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "core-foundation" -version = "0.7.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core-foundation-sys" -version = "0.7.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -323,9 +328,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-utils" -version = "0.6.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -375,14 +381,14 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dtoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -395,7 +401,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -404,9 +410,9 @@ name = "failure_derive" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -430,9 +436,9 @@ name = "ff_derive" version = "0.3.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ - "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -444,7 +450,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -461,8 +467,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -477,9 +483,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -508,15 +514,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-channel" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -525,26 +531,26 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-sink" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-task" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-util" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -558,12 +564,12 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -572,26 +578,26 @@ version = "0.1.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "h2" -version = "0.2.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -613,10 +619,10 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -638,9 +644,9 @@ name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -648,7 +654,7 @@ name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -662,38 +668,38 @@ name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hyper" -version = "0.13.5" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "indexmap" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -701,7 +707,7 @@ name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -714,20 +720,20 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "js-sys" -version = "0.3.33" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "json" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -746,7 +752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.70" +version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -765,8 +771,8 @@ name = "libsodium-sys" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -811,13 +817,13 @@ dependencies = [ "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -831,12 +837,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "miniz_oxide" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -852,7 +858,7 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -877,7 +883,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -912,7 +918,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -921,44 +927,44 @@ name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-bigint" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num_cpus" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -984,7 +990,7 @@ name = "ordered-float" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1012,7 +1018,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1030,7 +1036,7 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.1.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1039,30 +1045,30 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-internal" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-lite" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1090,7 +1096,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.12" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1101,7 +1107,7 @@ name = "prost" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1110,7 +1116,7 @@ name = "prost-build" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1129,9 +1135,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1139,30 +1145,30 @@ name = "prost-types" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "protobuf" -version = "2.8.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "protobuf-codegen" -version = "2.8.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "protobuf-codegen-pure" -version = "2.8.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf-codegen 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1170,13 +1176,13 @@ name = "qtlib" version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)", ] [[package]] name = "quick-error" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1192,7 +1198,7 @@ name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1201,7 +1207,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1215,11 +1221,11 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1262,7 +1268,7 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1294,7 +1300,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1306,7 +1312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1317,7 +1323,7 @@ name = "rand_os" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1369,13 +1375,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "redox_users" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1388,15 +1393,15 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.12" +version = "0.16.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1417,12 +1422,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rust-argon2" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1432,7 +1438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rust-embed-impl 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1442,8 +1448,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1451,7 +1457,7 @@ name = "rust-embed-utils" version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1469,25 +1475,25 @@ dependencies = [ [[package]] name = "rustls" -version = "0.17.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustls-native-certs" -version = "0.3.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1497,10 +1503,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1522,7 +1528,7 @@ name = "sct" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1531,28 +1537,26 @@ name = "secp256k1" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "security-framework" -version = "0.4.4" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "security-framework-sys" -version = "0.4.3" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1587,17 +1591,17 @@ name = "serde_derive" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.44" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1607,7 +1611,7 @@ name = "serde_yaml" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1615,7 +1619,7 @@ dependencies = [ [[package]] name = "sha2" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1630,13 +1634,13 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30#91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592#fb07cae93c706cce929beef98690109e5f2d7592" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -1646,7 +1650,7 @@ dependencies = [ "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "json 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "json 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1654,20 +1658,20 @@ dependencies = [ "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", "ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-embed 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tonic 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_client_backend 0.0.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "zcash_primitives 0.0.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -1693,7 +1697,7 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1703,7 +1707,7 @@ name = "sodiumoxide" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "libsodium-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1740,10 +1744,10 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1753,9 +1757,9 @@ name = "synstructure" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1770,7 +1774,7 @@ version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1781,8 +1785,8 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1793,7 +1797,7 @@ name = "thread-id" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1803,7 +1807,7 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1819,95 +1823,95 @@ dependencies = [ "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio" -version = "0.2.21" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-macros" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-rustls" -version = "0.13.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-util" -version = "0.3.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tonic" -version = "0.2.1" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tower 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-futures 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1915,18 +1919,18 @@ name = "tonic-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tower" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1943,20 +1947,20 @@ name = "tower-balance" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-ready-cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1964,12 +1968,12 @@ name = "tower-buffer" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1977,8 +1981,8 @@ name = "tower-discover" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1992,9 +1996,9 @@ name = "tower-limit" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2004,10 +2008,10 @@ name = "tower-load" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2017,8 +2021,8 @@ name = "tower-load-shed" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2028,7 +2032,7 @@ name = "tower-make" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2037,11 +2041,11 @@ name = "tower-ready-cache" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2050,9 +2054,9 @@ name = "tower-retry" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2067,8 +2071,8 @@ name = "tower-timeout" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2078,21 +2082,21 @@ name = "tower-util" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tracing" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2101,12 +2105,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tracing-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2114,11 +2118,11 @@ dependencies = [ [[package]] name = "tracing-futures" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2184,12 +2188,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.2.9" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2203,91 +2207,91 @@ dependencies = [ [[package]] name = "wasi" -version = "0.7.0" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-webidl" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "web-sys" -version = "0.3.33" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "webpki" -version = "0.21.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2296,7 +2300,7 @@ name = "webpki-roots" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2312,7 +2316,7 @@ name = "which" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2341,7 +2345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2366,7 +2370,7 @@ name = "xattr" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2382,13 +2386,13 @@ name = "zcash_client_backend" version = "0.0.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ - "bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen-pure 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf-codegen-pure 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "zcash_primitives 0.0.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", ] @@ -2399,8 +2403,8 @@ version = "0.0.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2s_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto_api_chachapoly 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2408,12 +2412,12 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2422,7 +2426,7 @@ version = "0.0.0" source = "git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37#1a0204113d487cdaaf183c2967010e5214ff9e37" dependencies = [ "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", - "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ff 0.4.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", "pairing 0.14.2 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2439,50 +2443,51 @@ dependencies = [ "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" -"checksum async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58982858be7540a465c790b95aaea6710e5139bf8956b1d1344d014fa40100b0" -"checksum async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393356ed99aa7bff0ac486dde592633b83ab02bd254d8c209d5b9f1d0f533480" -"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" +"checksum async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" +"checksum async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" +"checksum async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" -"checksum bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0089c35ab7c6f2bc55ab23f769913f0ac65b1023e7e74638a1f43128dd5df2" +"checksum bech32 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c" "checksum bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)" = "" "checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" -"checksum blake2s_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "050efd7a5bdb220988d4c5204f84ab796e778612af94275f1d39479798b39cf9" +"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +"checksum blake2s_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" "checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" -"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" +"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" +"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" -"checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -"checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" +"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" -"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" +"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum crypto_api 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f855e87e75a4799e18b8529178adcde6fd4f97c1449ff4821e747ff728bb102" "checksum crypto_api_chachapoly 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95b2ad7cab08fd71addba81df5077c49df208effdfb3118a1519f9cdeac5aaf2" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" +"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" @@ -2498,35 +2503,35 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" +"checksum futures-channel 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c92c2137e8e1ebf1ac99453550ab46eb4f35c5c53476d57d75eb782fb4d71e84" +"checksum futures-core 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ccfb301b0b09e940a67376cf40d1b0ac4db9366ee737f65c02edea225057e91e" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" +"checksum futures-sink 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0485279d763e8a3669358f500e805339138b7bbe90f5718c80eedfdcb2ea36a4" +"checksum futures-task 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cefffab2aacc73845afd3f202e09fc775a55e2e96f46c8b1a46c117ae1c126ca" +"checksum futures-util 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c3f8c59707f898b8b6f0b54c2aef5408ae90a560b7bf0fbf1b95b3c652b0171" "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" -"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" +"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum group 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)" = "" -"checksum h2 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" +"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" +"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -"checksum hyper 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14" -"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" +"checksum hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" +"checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "367647c532db6f1555d7151e619540ec5f713328235b8c062c6b4f63e84adfe3" -"checksum json 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3ca41abbeb7615d56322a984e63be5e5d0a117dfaca86c14393e32a762ccac1" +"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" +"checksum json 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a38661a28126f8621fb246611288ae28935ddf180f5e21f2d0fbfe5e4131dbe" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" "checksum libsodium-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1c344ff12b90ef8fa1f0fffacd348c1fd041db331841fec9eab23fdb991f5e73" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" @@ -2535,8 +2540,8 @@ dependencies = [ "checksum log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" "checksum log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "100052474df98158c0738a7d3f4249c99978490178b5f9f68cd835ac57adbd1b" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" -"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" +"checksum memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" +"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" @@ -2545,10 +2550,10 @@ dependencies = [ "checksum multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" -"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" -"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" +"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" "checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" @@ -2557,28 +2562,28 @@ dependencies = [ "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" -"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" -"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" -"checksum pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f" +"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" +"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" "checksum prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" "checksum prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" "checksum prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" -"checksum protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20" -"checksum protobuf-codegen 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12c6abd78435445fc86898ebbd0521a68438063d4a73e23527b7134e6bf58b4a" -"checksum protobuf-codegen-pure 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c1646acda5319f5b28b0bff4a484324df43ddae2c0f5a3f3e63c0b26095cd600" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6686ddd96a8dbe2687b5f2a687b2cfb520854010ec480f2d74c32e7c9873d3c5" +"checksum protobuf-codegen 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6456421eecf7fc72905868cd760c3e35848ded3552e480cfe67726ed4dbd8d23" +"checksum protobuf-codegen-pure 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7cb42d5ab6073333be90208ab5ea6ab41c8f6803b35fd773a7572624cc15c9" +"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" +"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" @@ -2596,37 +2601,37 @@ dependencies = [ "checksum rand_xorshift 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" +"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum ring 0.16.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" +"checksum ring 0.16.11 (registry+https://github.com/rust-lang/crates.io-index)" = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" "checksum ripemd160 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" "checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" -"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" +"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" "checksum rust-embed 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b18893bdbdb0fa5bce588f5d7ab4afbd0678fc879d31535912bf39b7fbc062d6" "checksum rust-embed-impl 5.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50633968284cfc373661345fc6382e62b738079f045738023ebc5e445cf44357" "checksum rust-embed-utils 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97655158074ccb2d2cfb1ccb4c956ef0f4054e43a2c1e71146d4991e6961e105" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustls 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" -"checksum rustls-native-certs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" +"checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" +"checksum rustls-native-certs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51ffebdbb48c14f84eba0b715197d673aff1dd22cc1007ca647e28483bbcc307" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" -"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" +"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" "checksum secp256k1 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0344a794ff109f85547039536028e12f313178ac1545e49fdf16a530d900a7b" -"checksum security-framework 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" -"checksum security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" +"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" +"checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" +"checksum serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" -"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" +"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" @@ -2636,7 +2641,7 @@ dependencies = [ "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" @@ -2644,13 +2649,13 @@ dependencies = [ "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" -"checksum tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" -"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" -"checksum tokio-rustls 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" -"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" -"checksum tonic 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4afef9ce97ea39593992cf3fa00ff33b1ad5eb07665b31355df63a690e38c736" +"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" +"checksum tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" +"checksum tokio-rustls 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc" +"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +"checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48" "checksum tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0436413ba71545bcc6c2b9a0f9d78d72deb0123c6a75ccdfe7c056f9930f5e52" -"checksum tower 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b299df54795e6f72bca45063b5803d1f9a1ba9b11a3c7c64d0b84519b451fdd" +"checksum tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd3169017c090b7a28fce80abaad0ab4f5566423677c9331bb320af7e49cfe62" "checksum tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a792277613b7052448851efcf98a2c433e6f1d01460832dc60bef676bc275d4c" "checksum tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4887dc2a65d464c8b9b66e0e4d51c2fd6cf5b3373afc72805b0a60bce00446a" "checksum tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6b5000c3c54d269cc695dff28136bb33d08cbf1df2c48129e143ab65bf3c2a" @@ -2664,10 +2669,10 @@ dependencies = [ "checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" "checksum tower-timeout 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "127b8924b357be938823eaaec0608c482d40add25609481027b96198b2e4b31e" "checksum tower-util 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5702d7890e35b2aae6ee420e8a762547505dbed30c075fbc84ec069a0aa18314" -"checksum tracing 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6de6a8590a29d3f401eab60470c699efa0adf7b4f0352055bf24df2b69849b40" +"checksum tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" "checksum tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" -"checksum tracing-core 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d7fb511ac6ca1d031c5cfc26d8c38da9d88e91d2bd5b38b60cf8dc1b8b5c211f" -"checksum tracing-futures 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "107ae59580d2a1d994b6b965b16fe94c969fe86d3f7fd2572a1ee243bcaf7f09" +"checksum tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" +"checksum tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33848db47a7c848ab48b66aab3293cb9c61ea879a3586ecfcd17302fcea0baf1" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" @@ -2679,17 +2684,17 @@ dependencies = [ "checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" +"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "99de4b68939a880d530aed51289a7c7baee154e3ea8ac234b542c49da7134aaf" -"checksum wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "b58e66a093a7b7571cb76409763c495b8741ac4319ac20acc2b798f6766d92ee" -"checksum wasm-bindgen-macro 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "a80f89daea7b0a67b11f6e9f911422ed039de9963dce00048a653b63d51194bf" -"checksum wasm-bindgen-macro-support 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "4f9dbc3734ad6cff6b76b75b7df98c06982becd0055f651465a08f769bca5c61" -"checksum wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "d907984f8506b3554eab48b8efff723e764ddbf76d4cd4a3fe4196bc00c49a70" -"checksum wasm-bindgen-webidl 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "f85a3825a459cf6a929d03bacb54dca37a614d43032ad1343ef2d4822972947d" -"checksum web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "2fb60433d0dc12c803b9b017b3902d80c9451bab78d27bc3210bf2a7b96593f1" -"checksum webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e664e770ac0110e2384769bcc59ed19e329d81f555916a6e072714957b81b4" +"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" +"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" +"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" +"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" +"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" +"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" +"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" +"checksum webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" "checksum webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" @@ -2697,7 +2702,7 @@ dependencies = [ "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" +"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 8bcf505..1d49baf 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "91c8d18d17aa5b67dc5dc8a5f8cfe4e323fdda30" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "fb07cae93c706cce929beef98690109e5f2d7592" } diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index fff8f9a..31ff448 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -5,7 +5,7 @@ ChatItem::ChatItem() {} -ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations) +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize) { _timestamp = timestamp; _address = address; @@ -17,9 +17,10 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _txid = txid; _confirmations = confirmations; _outgoing = false; + _notarize = notarize; } -ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing) +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize) { _timestamp = timestamp; _address = address; @@ -31,6 +32,7 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _txid = txid; _confirmations = confirmations; _outgoing = outgoing; + _notarize = notarize; } long ChatItem::getTimestamp() @@ -81,6 +83,11 @@ bool ChatItem::isOutgoing() return _outgoing; } +bool ChatItem::isNotarized() +{ + return _notarize; +} + void ChatItem::setTimestamp(long timestamp) { _timestamp = timestamp; @@ -128,6 +135,10 @@ void ChatItem::toggleOutgo() { _outgoing = true; } +void ChatItem::notarized() +{ + _notarize = false; +} QString ChatItem::toChatLine() @@ -136,14 +147,25 @@ QString ChatItem::toChatLine() QString lock; myDateTime.setTime_t(_timestamp); - if (_confirmations == 0){ + if (_notarize == true) + + { + + lock = " "; + + }else{ + lock = " "; - }else{ + } + if ((_confirmations > 0) && (_notarize == false)) + + { lock = " "; + } + - } - +qDebug()<<_notarize; QString line = QString("") + myDateTime.toString("dd.MM.yyyy hh:mm"); line += QString(lock) + QString(""); line += QString("

") + _memo.toHtmlEscaped() + QString("

"); diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h index be8a807..edfa8a0 100644 --- a/src/Model/ChatItem.h +++ b/src/Model/ChatItem.h @@ -20,11 +20,12 @@ class ChatItem QString _txid; int _confirmations; bool _outgoing = false; + bool _notarize = false; public: ChatItem(); - ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations); - ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing); + ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize); + ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize); long getTimestamp(); QString getAddress(); QString getContact(); @@ -35,6 +36,7 @@ class ChatItem QString getTxid(); int getConfirmations(); bool isOutgoing(); + bool isNotarized(); void setTimestamp(long timestamp); void setAddress(QString address); void setContact(QString contact); @@ -45,6 +47,7 @@ class ChatItem void setTxid(QString txid); void setConfirmations(int confirmations); void toggleOutgo(); + void notarized(); QString toChatLine(); json toJson(); ~ChatItem(); diff --git a/src/controller.cpp b/src/controller.cpp index 8007205..2b4c982 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -239,6 +239,12 @@ void Controller::getInfoThenRefresh(bool force) int curBlock = reply["latest_block_height"].get(); int longestchain = reply["longestchain"].get(); int notarized = reply["notarized"].get(); + int lag = longestchain - notarized ; + + + qDebug()<<"Lag :" << lag; + + int difficulty = reply["difficulty"].get(); int blocks_until_halving= 340000 - curBlock; int halving_days = (blocks_until_halving * 150) / (60*60*24) ; @@ -258,7 +264,11 @@ void Controller::getInfoThenRefresh(bool force) ); ui->longestchain->setText( "Block: " + QLocale(QLocale::German).toString(longestchain) + ); + + this->setLag(lag); + ui->difficulty->setText( QLocale(QLocale::German).toString(difficulty) ); @@ -285,6 +295,8 @@ void Controller::getInfoThenRefresh(bool force) (QLocale(QLocale::English).toString(blocks_until_halving)) + " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days" ) ); + + this->setLag(lag); } ui->Version->setText( @@ -293,6 +305,7 @@ void Controller::getInfoThenRefresh(bool force) ui->Vendor->setText( QString::fromStdString(reply["vendor"].get()) ); + this->setLag(lag); main->logger->write( QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") ); @@ -562,6 +575,20 @@ void Controller::getInfoThenRefresh(bool force) }); } +int Controller::getLag() +{ + + return _lag; + +} + +void Controller::setLag(int lag) +{ + + _lag = lag; + +} + void Controller::refreshAddresses() { if (!zrpc->haveConnection()) @@ -877,6 +904,15 @@ void Controller::refreshTransactions() { memo = QString::fromStdString(o["memo"]); QString cid; + bool isNotarized; + + if (confirmations > getLag()) + { + isNotarized = true; + }else{ + + isNotarized = false; + } ChatItem item = ChatItem( datetime, @@ -888,10 +924,11 @@ void Controller::refreshTransactions() { cid, txid, confirmations, - true + true, + isNotarized ); // qDebug()<<"Memo : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); @@ -973,8 +1010,20 @@ void Controller::refreshTransactions() { requestZaddr = chatModel->getrequestZaddrByTx(txid); }else{ requestZaddr = ""; - } + } + position = it["position"].get(); + + bool isNotarized; + + if (confirmations > getLag()) + { + isNotarized = true; + }else{ + + isNotarized = false; + } + ChatItem item = ChatItem( datetime, address, @@ -985,9 +1034,10 @@ void Controller::refreshTransactions() { cid, txid, confirmations, - false + false, + isNotarized ); - // qDebug()<< "Position : " << position; + qDebug()<< "Notarized : " << isNotarized; // qDebug()<<"Confirmation :" << confirmations; DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); @@ -995,6 +1045,7 @@ void Controller::refreshTransactions() { } } + qDebug()<< getLag(); // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds diff --git a/src/controller.h b/src/controller.h index b34aeb4..f35d636 100644 --- a/src/controller.h +++ b/src/controller.h @@ -37,7 +37,10 @@ public: Connection* getConnection() { return zrpc->getConnection(); } void setConnection(Connection* c); void refresh(bool force = false); - void refreshAddresses(); + void refreshAddresses(); + int getLag(); + void setLag(int lag); + int _lag; void checkForUpdate(bool silent = true); void refreshZECPrice(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 2d85bd5..c7d5481 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1505,6 +1505,9 @@ 521
+ + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + Qt::ScrollBarAsNeeded From 537d3828b060150a24e9cd1a6a81d2ee7b8cc753 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 25 May 2020 22:44:07 +0200 Subject: [PATCH 153/253] add contectmenu to contactitems --- src/contactmodel.cpp | 19 +++++++++++++++---- src/contactmodel.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 6f452fa..8700a32 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -6,10 +6,19 @@ #include "mainwindow.h" #include "chatmodel.h" + void ContactModel::renderContactList(QListView* view) { QStandardItemModel* contact = new QStandardItemModel(); - + QMenu* contextMenu; + QAction* requestAction; + QAction* editAction; + contextMenu = new QMenu(view); + requestAction = new QAction("Send a contact request",contextMenu); + editAction = new QAction("Edit this contact",contextMenu); + + // QObject::connect(requestAction,SIGNAL(customContextMenuRequested(const QModelIndex)),this, SLOT(&ContactModel::requestActionClickedSlot)); + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { @@ -18,14 +27,16 @@ void ContactModel::renderContactList(QListView* view) QStandardItem* Items1 = new QStandardItem(c.getName()); Items1->setData(QIcon(avatar),Qt::DecorationRole); + contact->appendRow(Items1); view->setModel(contact); view->setIconSize(QSize(60,70)); view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly); view->show(); - + view->setContextMenuPolicy(Qt::ActionsContextMenu); + view->addAction(requestAction); + view->addAction(editAction); } - -} \ No newline at end of file +} diff --git a/src/contactmodel.h b/src/contactmodel.h index fcdf7a3..cfe57bc 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -8,6 +8,7 @@ class ContactModel + { public: ContactModel() {} From eb0bb65230540b2a89437ae01f5a76aae537b8bc Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 26 May 2020 19:40:42 +0200 Subject: [PATCH 154/253] add error message for messages over 512 chars --- src/chatmodel.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 0e636b2..63ce92c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -349,6 +349,22 @@ void MainWindow::sendChat() { return; } + int max = 512; + QString chattext = ui->memoTxtChat->toPlainText(); + int size = chattext.size(); + + if (size > max){ + + // auto addr = ""; + // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"), + tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 512 character."), + QMessageBox::Ok, this); + + msg.exec(); + return; + } + Tx tx = createTxFromChatPage(); QString error = doSendChatTxValidations(tx); @@ -646,6 +662,22 @@ void MainWindow::ContactRequest() { return; } + int max = 512; + QString chattext = contactRequest.getMemo();; + int size = chattext.size(); + + if (size > max){ + + // auto addr = ""; + // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { + QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"), + tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 512 character."), + QMessageBox::Ok, this); + + msg.exec(); + return; + } + Tx tx = createTxForSafeContactRequest(); QString error = doSendRequestTxValidations(tx); From 963857fbdaa910342aff67e4a55eeaf05598101d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 26 May 2020 20:09:38 +0200 Subject: [PATCH 155/253] undo dep upgrade,refresh tab after sending a message --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- src/chatmodel.cpp | 10 +++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 07f7981..c2021b0 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1daf5ce75fcbd51047360681652f173f93f54f93)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592#fb07cae93c706cce929beef98690109e5f2d7592" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=1daf5ce75fcbd51047360681652f173f93f54f93#1daf5ce75fcbd51047360681652f173f93f54f93" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=fb07cae93c706cce929beef98690109e5f2d7592)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1daf5ce75fcbd51047360681652f173f93f54f93)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1d49baf..15e0acd 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "fb07cae93c706cce929beef98690109e5f2d7592" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "1daf5ce75fcbd51047360681652f173f93f54f93" } diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 63ce92c..cb5621d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -403,6 +403,7 @@ void MainWindow::sendChat() { d->show(); ui->memoTxtChat->clear(); + // And send the Tx rpc->executeTransaction(tx, @@ -411,6 +412,7 @@ void MainWindow::sendChat() { connD->status->setText(tr("Done!")); connD->statusDetail->setText(txid); + QTimer::singleShot(1000, [=]() { d->accept(); @@ -421,7 +423,7 @@ void MainWindow::sendChat() { }); // Force a UI update so we get the unconfirmed Tx - // rpc->refresh(true); + rpc->refresh(true); ui->memoTxtChat->clear(); }, @@ -440,6 +442,8 @@ void MainWindow::sendChat() { QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); } ); + + // rpc->refresh(true); } QString MainWindow::doSendChatTxValidations(Tx tx) { @@ -465,7 +469,7 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); if (available < total) { - return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 3 confirmations before they can be spent") + return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 1 confirmations before they can be spent") .arg(available.toDecimalhushString(), total.toDecimalhushString()); } @@ -662,7 +666,7 @@ void MainWindow::ContactRequest() { return; } - int max = 512; + int max = 512; QString chattext = contactRequest.getMemo();; int size = chattext.size(); From 7d081f678cabc58898b4ab68d31a489eb76920a3 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 26 May 2020 20:21:59 +0200 Subject: [PATCH 156/253] fix some typos, delete -add only a contact- on chattab --- src/chatmodel.cpp | 6 +++--- src/contactrequest.ui | 33 ++++----------------------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index cb5621d..97d46f9 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -399,7 +399,7 @@ void MainWindow::sendChat() { } connD->status->setText(tr("Please wait...")); - connD->statusDetail->setText(tr("Your Message will be send")); + connD->statusDetail->setText(tr("Your Message will be sent")); d->show(); ui->memoTxtChat->clear(); @@ -518,7 +518,7 @@ void::MainWindow::addContact() }); QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::saveandsendContact); - QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact); + // QObject::connect(request.onlyAdd, &QPushButton::clicked, this, &MainWindow::saveContact); dialog.exec(); @@ -716,7 +716,7 @@ void MainWindow::ContactRequest() { } connD->status->setText(tr("Please wait...")); - connD->statusDetail->setText(tr("Your Contact will be send")); + connD->statusDetail->setText(tr("Your contact request will be sent")); d->show(); ui->memoTxtChat->clear(); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 8667057..1e37ee9 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -6,7 +6,7 @@ 0 0 - 777 + 780 427
@@ -233,7 +233,7 @@
- + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request</span></p></body></html> @@ -318,36 +318,11 @@ - - - - - 152 - 25 - - - - - 100 - 0 - - - - Only add this contact - - - false - - - false - - - - 188 + 300 25 @@ -358,7 +333,7 @@ - Add Contact & send request + Add Contact and send request false From 78ca3cf8caca719a43f8c3ac5df23ab019dc136d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 26 May 2020 22:11:15 +0200 Subject: [PATCH 157/253] fix for double outgoing message --- src/Chat/Chat.cpp | 5 ++++- src/chatmodel.cpp | 9 ++++----- src/controller.cpp | 39 ++++++++++++++++++++------------------- src/mainwindow.cpp | 1 + src/mainwindow.ui | 7 +++++-- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index f76222d..c0482b8 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -67,7 +67,8 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) Items->setData(OUTGOING, Qt::UserRole + 1); chat->appendRow(Items); - ui->listChat->setModel(chat); + ui->listChat->setModel(chat); + } else @@ -86,6 +87,8 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) Items1->setData(INCOMING, Qt::UserRole + 1); chat->appendRow(Items1); ui->listChat->setModel(chat); + + } else { diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 97d46f9..e5864f8 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -53,7 +53,6 @@ void ChatModel::clear() void ChatModel::addMessage(ChatItem item) { QString key = ChatIDGenerator::getInstance()->generateID(item); //this->generateChatItemID(item); - // qDebug() << "inserting chatitem with id: " << key; this->chatItems[key] = item; } @@ -72,9 +71,7 @@ void ChatModel::showMessages() } } - - - + void MainWindow::renderContactRequest(){ Ui_requestDialog requestContact; @@ -336,7 +333,9 @@ void MainWindow::sendChat() { // Memos can only be used with zAddrs. So check that first // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - + QString Name = ui->contactNameMemo->text(); + int sizename = Name.size(); + qDebug()<< sizename; if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { // auto addr = ""; diff --git a/src/controller.cpp b/src/controller.cpp index 2b4c982..cd6152b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -237,18 +237,15 @@ void Controller::getInfoThenRefresh(bool force) zrpc->fetchInfo([=] (const json& reply) { prevCallSucceeded = true; int curBlock = reply["latest_block_height"].get(); - int longestchain = reply["longestchain"].get(); - int notarized = reply["notarized"].get(); - int lag = longestchain - notarized ; - - - qDebug()<<"Lag :" << lag; - - + bool doUpdate = force || (model->getLatestBlock() != curBlock); int difficulty = reply["difficulty"].get(); int blocks_until_halving= 340000 - curBlock; int halving_days = (blocks_until_halving * 150) / (60*60*24) ; - bool doUpdate = force || (model->getLatestBlock() != curBlock); + int longestchain = reply["longestchain"].get(); + int notarized = reply["notarized"].get(); + + + model->setLatestBlock(curBlock); if ( Settings::getInstance()->get_currency_name() == "EUR" || @@ -267,7 +264,7 @@ void Controller::getInfoThenRefresh(bool force) ); - this->setLag(lag); + ui->difficulty->setText( QLocale(QLocale::German).toString(difficulty) @@ -295,8 +292,6 @@ void Controller::getInfoThenRefresh(bool force) (QLocale(QLocale::English).toString(blocks_until_halving)) + " Blocks or , " + (QLocale(QLocale::English).toString(halving_days) + " days" ) ); - - this->setLag(lag); } ui->Version->setText( @@ -305,7 +300,6 @@ void Controller::getInfoThenRefresh(bool force) ui->Vendor->setText( QString::fromStdString(reply["vendor"].get()) ); - this->setLag(lag); main->logger->write( QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") ); @@ -553,8 +547,12 @@ void Controller::getInfoThenRefresh(bool force) refreshAddresses(); // This calls refreshZSentTransactions() and refreshReceivedZTrans() refreshTransactions(); } + + int lag = longestchain - notarized ; + this->setLag(lag); }, [=](QString err) { // hushd has probably disappeared. + this->noConnection(); // Prevent multiple dialog boxes, because these are called async @@ -914,6 +912,12 @@ void Controller::refreshTransactions() { isNotarized = false; } + if (confirmations == 1) { + DataStore::getChatDataStore()->clear(); + this->refresh(true); + } + qDebug()<<"Conf : " << confirmations; + ChatItem item = ChatItem( datetime, address, @@ -927,12 +931,10 @@ void Controller::refreshTransactions() { true, isNotarized ); - // qDebug()<<"Memo : " <setData(ChatIDGenerator::getInstance()->generateID(item), item); - - } + } + + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; @@ -1038,7 +1040,6 @@ void Controller::refreshTransactions() { isNotarized ); qDebug()<< "Notarized : " << isNotarized; - // qDebug()<<"Confirmation :" << confirmations; DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4f6c428..d71baad 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1208,6 +1208,7 @@ void MainWindow::setupTransactionsTab() { ui->listChat->setMinimumSize(200,350); ui->listChat->setItemDelegate(new ListViewDelegate()); ui->listChat->show(); + ui->transactionsTable->setContextMenuPolicy(Qt::CustomContextMenu); // Table right click QObject::connect(ui->transactionsTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) { diff --git a/src/mainwindow.ui b/src/mainwindow.ui index c7d5481..a4a4e78 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1378,7 +1378,10 @@ true - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + QAbstractItemView::NoEditTriggers + + + false false @@ -1518,7 +1521,7 @@ QAbstractScrollArea::AdjustToContents - QAbstractItemView::AllEditTriggers + QAbstractItemView::NoEditTriggers QListView::Adjust From aa46cc99ae4489ad818cc65f123e57476e6af2bc Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 26 May 2020 23:28:40 +0200 Subject: [PATCH 158/253] refresh if conf=1 --- src/chatmodel.cpp | 25 +++++++++++++++++++++++++ src/chatmodel.h | 4 ++++ src/controller.cpp | 19 ++++++++++++++----- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index e5864f8..b0acb38 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -216,6 +216,11 @@ void ChatModel::addrequestZaddr(QString tx, QString requestZaddr) this->requestZaddrMap[tx] = requestZaddr; } +void ChatModel::addconfirmations(QString tx, int confirmation) +{ + this->confirmationsMap[tx] = confirmation; +} + QString ChatModel::getCidByTx(QString tx) { for(auto& pair : this->cidMap) @@ -231,6 +236,21 @@ QString ChatModel::getCidByTx(QString tx) return QString("0xdeadbeef"); } +QString ChatModel::getConfirmationByTx(QString tx) +{ + for(auto& pair : this->confirmationsMap) + { + + } + + if(this->confirmationsMap.count(tx) > 0) + { + return this->confirmationsMap[tx]; + } + + return QString("0xdeadbeef"); +} + QString ChatModel::getrequestZaddrByTx(QString tx) { for(auto& pair : this->requestZaddrMap) @@ -256,6 +276,11 @@ void ChatModel::killrequestZaddrCache() this->requestZaddrMap.clear(); } +void ChatModel::killConfirmationCache() +{ + this->confirmationsMap.clear(); +} + QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) { diff --git a/src/chatmodel.h b/src/chatmodel.h index e8bc3e7..7ca5a0f 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -32,6 +32,7 @@ class ChatModel MainWindow* main; std::map cidMap; std::map requestZaddrMap; + std::map confirmationsMap; std::map> sendrequestMap; public: @@ -49,10 +50,13 @@ class ChatModel void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); void addrequestZaddr(QString tx, QString requestZaddr); + void addconfirmations(QString tx, int confirmation); void addSendRequest(int i, QString myAddr, QString cid, QString addr ); QString getCidByTx(QString tx); QString getrequestZaddrByTx(QString tx); + QString getConfirmationByTx(QString tx); void killCidCache(); + void killConfirmationCache(); void killrequestZaddrCache(); }; diff --git a/src/controller.cpp b/src/controller.cpp index cd6152b..541821c 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -896,6 +896,16 @@ void Controller::refreshTransactions() { CAmount amount = CAmount::fromqint64(-1* o["value"].get()); // Check for Memos + + if (confirmations == 0) { + chatModel->addconfirmations(txid, confirmations); + } + + if ((confirmations == 1) && (chatModel->getConfirmationByTx(txid) != QString("0xdeadbeef"))){ + DataStore::getChatDataStore()->clear(); + chatModel->killConfirmationCache(); + this->refresh(true); + } QString memo; if (!o["memo"].is_null()) { @@ -912,10 +922,6 @@ void Controller::refreshTransactions() { isNotarized = false; } - if (confirmations == 1) { - DataStore::getChatDataStore()->clear(); - this->refresh(true); - } qDebug()<<"Conf : " << confirmations; ChatItem item = ChatItem( @@ -932,10 +938,13 @@ void Controller::refreshTransactions() { isNotarized ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + + + } - + // this->refresh(true); items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } From 56cc89a918b22bf217eadeb1e10a209b9b4e3980 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 07:41:11 +0200 Subject: [PATCH 159/253] dont delete unsent message when switching tab, add more contextmenu --- src/Model/ChatItem.h | 1 + src/contactmodel.cpp | 37 +++++++++++++++++++++++++------------ src/contactmodel.h | 3 +++ src/controller.cpp | 3 +-- src/mainwindow.cpp | 22 +++++++++++++++++++++- src/mainwindow.h | 1 + src/mainwindow.ui | 13 +++++++++++-- 7 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h index edfa8a0..11e3b65 100644 --- a/src/Model/ChatItem.h +++ b/src/Model/ChatItem.h @@ -36,6 +36,7 @@ class ChatItem QString getTxid(); int getConfirmations(); bool isOutgoing(); + bool isdouble(); bool isNotarized(); void setTimestamp(long timestamp); void setAddress(QString address); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 8700a32..691c65e 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -5,20 +5,17 @@ #include "addressbook.h" #include "mainwindow.h" #include "chatmodel.h" +#include "requestdialog.h" +#include "ui_requestdialog.h" +#include "settings.h" +#include "controller.h" + void ContactModel::renderContactList(QListView* view) { QStandardItemModel* contact = new QStandardItemModel(); - QMenu* contextMenu; - QAction* requestAction; - QAction* editAction; - contextMenu = new QMenu(view); - requestAction = new QAction("Send a contact request",contextMenu); - editAction = new QAction("Edit this contact",contextMenu); - - // QObject::connect(requestAction,SIGNAL(customContextMenuRequested(const QModelIndex)),this, SLOT(&ContactModel::requestActionClickedSlot)); - + for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { @@ -34,9 +31,25 @@ void ContactModel::renderContactList(QListView* view) view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly); view->show(); - view->setContextMenuPolicy(Qt::ActionsContextMenu); - view->addAction(requestAction); - view->addAction(editAction); + + } } + +void MainWindow::showRequesthush() { + + Ui_RequestDialog req; + QDialog d(this); + req.setupUi(&d); + Settings::saveRestore(&d); + + // setupDialog(main, &d, &req); + + // Setup the Label completer for the Address + + + d.exec(); + +} + diff --git a/src/contactmodel.h b/src/contactmodel.h index cfe57bc..095fe99 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -5,14 +5,17 @@ #include "Model/ContactItem.h" #include +#include "mainwindow.h" class ContactModel { public: + ContactModel() {} void renderContactList(QListView* view); + }; #endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 541821c..10b41bb 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -943,8 +943,7 @@ void Controller::refreshTransactions() { } - - // this->refresh(true); + items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d71baad..24f9b7c 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1358,13 +1358,33 @@ void MainWindow::setupchatTab() { // ui->ContactZaddr->setText(p.getPartnerAddress()); // ui->MyZaddr->setText(p.getMyAddress()); ui->contactNameMemo->setText(p.getName()); - ui->memoTxtChat->clear(); + // ui->memoTxtChat->clear(); rpc->refresh(true); // updateChat(); } }); + + QMenu* contextMenu; + QAction* requestAction; + QAction* editAction; + QAction* HushAction; + QAction* requestHushAction; + contextMenu = new QMenu(ui->listContactWidget); + requestAction = new QAction("Send a contact request",contextMenu); + editAction = new QAction("Delete this contact",contextMenu); + HushAction = new QAction("Send a friend some Hush",contextMenu); + requestHushAction = new QAction("Request some Hush",contextMenu); + ui->listContactWidget->setContextMenuPolicy(Qt::ActionsContextMenu); + ui->listContactWidget->addAction(requestAction); + ui->listContactWidget->addAction(editAction); + ui->listContactWidget->addAction(HushAction); + ui->listContactWidget->addAction(requestHushAction); + QObject::connect(requestHushAction, &QAction::triggered, [=]() { + MainWindow::showRequesthush(); + }); + ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat); } diff --git a/src/mainwindow.h b/src/mainwindow.h index fb08fdb..56bfbc6 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -60,6 +60,7 @@ public: void stopWebsocket(); void saveContact(); void saveandsendContact(); + void showRequesthush(); // void setmaxlenChat(int len); // void updateDisplay(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index a4a4e78..de58411 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1389,6 +1389,9 @@ QAbstractItemView::SingleSelection + + QAbstractItemView::SelectItems + @@ -1422,10 +1425,16 @@ QTextEdit::AutoNone - QTextEdit::FixedColumnWidth + QTextEdit::FixedPixelWidth - 80 + 600 + + + false + + + Qt::TextEditorInteraction From 4d8e3ba4605fa7d86be7a554ac6436cf4cf3c475 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 13:46:51 +0200 Subject: [PATCH 160/253] add hushrequest and delete contact --- src/hushrequest.ui | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/hushrequest.ui diff --git a/src/hushrequest.ui b/src/hushrequest.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/src/hushrequest.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From d0f406d37375eeb192336cc594bef5f2e1998a61 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 13:47:22 +0200 Subject: [PATCH 161/253] add hushrequest and delete contact --- silentdragon-lite.pro | 1 + src/contactmodel.cpp | 102 +++++++++++++-- src/contactmodel.h | 1 + src/hushrequest.ui | 208 +++++++++++++++++++++---------- src/mainwindow.cpp | 48 ++++++-- src/requestdialog.ui | 280 +++++++++++++++++++++--------------------- 6 files changed, 420 insertions(+), 220 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 4d07b4d..90b261b 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -122,6 +122,7 @@ HEADERS += \ FORMS += \ src/contactrequest.ui \ src/encryption.ui \ + src/hushrequest.ui \ src/mainwindow.ui \ src/migration.ui \ src/newseed.ui \ diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 691c65e..7f9d097 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -7,6 +7,7 @@ #include "chatmodel.h" #include "requestdialog.h" #include "ui_requestdialog.h" +#include "ui_hushrequest.h" #include "settings.h" #include "controller.h" @@ -39,17 +40,104 @@ void ContactModel::renderContactList(QListView* view) void MainWindow::showRequesthush() { - Ui_RequestDialog req; + Ui_hushrequest req; QDialog d(this); req.setupUi(&d); Settings::saveRestore(&d); - // setupDialog(main, &d, &req); + QString label = ui->contactNameMemo->text(); + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + { + + if (p.getName() == label) + + { + + QString addr = p.getPartnerAddress(); + QString myzaddr = p.getMyAddress(); + + req.txtFrom->setText(addr); + req.lblAddressInfo->setText(myzaddr); + // Amount textbox + req.txtAmount->setValidator(this->getAmountValidator()); + QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) { + CAmount amount = CAmount::fromDecimalString(text); + if (Settings::getInstance()->get_currency_name() == "USD") { + req.txtAmountUSD->setText(amount.toDecimalUSDString()); + } else if (Settings::getInstance()->get_currency_name() == "EUR") { + req.txtAmountUSD->setText(amount.toDecimalEURString()); + } else if (Settings::getInstance()->get_currency_name() == "BTC") { + req.txtAmountUSD->setText(amount.toDecimalBTCString()); + } else if (Settings::getInstance()->get_currency_name() == "CNY") { + req.txtAmountUSD->setText(amount.toDecimalCNYString()); + } else if (Settings::getInstance()->get_currency_name() == "RUB") { + req.txtAmountUSD->setText(amount.toDecimalRUBString()); + } else if (Settings::getInstance()->get_currency_name() == "CAD") { + req.txtAmountUSD->setText(amount.toDecimalCADString()); + } else if (Settings::getInstance()->get_currency_name() == "SGD") { + req.txtAmountUSD->setText(amount.toDecimalSGDString()); + } else if (Settings::getInstance()->get_currency_name() == "CHF") { + req.txtAmountUSD->setText(amount.toDecimalCHFString()); + } else if (Settings::getInstance()->get_currency_name() == "INR") { + req.txtAmountUSD->setText(amount.toDecimalINRString()); + } else if (Settings::getInstance()->get_currency_name() == "GBP") { + req.txtAmountUSD->setText(amount.toDecimalGBPString()); + } else if (Settings::getInstance()->get_currency_name() == "AUD") { + req.txtAmountUSD->setText(amount.toDecimalBTCString()); + } + }); + CAmount amount = CAmount::fromDecimalString(req.txtAmount->text()); + if (Settings::getInstance()->get_currency_name() == "USD") { + req.txtAmountUSD->setText(amount.toDecimalUSDString()); + } else if (Settings::getInstance()->get_currency_name() == "EUR") { + req.txtAmountUSD->setText(amount.toDecimalEURString()); + } else if (Settings::getInstance()->get_currency_name() == "BTC") { + req.txtAmountUSD->setText(amount.toDecimalBTCString()); + } else if (Settings::getInstance()->get_currency_name() == "CNY") { + req.txtAmountUSD->setText(amount.toDecimalCNYString()); + } else if (Settings::getInstance()->get_currency_name() == "RUB") { + req.txtAmountUSD->setText(amount.toDecimalRUBString()); + } else if (Settings::getInstance()->get_currency_name() == "CAD") { + req.txtAmountUSD->setText(amount.toDecimalCADString()); + } else if (Settings::getInstance()->get_currency_name() == "SGD") { + req.txtAmountUSD->setText(amount.toDecimalSGDString()); + } else if (Settings::getInstance()->get_currency_name() == "CHF") { + req.txtAmountUSD->setText(amount.toDecimalCHFString()); + } else if (Settings::getInstance()->get_currency_name() == "INR") { + req.txtAmountUSD->setText(amount.toDecimalINRString()); + } else if (Settings::getInstance()->get_currency_name() == "GBP") { + req.txtAmountUSD->setText(amount.toDecimalGBPString()); + } else if (Settings::getInstance()->get_currency_name() == "AUD") { + req.txtAmountUSD->setText(amount.toDecimalBTCString()); + } + req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok)); + req.txtMemo->setLenDisplayLabel(req.lblMemoLen); + req.txtMemo->setMaxLen(400); + + req.txtFrom->setFocus(); + + + } + } + if (d.exec() == QDialog::Accepted) { + // Construct a hush Payment URI with the data and pay it immediately. + CAmount amount = CAmount::fromDecimalString(req.txtAmount->text()); + QString memoURI = "hush:" + req.lblAddressInfo->text() + + "?amt=" + amount.toDecimalString() + + "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText()); + + QString sendURI = "hush:" + AddressBook::addressFromAddressLabel(req.txtFrom->text()) + + "?amt=0.0001" + + "&memo=" + QUrl::toPercentEncoding(memoURI); + + // If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default + // sapling address + this->payhushURI(sendURI, req.lblAddressInfo->text()); + + + + } - // Setup the Label completer for the Address - - - d.exec(); - } + diff --git a/src/contactmodel.h b/src/contactmodel.h index 095fe99..f361ceb 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -16,6 +16,7 @@ class ContactModel ContactModel() {} void renderContactList(QListView* view); + }; #endif \ No newline at end of file diff --git a/src/hushrequest.ui b/src/hushrequest.ui index fb923db..d0b0ca7 100644 --- a/src/hushrequest.ui +++ b/src/hushrequest.ui @@ -1,72 +1,156 @@ - - - - - Dialog - - + + + hushrequest + + 0 0 - 400 - 300 + 663 + 529 - + Dialog - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + + + true + + + + + + + Request From + + + + + + + Qt::Horizontal + + + + 541 + 20 + + + + + + + + zaddr + + + + + + + Amount in + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + Amount + + + + + + + Amount USD + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Memo + + + + + + + 0 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + My Address + + + + + + + The recipient will see this address in the "to" field when they pay your request. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + - + + + MemoEdit + QPlainTextEdit +
memoedit.h
+
+
- - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - +
- diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 24f9b7c..cad3ca9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1338,9 +1338,6 @@ void MainWindow::setupchatTab() { ui->memoTxtChat->setTextColor("Black"); } - - - QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); @@ -1355,17 +1352,13 @@ void MainWindow::setupchatTab() { for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) if (label_contact == p.getName()) { - // ui->ContactZaddr->setText(p.getPartnerAddress()); - // ui->MyZaddr->setText(p.getMyAddress()); - ui->contactNameMemo->setText(p.getName()); - // ui->memoTxtChat->clear(); - - rpc->refresh(true); - // updateChat(); + ui->contactNameMemo->setText(p.getName()); + rpc->refresh(true); + } }); - + QMenu* contextMenu; QAction* requestAction; QAction* editAction; @@ -1382,9 +1375,42 @@ void MainWindow::setupchatTab() { ui->listContactWidget->addAction(HushAction); ui->listContactWidget->addAction(requestHushAction); QObject::connect(requestHushAction, &QAction::triggered, [=]() { + QModelIndex index = ui->listContactWidget->currentIndex(); + QString label_contact = index.data(Qt::DisplayRole).toString(); + + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + if (label_contact == p.getName()) { + ui->contactNameMemo->setText(p.getName()); + rpc->refresh(true); + + } + MainWindow::showRequesthush(); }); + QObject::connect(editAction, &QAction::triggered, [=]() { + QModelIndex index = ui->listContactWidget->currentIndex(); + QString label_contact = index.data(Qt::DisplayRole).toString(); + + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + if (label_contact == p.getName()) { + + + QString label1 = p.getName(); + QString addr = p.getPartnerAddress(); + QString myzaddr = p.getMyAddress(); + QString cid = p.getCid(); + QString avatar = p.getAvatar(); + + + AddressBook::getInstance()->removeAddressLabel(label1, addr, myzaddr, cid,avatar); + // QList labels = AddressBook::getInstance()->getAllAddressLabels(); + rpc->refreshContacts( + ui->listContactWidget); + rpc->refresh(true); + } + }); + ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat); } diff --git a/src/requestdialog.ui b/src/requestdialog.ui index 952f780..e52c475 100644 --- a/src/requestdialog.ui +++ b/src/requestdialog.ui @@ -14,9 +14,124 @@ Payment Request
+ + + + + + + + + + + Request From + + + + + + + The recipient will see this address in the "to" field when they pay your request. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + TextLabel + + + Qt::AlignCenter + + + + + + + + + + + + + + color: red; + + + + + + + + + + Memo + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 / 512 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + + + + Amount USD + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + @@ -41,65 +156,13 @@ - - - - Qt::Horizontal - - - - - + + - Request From + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. - - - - - - My Address - - - - - - - color: red; - - - - - - - - - - Amount in - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - + + true @@ -119,20 +182,20 @@ - - - - Qt::Horizontal + + + + My Address - - - - - 0 - 0 - + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -146,83 +209,20 @@ - - + + + + Amount in + + + + + Qt::Horizontal - - - - The recipient will see this address in the "to" field when they pay your request. - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0 / 512 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Amount USD - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Memo - - - - - - - TextLabel - - - Qt::AlignCenter - - - - - - - Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. - - - true - - -
From 50ac16f115235a88579711c34061a5a3b275650c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 15:38:24 +0200 Subject: [PATCH 162/253] dummy option for subatomic swaps in sdl --- src/mainwindow.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cad3ca9..de2583e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1364,16 +1364,19 @@ void MainWindow::setupchatTab() { QAction* editAction; QAction* HushAction; QAction* requestHushAction; + QAction* subatomicAction; contextMenu = new QMenu(ui->listContactWidget); - requestAction = new QAction("Send a contact request",contextMenu); + requestAction = new QAction("Send a contact request - coming soon",contextMenu); editAction = new QAction("Delete this contact",contextMenu); - HushAction = new QAction("Send a friend some Hush",contextMenu); - requestHushAction = new QAction("Request some Hush",contextMenu); + HushAction = new QAction("Send a friend some Hush - coming soon",contextMenu); + requestHushAction = new QAction("Request some Hush - coming soon",contextMenu); + subatomicAction = new QAction("Make a subatomic swap with a friend- coming soon",contextMenu); ui->listContactWidget->setContextMenuPolicy(Qt::ActionsContextMenu); ui->listContactWidget->addAction(requestAction); ui->listContactWidget->addAction(editAction); ui->listContactWidget->addAction(HushAction); ui->listContactWidget->addAction(requestHushAction); + ui->listContactWidget->addAction(subatomicAction); QObject::connect(requestHushAction, &QAction::triggered, [=]() { QModelIndex index = ui->listContactWidget->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); From f57dc2c5ad36ab609ffcd7b399a0b3bc70278050 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 17:46:52 +0200 Subject: [PATCH 163/253] push lock.png --- res/lock_orange.png | Bin 0 -> 929 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/lock_orange.png diff --git a/res/lock_orange.png b/res/lock_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..11a5c55fc5a65456a87766f9f43793e93f20a230 GIT binary patch literal 929 zcmV;S177@zP)EX>4Tx04R}tkv&MmKpe$iQ%j3f9GXGJAwzYtAS&XhRVYG*P%E_RU_SZ@4|zbb@Z5yBv1;1Q7&%a{|zGt~4AUmwAfDc| z4aWP#yi%4_;&b9LlP*a7$aLA`H^wEGIhM(r*~~mKPb`$WSngt_Y-+?)#Bo*ADWA)E ztTNtWtX1nu`=0ED(Sp9R%ygQ=NMR965FtQD9TikzBSEW9iiHgACw=@wu3sdVOs)zP zax9<*4U+2z`-9)zTE)o;FDaS?LNAW0S*p< z(Gq2^`@B2S-P^xs+Wq|iD(Z5Iz6|rv00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4c7nw4c7reD4Tcy000McNliruIjYZgv7Ps2nAlN9_BmogY6YVULBI*4vEVWcL zVOPyqcz3zGNg$^=Q@r!e%4a-h>3X^$A#msNj+)7FGM9+
u`Dxf3m)wB5@JU~A=M(6N9o+O7-tqv>)FToS^%s<}*`Oc|CbTo`shAm<|7#JQ!Df&l^`YhiOT*fZ7&zb!?@)1QP!M?tGsqn_I}<00000NkvXXu0mjf DpzWW* literal 0 HcmV?d00001 From cfbcc43b14eb1a21c02853d4fbf237efa9f06eff Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 21:42:39 +0200 Subject: [PATCH 164/253] render only new requests --- src/Chat/Chat.cpp | 1 - src/DataStore/ChatDataStore.cpp | 9 +++--- src/FileSystem/FileSystem.cpp | 6 ++-- src/FileSystem/FileSystem.h | 4 ++- src/Model/ChatItem.cpp | 17 +++++++++-- src/Model/ChatItem.h | 7 +++-- src/Model/ContactItem.cpp | 7 ++++- src/Model/ContactItem.h | 5 +++- src/addressbook.cpp | 3 ++ src/addressbook.h | 9 +++++- src/chatmodel.cpp | 35 +++++++++++++++++++---- src/chatmodel.h | 6 +++- src/contactmodel.h | 3 +- src/controller.cpp | 38 ++++++++++++++++++++----- src/controller.h | 3 ++ src/mainwindow.cpp | 7 +---- src/requestContactDialog.ui | 50 +++++++++++++++++++++------------ src/sendtab.cpp | 2 +- 18 files changed, 157 insertions(+), 55 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index c0482b8..cdc3814 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -55,7 +55,6 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) { for (auto &c : DataStore::getChatDataStore()->getAllMemos()) { - //////Render only Memos for selected contacts. Do not render empty Memos //// Render only memos where cid=cid if ( (p.getName() == ui->contactNameMemo->text().trimmed()) && diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 21ddef9..7bb3840 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -3,6 +3,8 @@ #include "ChatDataStore.h" #include "addressbook.h" +#include "chatmodel.h" + ChatDataStore* ChatDataStore::getInstance() { @@ -53,15 +55,14 @@ std::map ChatDataStore::getAllNewContactRequests() { std::map filteredItems; - for(auto &c: this->data) + for(auto &c: this->data) { if ( (c.second.isOutgoing() == false) && (c.second.getType() == "Cont") && - (c.second.getContact() == "") - - + (c.second.isContact() == false) ) + { filteredItems[c.first] = c.second; } diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 2a60de1..208bfaa 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -1,8 +1,11 @@ -#include "FileSystem.h" +// Copyright 2019-2020 The Hush developers +// GPLv3 +#include "FileSystem.h" #include #include #include "../Crypto/passwd.h" +#include "addressbook.h" FileSystem::FileSystem() { @@ -99,7 +102,6 @@ QList FileSystem::readContactsOldFormat(QString file) qDebug() << "Detected old addressbook format"; QList> stuff; in >> stuff; - //qDebug() << "Stuff: " << stuff; for (int i=0; i < stuff.size(); i++) { ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); diff --git a/src/FileSystem/FileSystem.h b/src/FileSystem/FileSystem.h index 30dd5fc..34fc5fc 100644 --- a/src/FileSystem/FileSystem.h +++ b/src/FileSystem/FileSystem.h @@ -1,3 +1,5 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #ifndef FILESYSTEM_H #define FILESYSTEM_H @@ -13,7 +15,7 @@ class FileSystem static bool instanced; static FileSystem* instance; FileSystem(); - + public: static FileSystem* getInstance(); QList readContacts(QString file); diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index 31ff448..6a30f56 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -5,7 +5,7 @@ ChatItem::ChatItem() {} -ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize) +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize, bool iscontact) { _timestamp = timestamp; _address = address; @@ -18,9 +18,10 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _confirmations = confirmations; _outgoing = false; _notarize = notarize; + _iscontact = iscontact; } -ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize) +ChatItem::ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize, bool iscontact) { _timestamp = timestamp; _address = address; @@ -33,6 +34,8 @@ ChatItem::ChatItem(long timestamp, QString address, QString contact, QString mem _confirmations = confirmations; _outgoing = outgoing; _notarize = notarize; + _iscontact = iscontact; + } long ChatItem::getTimestamp() @@ -88,6 +91,11 @@ bool ChatItem::isNotarized() return _notarize; } +bool ChatItem::isContact() +{ + return _iscontact; +} + void ChatItem::setTimestamp(long timestamp) { _timestamp = timestamp; @@ -140,6 +148,11 @@ void ChatItem::notarized() _notarize = false; } +void ChatItem::contact(bool iscontact) +{ + _iscontact = iscontact; +} + QString ChatItem::toChatLine() { diff --git a/src/Model/ChatItem.h b/src/Model/ChatItem.h index 11e3b65..900c994 100644 --- a/src/Model/ChatItem.h +++ b/src/Model/ChatItem.h @@ -21,11 +21,12 @@ class ChatItem int _confirmations; bool _outgoing = false; bool _notarize = false; + bool _iscontact = false; public: ChatItem(); - ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize); - ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize); + ChatItem(long timestamp, QString address, QString contact, QString memo,QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool notarize, bool iscontact); + ChatItem(long timestamp, QString address, QString contact, QString memo, QString requestZaddr, QString type, QString cid, QString txid, int confirmations, bool outgoing, bool notarize, bool iscontact); long getTimestamp(); QString getAddress(); QString getContact(); @@ -38,6 +39,7 @@ class ChatItem bool isOutgoing(); bool isdouble(); bool isNotarized(); + bool isContact(); void setTimestamp(long timestamp); void setAddress(QString address); void setContact(QString contact); @@ -49,6 +51,7 @@ class ChatItem void setConfirmations(int confirmations); void toggleOutgo(); void notarized(); + void contact(bool iscontact); QString toChatLine(); json toJson(); ~ChatItem(); diff --git a/src/Model/ContactItem.cpp b/src/Model/ContactItem.cpp index d38c1c5..d2321bd 100644 --- a/src/Model/ContactItem.cpp +++ b/src/Model/ContactItem.cpp @@ -1,4 +1,9 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #include "ContactItem.h" +#include "chatmodel.h" +#include "Model/ChatItem.h" +#include "controller.h" ContactItem::ContactItem() {} @@ -8,7 +13,7 @@ ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress _myAddress = myAddress; _partnerAddress = partnerAddress; _cid = cid; - _avatar = avatar; + _avatar = avatar; } QString ContactItem::getName() const diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index f066740..7eda17d 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -1,8 +1,11 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #ifndef CONTACTITEM_H #define CONTACTITEM_H #include #include +#include "mainwindow.h" using json = nlohmann::json; class ContactItem @@ -13,7 +16,7 @@ private: QString _name; QString _cid; QString _avatar; - + public: ContactItem(); ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar); diff --git a/src/addressbook.cpp b/src/addressbook.cpp index f51e279..808ca40 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -40,7 +40,10 @@ void AddressBookModel::loadData() QSettings().value( "addresstablegeometry" ).toByteArray() + + ); + } void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid, QString avatar) diff --git a/src/addressbook.h b/src/addressbook.h index 8e32fe8..fbd361b 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -23,6 +23,7 @@ public: 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: @@ -32,7 +33,8 @@ private: QTableView* parent; //QList> labels; QList labels; - QStringList headers; + QStringList headers; + }; class AddressBook { @@ -63,6 +65,10 @@ public: QString get_avatar_name(); void set_avatar_name(QString avatar_name); + + + + @@ -76,6 +82,7 @@ private: QString writeableFile(); QList allLabels; + static AddressBook* instance; }; diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b0acb38..7bc1688 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -71,6 +71,26 @@ void ChatModel::showMessages() } } + +void ChatModel::addAddressbylabel(QString address, QString label) +{ + this->AddressbyLabelMap[address] = label; +} + +QString ChatModel::Addressbylabel(QString address) +{ + for(auto& pair : this->AddressbyLabelMap) + { + + } + + if(this->AddressbyLabelMap.count(address) > 0) + { + return this->AddressbyLabelMap[address]; + } + + return QString("0xdeadbeef"); +} void MainWindow::renderContactRequest(){ @@ -89,17 +109,22 @@ void MainWindow::renderContactRequest(){ contactRequest->appendRow(Items); requestContact.requestContact->setModel(contactRequest); requestContact.requestContact->show(); + requestContact.zaddrnew->setVisible(false); + requestContact.zaddrnew->setText(c.second.getAddress()); } QStandardItemModel* contactRequestOld = new QStandardItemModel(); + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) { if (p.getPartnerAddress() == c.second.getRequestZaddr()) { - QStandardItem* Items = new QStandardItem(c.second.getAddress()); + QStandardItem* Items = new QStandardItem(p.getName()); contactRequestOld->appendRow(Items); requestContact.requestContactOld->setModel(contactRequestOld); + requestContact.zaddrold->setVisible(false); + requestContact.zaddrold->setText(c.second.getAddress()); requestContact.requestContactOld->show(); }else{} } @@ -135,11 +160,11 @@ void MainWindow::renderContactRequest(){ QObject::connect(requestContact.requestContactOld, &QTableView::clicked, [&] () { for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ - QModelIndex index = requestContact.requestContactOld->currentIndex(); - QString label_contactold = index.data(Qt::DisplayRole).toString(); + /* QModelIndex index = requestContact.requestContactOld->currentIndex(); + QString label_contactold = index.data(Qt::DisplayRole).toString();*/ QStandardItemModel* contactMemo = new QStandardItemModel(); - if ((c.second.isOutgoing() == false) && (label_contactold == c.second.getAddress()) && (c.second.getType() != "Cont")) + if ((c.second.isOutgoing() == false) && (requestContact.zaddrold->text() == c.second.getAddress()) && (c.second.getType() != "Cont")) { @@ -809,7 +834,7 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); if (available < total) { - return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") + return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 1 confirmations before they can be spent") .arg(available.toDecimalhushString(), total.toDecimalhushString()); } diff --git a/src/chatmodel.h b/src/chatmodel.h index 7ca5a0f..1768b9f 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -20,6 +20,7 @@ #include "Chat/Helper/ChatDelegator.h" #include "Chat/Helper/ChatIDGenerator.h" + namespace Ui { class MainWindow; } @@ -34,6 +35,7 @@ class ChatModel std::map requestZaddrMap; std::map confirmationsMap; std::map> sendrequestMap; + std::map AddressbyLabelMap; public: ChatModel() {}; @@ -46,6 +48,7 @@ class ChatModel void triggerRequest(); void showMessages(); void clear(); + void addAddressbylabel(QString addr, QString label); void addMessage(ChatItem item); void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); @@ -55,10 +58,11 @@ class ChatModel QString getCidByTx(QString tx); QString getrequestZaddrByTx(QString tx); QString getConfirmationByTx(QString tx); + QString Addressbylabel(QString addr); void killCidCache(); void killConfirmationCache(); void killrequestZaddrCache(); - + }; #endif \ No newline at end of file diff --git a/src/contactmodel.h b/src/contactmodel.h index f361ceb..5f79c47 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -15,8 +15,7 @@ class ContactModel ContactModel() {} void renderContactList(QListView* view); - - + }; #endif \ No newline at end of file diff --git a/src/controller.cpp b/src/controller.cpp index 10b41bb..83ee2e4 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -935,7 +935,8 @@ void Controller::refreshTransactions() { txid, confirmations, true, - isNotarized + isNotarized, + false ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); @@ -991,6 +992,28 @@ void Controller::refreshTransactions() { QString cid; int position; QString requestZaddr; + bool isContact; + + + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) + { + + if (p.getPartnerAddress() == requestZaddr) + { + + chatModel->addAddressbylabel(address, requestZaddr); + } else{} + + + if (chatModel->Addressbylabel(address) != QString("0xdeadbeef")){ + + isContact = true; + + }else{ + + isContact = false; + + } if (!it["memo"].is_null()) { @@ -1005,7 +1028,8 @@ void Controller::refreshTransactions() { chatModel->addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); - } + } + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ @@ -1045,16 +1069,16 @@ void Controller::refreshTransactions() { txid, confirmations, false, - isNotarized + isNotarized, + isContact ); - qDebug()<< "Notarized : " << isNotarized; - + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } } - + } } - qDebug()<< getLag(); + qDebug()<<"get Lag" << getLag(); // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds diff --git a/src/controller.h b/src/controller.h index f35d636..9fd445b 100644 --- a/src/controller.h +++ b/src/controller.h @@ -1,3 +1,6 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 + #ifndef RPCCLIENT_H #define RPCCLIENT_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index de2583e..7db28cf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1358,7 +1358,6 @@ void MainWindow::setupchatTab() { } }); - QMenu* contextMenu; QAction* requestAction; QAction* editAction; @@ -1397,7 +1396,6 @@ void MainWindow::setupchatTab() { for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) if (label_contact == p.getName()) { - QString label1 = p.getName(); QString addr = p.getPartnerAddress(); @@ -1407,7 +1405,6 @@ void MainWindow::setupchatTab() { AddressBook::getInstance()->removeAddressLabel(label1, addr, myzaddr, cid,avatar); - // QList labels = AddressBook::getInstance()->getAllAddressLabels(); rpc->refreshContacts( ui->listContactWidget); rpc->refresh(true); @@ -1424,13 +1421,11 @@ void MainWindow::updateChat() { rpc->refreshChat(ui->listChat,ui->memoSizeChat); rpc->refresh(true); - - } void MainWindow::updateContacts() { - //rpc->refreshContacts(ui->listContactWidget); + } void MainWindow::addNewZaddr(bool sapling) { diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 2eb4bc0..242e3ba 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -6,7 +6,7 @@ 0 0 - 812 + 850 495 @@ -27,7 +27,7 @@ - + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> @@ -97,12 +97,12 @@ - + 256 - 192 + 190 @@ -119,14 +119,21 @@ - + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + Request from : - + @@ -142,14 +149,14 @@ - + My Zaddr : - + @@ -165,24 +172,24 @@ - + Give a Nickname: - + - + <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> - + @@ -328,7 +335,7 @@ - + @@ -353,7 +360,7 @@ - + @@ -369,17 +376,24 @@ - + - - + + - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + + + + diff --git a/src/sendtab.cpp b/src/sendtab.cpp index de61cf2..ce04a54 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -937,7 +937,7 @@ QString MainWindow::doSendTxValidations(Tx tx) { auto available = rpc->getModel()->getAvailableBalance(); if (available < total) { - return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 5 confirmations before they can be spent") + return tr("Not enough available funds to send this transaction\n\nHave: %1\nNeed: %2\n\nNote: Funds need 1 confirmations before they can be spent") .arg(available.toDecimalhushString(), total.toDecimalhushString()); } From 8e59d777c2553bedb50bc75f173936f8e7ae7cfb Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 27 May 2020 22:53:41 +0200 Subject: [PATCH 165/253] dont save contact if contactrequest was not succesfull --- src/chatmodel.cpp | 142 ++++++++++++++-------------------------------- 1 file changed, 44 insertions(+), 98 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 7bc1688..5bd28d0 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -114,7 +114,7 @@ void MainWindow::renderContactRequest(){ } QStandardItemModel* contactRequestOld = new QStandardItemModel(); - + for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) { @@ -380,16 +380,12 @@ void MainWindow::sendChat() { // Create a Tx from the values on the send tab. Note that this Tx object // might not be valid yet. - - // Memos can only be used with zAddrs. So check that first - // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + QString Name = ui->contactNameMemo->text(); int sizename = Name.size(); qDebug()<< sizename; if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { - // auto addr = ""; - // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), QMessageBox::Ok, this); @@ -404,8 +400,6 @@ void MainWindow::sendChat() { if (size > max){ - // auto addr = ""; - // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"), tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 512 character."), QMessageBox::Ok, this); @@ -578,96 +572,7 @@ void::MainWindow::addContact() void MainWindow::saveandsendContact() { this->ContactRequest(); - QString addr = contactRequest.getReceiverAddress(); - QString newLabel = contactRequest.getLabel(); - QString myAddr = contactRequest.getSenderAddress(); - QString cid = contactRequest.getCid(); - QString avatar = contactRequest.getAvatar(); - contactRequest.clear(); - if (addr.isEmpty() || newLabel.isEmpty()) - { - QMessageBox::critical( - this, - QObject::tr("Address or Label Error"), - QObject::tr("Address or Label cannot be empty"), - QMessageBox::Ok - ); - return; - } - - // Test if address is valid. - if (!Settings::isValidAddress(addr)) - { - QMessageBox::critical( - this, - QObject::tr("Address Format Error"), - QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), - QMessageBox::Ok - ); - return; - } - - ///////Todo: Test if label allready exist! - - ////// Success, so show it - AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::information( - this, - QObject::tr("Added Contact"), - QObject::tr("successfully added your new contact").arg(newLabel), - QMessageBox::Ok - ); - return; - - - -} - -void MainWindow::saveContact() -{ - - QString addr = contactRequest.getReceiverAddress(); - QString newLabel = contactRequest.getLabel(); - QString myAddr = contactRequest.getSenderAddress(); - QString cid = contactRequest.getCid(); - QString avatar = contactRequest.getAvatar(); - - if (addr.isEmpty() || newLabel.isEmpty()) - { - QMessageBox::critical( - this, - QObject::tr("Address or Label Error"), - QObject::tr("Address or Label cannot be empty"), - QMessageBox::Ok - ); - return; - } - - // Test if address is valid. - if (!Settings::isValidAddress(addr)) - { - QMessageBox::critical( - this, - QObject::tr("Address Format Error"), - QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), - QMessageBox::Ok - ); - return; - } - - ///////Todo: Test if label allready exist! - - ////// Success, so show it - AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::information( - this, - QObject::tr("Added Contact"), - QObject::tr("successfully added your new contact").arg(newLabel), - QMessageBox::Ok - ); - return; - } // Create a Tx for a contact Request @@ -785,7 +690,46 @@ void MainWindow::ContactRequest() { delete d; }); - + QString addr = contactRequest.getReceiverAddress(); + QString newLabel = contactRequest.getLabel(); + QString myAddr = contactRequest.getSenderAddress(); + QString cid = contactRequest.getCid(); + QString avatar = contactRequest.getAvatar(); + + if (addr.isEmpty() || newLabel.isEmpty()) + { + QMessageBox::critical( + this, + QObject::tr("Address or Label Error"), + QObject::tr("Address or Label cannot be empty"), + QMessageBox::Ok + ); + return; + } + + // Test if address is valid. + if (!Settings::isValidAddress(addr)) + { + QMessageBox::critical( + this, + QObject::tr("Address Format Error"), + QObject::tr("%1 doesn't seem to be a valid hush address.").arg(addr), + QMessageBox::Ok + ); + return; + } + + ///////Todo: Test if label allready exist! + + ////// Success, so show it + AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); + QMessageBox::information( + this, + QObject::tr("Added Contact"), + QObject::tr("successfully added your new contact").arg(newLabel), + QMessageBox::Ok + ); + return; // Force a UI update so we get the unconfirmed Tx // rpc->refresh(true); ui->memoTxtChat->clear(); @@ -840,3 +784,5 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { return ""; } + + From a2e68c9cc23bd1fdfd810a2efa4db438433aab2c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 00:23:48 +0200 Subject: [PATCH 166/253] add new logo for unknown sender --- application.qrc | 6 ++---- res/getAddrBlack.png | Bin 20966 -> 20691 bytes res/getAddrWhite.png | Bin 12887 -> 12615 bytes res/unknownBlack.png | Bin 0 -> 21025 bytes res/unknownWhite.png | Bin 0 -> 12617 bytes res/unlocked.svg | 7 ------- res/upload.png | Bin 1369 -> 0 bytes res/upload.svg | 8 -------- src/chatmodel.cpp | 25 +++++++++++++++++++++++-- 9 files changed, 25 insertions(+), 21 deletions(-) create mode 100644 res/unknownBlack.png create mode 100644 res/unknownWhite.png delete mode 100644 res/unlocked.svg delete mode 100644 res/upload.png delete mode 100644 res/upload.svg diff --git a/application.qrc b/application.qrc index e2da53c..bb3c02c 100644 --- a/application.qrc +++ b/application.qrc @@ -33,11 +33,7 @@ res/add_contact.png res/notification.png res/rahmen-message.png - res/upload.png - res/upload.svg res/message-icon.svg - res/lock.svg - res/lock.png res/lock_green.png res/lock_orange.png res/unlocked.png @@ -49,6 +45,8 @@ res/sendBlack.png res/requestBlack.png res/addContactBlack.png + res/unknownBlack.png + res/unknownWhite.png diff --git a/res/getAddrBlack.png b/res/getAddrBlack.png index 2ede956ed1f29f52bffb24c124c26dda23c479ab..d90c9a522937a6c0270e9078bfb6fba62846ceed 100644 GIT binary patch literal 20691 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%0Ag)8KZtd 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 ab|vNW;h(G-u@8fPCX7!>JUC8X{Qm(Zf7iAE diff --git a/res/getAddrWhite.png b/res/getAddrWhite.png index 6caeeae319540c6c3bbc1b0b91af02aa7e042a72..28b30fbaeb67d543d56382775706b8fae81d3fba 100644 GIT binary patch literal 12615 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 diff --git a/res/unknownBlack.png b/res/unknownBlack.png new file mode 100644 index 0000000000000000000000000000000000000000..faf65e0eeb0c6b8e08a7cfdd172801dea0812cc0 GIT binary patch literal 21025 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 - - - - Svg Vector Icons : http://www.onlinewebfonts.com/icon - - diff --git a/res/upload.png b/res/upload.png deleted file mode 100644 index b6f3c1fc0fe0d3f6b4bef72ec66a3bcd4d3dc2b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1369 zcmeAS@N?(olHy`uVBq!ia0vp^w;321WjNS?EI-MEKY*N;OlRi+PiJR^f};Gi%$!sP z291fe6Ky>XJIEZ356*Vg;wuv|5lX0FZ|9Y@G5m#q-=7-vfF7^GX*y9 z6gB+QC154!%A;(wxhK-o>tK1!UF8GUcUzqQWdHs7i@?uf%uGrjd5nE#SIn)*x@>0g zUf4a-GpzG`r@QYig^$YDMf>kth{uXmq+L0)03F=@2AtX zvGzaY|Gc}V<mW zgs+r-@IXL9FX-E>^SgK7s{Z}mXY+pfqN7F2cV#rC0HcL1$=lt9;Xep2*t>i(P=vF< zBeED6gV#Zr(Me-=1yGQ^#M9T6{Ru0Zh#KGI!)@XW49sDkE{-7;x8B~}$jfZV!{Rvi z_xs4cn5Oe}MQTA>T-;3aYxw$$-tV1XJZZ*>;)*rxZE6-919^N4k`_zMdT_+e(Bxoe zZ&F5+u=LRjEb3-m3pxFAM4W}^+|a#23w$Lv5^yGzEqPiL;$4K z8DgQD3DgN-t!)pWW^v?&Lrgz*>46ehiJ{gG4zQ^`TzX*5Qj43qF9-k~aBKyBC3hYH z)f@q-*=}IA(9jZOj&7H4Mh*waAa0<$W`j(+^8l#q7)Y5pP}xSXvQnVL0^yhzwz)v@ z7cAln9o2!ltq!_oT;SAmYW6D-lq#XF5?OuahD&9)s|uz6+S^Ip$Z5FY0LBVt4ml7k zAgy2q!5zE;(hz)vt%DbWlbDaNLGVV#BxW#fyuq*$f+0qMjHIz~z+{gDJfBkxOxed6 r?mzzzbOh8NXE|UlBE@s4HvF*8f8(*Ycx^~XAV|W~)z4*}Q$iB}e1!gF diff --git a/res/upload.svg b/res/upload.svg deleted file mode 100644 index 9f31b60..0000000 --- a/res/upload.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 5bd28d0..ee3fe6d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -99,18 +99,39 @@ void MainWindow::renderContactRequest(){ requestContact.setupUi(&dialog); Settings::saveRestore(&dialog); + QString icon; + auto theme = Settings::getInstance()->get_theme_name(); + if (theme == "dark" || theme == "midnight") { + icon = ":/icons/res/unknownWhite.png"; + }else{ + icon = ":/icons/res/unknownBlack.png"; + } + + QPixmap unknownWhite(icon); + QIcon addnewAddrIcon(unknownWhite); + + + + QStandardItemModel* contactRequest = new QStandardItemModel(); for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) + + { - QStandardItem* Items = new QStandardItem(c.second.getAddress()); + QStandardItem* Items = new QStandardItem(QString("Unknown Sender")); contactRequest->appendRow(Items); requestContact.requestContact->setModel(contactRequest); + + Items->setData(QIcon(addnewAddrIcon),Qt::DecorationRole); + requestContact.requestContact->setIconSize(QSize(40,50)); + requestContact.requestContact->setUniformItemSizes(true); requestContact.requestContact->show(); requestContact.zaddrnew->setVisible(false); requestContact.zaddrnew->setText(c.second.getAddress()); + } QStandardItemModel* contactRequestOld = new QStandardItemModel(); @@ -137,7 +158,7 @@ void MainWindow::renderContactRequest(){ QString label_contact = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); - if ((c.second.isOutgoing() == false) && (label_contact == c.second.getAddress()) && (c.second.getType() != "Cont")) + if ((c.second.isOutgoing() == false) && (requestContact.zaddrnew->text() == c.second.getAddress()) && (c.second.getType() != "Cont")) { From a02ee09241799febdb54e42fd35c464a95501a1e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 00:30:02 +0200 Subject: [PATCH 167/253] fix place of gui element --- src/requestContactDialog.ui | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 242e3ba..d4420ea 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -376,13 +376,6 @@ - - - - - - - @@ -397,6 +390,13 @@ + + + + + + + From 76a7776e7385b2cbd5c8ac8748fd63392c78a76a Mon Sep 17 00:00:00 2001 From: Denio <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 15:39:40 +0200 Subject: [PATCH 168/253] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a36f828..31d4041 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ SilentDragonLite does automatic note and utxo management, which means it doesn't ## Compiling from source * SilentDragonLite 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). -* You'll need Rust v1.37 + +* You'll need Rust v1.41 + ## Building on Linux From 0333d502ed312a607f342566351f412db8fb5810 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 16:24:55 +0200 Subject: [PATCH 169/253] fix deps --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index c2021b0..01613d0 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1daf5ce75fcbd51047360681652f173f93f54f93)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=1daf5ce75fcbd51047360681652f173f93f54f93#1daf5ce75fcbd51047360681652f173f93f54f93" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359#32ca60735b3529ff8589ab08fc16678f508a9359" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=1daf5ce75fcbd51047360681652f173f93f54f93)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 15e0acd..fba5265 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "1daf5ce75fcbd51047360681652f173f93f54f93" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "32ca60735b3529ff8589ab08fc16678f508a9359" } From 1efbfa342fb72fdc017f773fa5c70123d21789a6 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 16:25:51 +0200 Subject: [PATCH 170/253] fix deps --- res/unkownBlack.png | Bin 0 -> 21025 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/unkownBlack.png diff --git a/res/unkownBlack.png b/res/unkownBlack.png new file mode 100644 index 0000000000000000000000000000000000000000..faf65e0eeb0c6b8e08a7cfdd172801dea0812cc0 GIT binary patch literal 21025 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 Date: Thu, 28 May 2020 16:44:12 +0200 Subject: [PATCH 171/253] switch back to sdl-cli 1.0 --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 01613d0..e0ea0c9 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359#32ca60735b3529ff8589ab08fc16678f508a9359" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763#d196ad938a22810c0b6b4164e6bf8f1db0409763" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=32ca60735b3529ff8589ab08fc16678f508a9359)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index fba5265..dba0c30 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "32ca60735b3529ff8589ab08fc16678f508a9359" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d196ad938a22810c0b6b4164e6bf8f1db0409763" } From 01737a5dfafc8f44612af3413535b2023edbd648 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.notfound> Date: Thu, 28 May 2020 19:31:34 +0200 Subject: [PATCH 172/253] update// added read fix --- src/FileSystem/FileSystem.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 208bfaa..07d476c 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -100,12 +100,29 @@ QList FileSystem::readContactsOldFormat(QString file) in >> version; qDebug() << "Read " << version << " Hush contacts from disk..."; qDebug() << "Detected old addressbook format"; - QList> stuff; - in >> stuff; - for (int i=0; i < stuff.size(); i++) + if(in.status() == QDataStream::ReadCorruptData) { - ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); - contacts.push_back(contact); + qDebug() << "Error reading contacts! ---> Your hush contacts from disk maybe corrupted"; + QFile::rename(file, file + QString(".corrupted")); + QMessageBox::critical( + nullptr, + QObject::tr("Error reading contacts!"), + QObject::tr("Your hush contacts from disk maybe corrupted"), + QMessageBox::Ok + ); + } + else + { + qDebug() << "Read " << version << " Hush contacts from disk..."; + QList> stuff; + in >> stuff; + for (int i=0; i < stuff.size(); i++) + { + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + contacts.push_back(contact); + } + + qDebug() << "Hush contacts readed from disk..."; } _file.close(); From 47d11fc5c8b1b74dc0af115879466161e0aaca17 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.notfound> Date: Thu, 28 May 2020 19:57:22 +0200 Subject: [PATCH 173/253] update// added backwarts compat on addresses --- src/Model/ContactItem.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index 7eda17d..861ad26 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -11,11 +11,11 @@ using json = nlohmann::json; class ContactItem { private: - QString _myAddress; - QString _partnerAddress; - QString _name; - QString _cid; - QString _avatar; + QString _myAddress = ""; + QString _partnerAddress = ""; + QString _name = ""; + QString _cid = ""; + QString _avatar = ":/icons/res/sdlogo.png"; public: ContactItem(); From 54deb0cb2688528eb67a527de641bff23f1207f0 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.notfound> Date: Thu, 28 May 2020 20:09:23 +0200 Subject: [PATCH 174/253] update// added backwarts compat on addresses --- src/FileSystem/FileSystem.cpp | 19 ++++++++++++++++++- src/Model/ContactItem.cpp | 14 ++++++++++++++ src/Model/ContactItem.h | 2 ++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 07d476c..4d3f146 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -118,7 +118,24 @@ QList FileSystem::readContactsOldFormat(QString file) in >> stuff; for (int i=0; i < stuff.size(); i++) { - ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + qDebug() << stuff[i].size(); + ContactItem contact; + if(stuff[i].size() == 2) + { + contact = ContactItem(stuff[i][0],stuff[i][1]); + + } + else if(stuff[i].size() == 4) + { + contact = ContactItem(stuff[i][0],stuff[i][1]); + + } + else + { + contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + } + + contacts.push_back(contact); } diff --git a/src/Model/ContactItem.cpp b/src/Model/ContactItem.cpp index d2321bd..589ca9f 100644 --- a/src/Model/ContactItem.cpp +++ b/src/Model/ContactItem.cpp @@ -7,6 +7,20 @@ ContactItem::ContactItem() {} +ContactItem::ContactItem(QString name, QString partnerAddress) +{ + _name = name; + _partnerAddress = partnerAddress; +} + +ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid) +{ + _name = name; + _myAddress = myAddress; + _partnerAddress = partnerAddress; + _cid = cid; +} + ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar) { _name = name; diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index 861ad26..edb512d 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -19,6 +19,8 @@ private: public: ContactItem(); + ContactItem(QString name, QString partnerAddress); + ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid); ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar); QString getName() const; QString getMyAddress() const; From 5e9c7fa5ee9118ae98d7ba0e187e8a3770d541ae Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.notfound> Date: Thu, 28 May 2020 20:13:13 +0200 Subject: [PATCH 175/253] update// address improvement --- src/FileSystem/FileSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 4d3f146..92f5bb8 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -127,7 +127,7 @@ QList FileSystem::readContactsOldFormat(QString file) } else if(stuff[i].size() == 4) { - contact = ContactItem(stuff[i][0],stuff[i][1]); + contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3]); } else From 4413d3de62a1504c27f94ba7a8462f5dd8faecd2 Mon Sep 17 00:00:00 2001 From: Strider <127.0.0.1@404.notfound> Date: Thu, 28 May 2020 20:45:30 +0200 Subject: [PATCH 176/253] update// address improvement --- .gdb_history | 5 ++ peda-session-SilentDragonLite.txt | 2 +- src/FileSystem/FileSystem.cpp | 84 ++++++++++++++++++------------- src/addressbook.cpp | 5 -- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/.gdb_history b/.gdb_history index 06f6849..4846c14 100644 --- a/.gdb_history +++ b/.gdb_history @@ -54,3 +54,8 @@ r s n q +b FileSystem::readContactsOldFormat +r +n +c +q diff --git a/peda-session-SilentDragonLite.txt b/peda-session-SilentDragonLite.txt index 6f620bf..12c5dfb 100644 --- a/peda-session-SilentDragonLite.txt +++ b/peda-session-SilentDragonLite.txt @@ -1,2 +1,2 @@ -break FileEncryption::encrypt +break FileSystem::readContactsOldFormat diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index 92f5bb8..f7d37be 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -83,7 +83,7 @@ void FileSystem::writeContactsOldFormat(QString file, QList contact c.push_back(item.getAvatar()); _contacts.push_back(c); } - out << QString("v1") << _contacts; + out << QString("v2") << _contacts; _file.close(); } @@ -96,52 +96,68 @@ QList FileSystem::readContactsOldFormat(QString file) contacts.clear(); _file.open(QIODevice::ReadOnly); QDataStream in(&_file); // read the data serialized from the file - QString version; - in >> version; - qDebug() << "Read " << version << " Hush contacts from disk..."; - qDebug() << "Detected old addressbook format"; if(in.status() == QDataStream::ReadCorruptData) { - qDebug() << "Error reading contacts! ---> Your hush contacts from disk maybe corrupted"; - QFile::rename(file, file + QString(".corrupted")); - QMessageBox::critical( - nullptr, - QObject::tr("Error reading contacts!"), - QObject::tr("Your hush contacts from disk maybe corrupted"), - QMessageBox::Ok - ); + qDebug() << "Error reading contacts! ---> Your hush contacts from disk maybe corrupted"; + QFile::rename(file, file + QString(".corrupted")); + QMessageBox::critical( + nullptr, + QObject::tr("Error reading contacts!"), + QObject::tr("Your hush contacts from disk maybe corrupted"), + QMessageBox::Ok + ); } - else + else { - qDebug() << "Read " << version << " Hush contacts from disk..."; - QList> stuff; - in >> stuff; - for (int i=0; i < stuff.size(); i++) + QString version; + in >> version; + if(version == "v1") { - qDebug() << stuff[i].size(); - ContactItem contact; - if(stuff[i].size() == 2) + qDebug() << "Detected old addressbook format"; + // Convert old addressbook format v1 to v2 + QList> stuff; + in >> stuff; + qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) { - contact = ContactItem(stuff[i][0],stuff[i][1]); - - } - else if(stuff[i].size() == 4) - { - contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3]); - - } - else - { - contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + ContactItem contact = ContactItem(stuff[i].first, stuff[i].second); + contacts.push_back(contact); + qDebug() << "contact=" << contact.toQTString(); } + } + else + { + qDebug() << "Read " << version << " Hush contacts from disk..."; + QList> stuff; + in >> stuff; + qDebug() << "Dataarray size: " << stuff.size(); + if(stuff.size() == 0) + return contacts; + + for (int i= 0; i < stuff.size(); i++) + { + qDebug() << stuff[i].size(); + ContactItem contact; + if(stuff[i].size() == 4) + { + contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3]); + } + else + { + contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + } + + qDebug() << contact.toQTString(); + contacts.push_back(contact); + } + - contacts.push_back(contact); } qDebug() << "Hush contacts readed from disk..."; } - + _file.close(); } else diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 808ca40..6d7f913 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -417,12 +417,7 @@ void AddressBook::readFromStorage() allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); // test to see if the contact items in datastore are correctly dumped to json - for(ContactItem item: allLabels) - { - DataStore::getContactDataStore()->setData(item.getCid(), item); - } DataStore::getContactDataStore()->dump(); - AddressBook::writeToStorage(); } void AddressBook::writeToStorage() From e21a02a510e5a8274954030067cbbc3e3ab667df Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 21:05:54 +0200 Subject: [PATCH 177/253] change error message if sdl has no connection --- src/controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controller.cpp b/src/controller.cpp index 83ee2e4..17f80bc 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -563,7 +563,7 @@ void Controller::getInfoThenRefresh(bool force) QMessageBox::critical( main, QObject::tr("Connection Error"), - QObject::tr("There was an error connecting to hushd. The error was") + ": \n\n"+ err, + QObject::tr("There was an error connecting to the server. Please check your internet connection. The error was") + ": \n\n"+ err, QMessageBox::StandardButton::Ok ); shown = false; From c298b8a63cf62511569475dc8dcb21c841305abe Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 21:08:52 +0200 Subject: [PATCH 178/253] change default theme to dark --- src/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7db28cf..27c567e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -59,7 +59,7 @@ MainWindow::MainWindow(QWidget *parent) : } catch (...) { - theme_name = "default"; + theme_name = "dark"; } this->slot_change_theme(theme_name); @@ -1823,7 +1823,7 @@ void MainWindow::slot_change_theme(const QString& theme_name) } catch (...) { - saved_theme_name = "default"; + saved_theme_name = "dark"; } QFile qFile(":/css/res/css/" + saved_theme_name +".css"); From 83dc3b5135251bee968ae5d262420f91c21ff4e4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 28 May 2020 21:30:21 +0200 Subject: [PATCH 179/253] make sd-logo default for a new contact --- src/addressbook.ui | 52 ++++++++++++++-------------- src/contactrequest.ui | 68 ++++++++++++++++++------------------- src/requestContactDialog.ui | 52 ++++++++++++++-------------- 3 files changed, 86 insertions(+), 86 deletions(-) diff --git a/src/addressbook.ui b/src/addressbook.ui index f7877bf..1bcf214 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -65,31 +65,11 @@ - Stag + SDLogo - :/icons/res/Stag.png - - - - - - Elsa - - - - :/icons/res/Elsa.png - - - - - - Denio - - - - :/icons/res/Denio.png + :/icons/res/sdlogo.png @@ -105,11 +85,11 @@ - Yoda + Denio - :/icons/res/Yoda.png + :/icons/res/Denio.png @@ -133,6 +113,26 @@ + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + Garflied @@ -185,11 +185,11 @@ - SDLogo + Stag - :/icons/res/sdlogo2.png + :/icons/res/Stag.png diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 1e37ee9..cd4120b 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -38,31 +38,11 @@ - Stag + SDLogo - :/icons/res/Stag.png - - - - - - Elsa - - - - :/icons/res/Elsa.png - - - - - - Denio - - - - :/icons/res/Denio.png + :/icons/res/sdlogo.png @@ -78,11 +58,11 @@ - Yoda + Denio - :/icons/res/Yoda.png + :/icons/res/Denio.png @@ -96,6 +76,16 @@ + + + Stag + + + + :/icons/res/Stag.png + + + Sharpee @@ -106,6 +96,26 @@ + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + Garfield @@ -156,16 +166,6 @@ - - - SDLogo - - - - :/icons/res/sdlogo2.png - - - diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index d4420ea..f8cb244 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -205,31 +205,11 @@ - Stag + SDLogo - :/icons/res/Stag.png - - - - - - Elsa - - - - :/icons/res/Elsa.png - - - - - - Denio - - - - :/icons/res/Denio.png + :/icons/res/sdlogo.png @@ -245,11 +225,11 @@ - Yoda + Denio - :/icons/res/Yoda.png + :/icons/res/Denio.png @@ -273,6 +253,26 @@ + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + Garfield @@ -325,11 +325,11 @@ - SDLogo + Stag - :/icons/res/sdlogo2.png + :/icons/res/Stag.png From 854b14df6a744733e6052d8582887f15226d0941 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 30 May 2020 14:12:17 +0200 Subject: [PATCH 180/253] unready code for mmessage encryption --- src/chatmodel.cpp | 231 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 230 insertions(+), 1 deletion(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index ee3fe6d..445a6f1 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -374,7 +374,236 @@ Tx MainWindow::createTxFromChatPage() { QString hmemo= createHeaderMemo(type,cid,myAddr); - QString memo = ui->memoTxtChat->toPlainText().trimmed(); + QString memounencrypt = ui->memoTxtChat->toPlainText().trimmed(); + + + int length = memounencrypt.length(); + + char *sequence = NULL; + sequence = new char[length+1]; + strncpy(sequence, memounencrypt.toLocal8Bit(), length +1); + +////////////////////////////////////////////////////Important: If we can decrypt the output of QString memo, after we encrypt it, Bobs code must be in Controller.cpp + + /////////////////Alice Pubkey + #define MESSAGEAP ((const unsigned char *) "Ioesd") + #define MESSAGEAP_LEN 5 + + unsigned char alice_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_generichash(alice_publickey, sizeof alice_publickey, + MESSAGEAP, MESSAGEAP_LEN, + NULL, 0); + QString alice = QString::fromLocal8Bit((char*)alice_publickey); + qDebug()<<"Alice Pubkey : "<(c1), CIPHERTEXT_LEN); + + qDebug()<<"Size Controller Memo :"<< encryptedMemo.length(); + + QString memo = QString::fromUtf8( encryptedMemo.data(), encryptedMemo.size()); + + + /////////////////Bob Pubkey + #define MESSAGEBAP1 ((const unsigned char *) "Hal12") + #define MESSAGEBAP1_LEN 5 + + unsigned char bob1_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_generichash(bob1_publickey, sizeof bob1_publickey, + MESSAGEBAP1, MESSAGEBAP1_LEN, + NULL, 0); + + qDebug()<<"Bobs Pubkey created"; + + /////////////////Bob Secretkey + #define MESSAGEBS ((const unsigned char *) "Hal11") + #define MESSAGEBS_LEN 5 + + unsigned char bob_secretkey[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + + crypto_generichash(bob_secretkey, sizeof bob_secretkey, + MESSAGEBS, MESSAGEBS_LEN, + NULL, 0); + + qDebug()<<"Bobs Pubkey created"; + + /////////////////Alice Pubkey bob creates + #define MESSAGEA121 ((const unsigned char *) "Ioesd") + #define MESSAGEAP121_LEN 5 + + unsigned char alice1_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_generichash(alice1_publickey, sizeof alice1_publickey, + MESSAGEA121, MESSAGEAP121_LEN, + NULL, 0); + + QString alice1 = QString::fromLocal8Bit((char*)alice1_publickey); + qDebug()<<"Alice Pubkey Bob create: "<(m2),MESSAGE_LEN); + qDebug()<<"7: "; + QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + + + + qDebug()<<"OUT decrypt:" << memodecrypt; From b67d304b66a9db782a9d6e72b2f3017ef7e0a7d0 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 30 May 2020 21:43:04 +0200 Subject: [PATCH 181/253] undo addressbooklabels storage in filesystem --- src/FileSystem/FileSystem.cpp | 86 +++++++---------------------------- src/Model/ContactItem.h | 10 ++-- src/addressbook.cpp | 19 +++++--- 3 files changed, 34 insertions(+), 81 deletions(-) diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index f7d37be..d31d5f4 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -1,11 +1,7 @@ -// Copyright 2019-2020 The Hush developers -// GPLv3 - #include "FileSystem.h" + #include #include -#include "../Crypto/passwd.h" -#include "addressbook.h" FileSystem::FileSystem() { @@ -23,9 +19,9 @@ FileSystem* FileSystem::getInstance() return FileSystem::instance; } -QList FileSystem::readContacts(QString file) +/*QList FileSystem::readContacts(QString file) { - return this->readContactsOldFormat(file); //will be called if addresses are in the old dat-format + //return this->readContactsOldFormat(file); //will be called if addresses are in the old dat-format QFile _file(file); if (_file.exists()) @@ -83,7 +79,7 @@ void FileSystem::writeContactsOldFormat(QString file, QList contact c.push_back(item.getAvatar()); _contacts.push_back(c); } - out << QString("v2") << _contacts; + out << QString("v0") << _contacts; _file.close(); } @@ -96,68 +92,20 @@ QList FileSystem::readContactsOldFormat(QString file) contacts.clear(); _file.open(QIODevice::ReadOnly); QDataStream in(&_file); // read the data serialized from the file - if(in.status() == QDataStream::ReadCorruptData) + QString version; + in >> version; + qDebug() << "Read " << version << " Hush contacts from disk..."; + qDebug() << "Detected old addressbook format"; + QList> stuff; + in >> stuff; + //qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) { - qDebug() << "Error reading contacts! ---> Your hush contacts from disk maybe corrupted"; - QFile::rename(file, file + QString(".corrupted")); - QMessageBox::critical( - nullptr, - QObject::tr("Error reading contacts!"), - QObject::tr("Your hush contacts from disk maybe corrupted"), - QMessageBox::Ok - ); + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + contacts.push_back(contact); + i++; } - else - { - QString version; - in >> version; - if(version == "v1") - { - qDebug() << "Detected old addressbook format"; - // Convert old addressbook format v1 to v2 - QList> stuff; - in >> stuff; - qDebug() << "Stuff: " << stuff; - for (int i=0; i < stuff.size(); i++) - { - ContactItem contact = ContactItem(stuff[i].first, stuff[i].second); - contacts.push_back(contact); - qDebug() << "contact=" << contact.toQTString(); - } - - } - else - { - qDebug() << "Read " << version << " Hush contacts from disk..."; - QList> stuff; - in >> stuff; - qDebug() << "Dataarray size: " << stuff.size(); - if(stuff.size() == 0) - return contacts; - - for (int i= 0; i < stuff.size(); i++) - { - qDebug() << stuff[i].size(); - ContactItem contact; - if(stuff[i].size() == 4) - { - contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3]); - } - else - { - contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); - } - - qDebug() << contact.toQTString(); - contacts.push_back(contact); - } - - - } - - qDebug() << "Hush contacts readed from disk..."; - } - + _file.close(); } else @@ -173,7 +121,7 @@ FileSystem::~FileSystem() this->instance = nullptr; this->instanced = false; delete this->instance; -} +}*/ FileSystem *FileSystem::instance = nullptr; bool FileSystem::instanced = false; \ No newline at end of file diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index edb512d..63b4b39 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -11,11 +11,11 @@ using json = nlohmann::json; class ContactItem { private: - QString _myAddress = ""; - QString _partnerAddress = ""; - QString _name = ""; - QString _cid = ""; - QString _avatar = ":/icons/res/sdlogo.png"; + QString _myAddress; + QString _partnerAddress; + QString _name; + QString _cid; + QString _avatar; public: ContactItem(); diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 6d7f913..28a0f9e 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -380,7 +380,7 @@ AddressBook::AddressBook() void AddressBook::readFromStorage() { - /*QFile file(AddressBook::writeableFile()); + QFile file(AddressBook::writeableFile()); if (file.exists()) { @@ -413,21 +413,26 @@ void AddressBook::readFromStorage() { qDebug() << "No Hush contacts found on disk!"; } - }*/ - allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); + } + // allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); // test to see if the contact items in datastore are correctly dumped to json - DataStore::getContactDataStore()->dump(); + for(ContactItem item: allLabels) + { + DataStore::getContactDataStore()->setData(item.getCid(), item); + } + + AddressBook::writeToStorage(); } void AddressBook::writeToStorage() { //FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), DataStore::getContactDataStore()->dump()); - FileSystem::getInstance()->writeContactsOldFormat(AddressBook::writeableFile(), allLabels); + // FileSystem::getInstance()->writeContactsOldFormat(AddressBook::writeableFile(), allLabels); - /*QFile file(AddressBook::writeableFile()); + QFile file(AddressBook::writeableFile()); file.open(QIODevice::ReadWrite | QIODevice::Truncate); QDataStream out(&file); // we will serialize the data into the file QList> contacts; @@ -442,7 +447,7 @@ void AddressBook::writeToStorage() contacts.push_back(c); } out << QString("v1") << contacts; - file.close();*/ + file.close(); } QString AddressBook::writeableFile() From 030443393f2ccf0d1e9ce28e6e6c50f23a2b1e14 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 30 May 2020 22:46:57 +0200 Subject: [PATCH 182/253] rename sdlogo, refresh at new contact --- application.qrc | 2 +- lib/Cargo.lock | 6 ++--- lib/Cargo.toml | 2 +- res/{sdlogo.png => SDLogo.png} | Bin src/FileSystem/FileSystem.cpp | 2 +- src/addressbook.cpp | 42 +++++++++++++++++---------------- src/chatmodel.cpp | 34 +++++++++++++++++--------- 7 files changed, 51 insertions(+), 37 deletions(-) rename res/{sdlogo.png => SDLogo.png} (100%) diff --git a/application.qrc b/application.qrc index bb3c02c..d62ea29 100644 --- a/application.qrc +++ b/application.qrc @@ -9,7 +9,7 @@ res/icon.ico res/mail.png res/darkwing.png - res/sdlogo.png + res/SDLogo.png res/sdlogo2.png res/Berg.png res/Denio.png diff --git a/lib/Cargo.lock b/lib/Cargo.lock index e0ea0c9..d1c7722 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)", + "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763#d196ad938a22810c0b6b4164e6bf8f1db0409763" +source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0#d2887d07879a93bdd9b2c8bd12504bb977e82fe0" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d196ad938a22810c0b6b4164e6bf8f1db0409763)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index dba0c30..d46b55f 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d196ad938a22810c0b6b4164e6bf8f1db0409763" } +silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d2887d07879a93bdd9b2c8bd12504bb977e82fe0" } diff --git a/res/sdlogo.png b/res/SDLogo.png similarity index 100% rename from res/sdlogo.png rename to res/SDLogo.png diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp index d31d5f4..055ca88 100644 --- a/src/FileSystem/FileSystem.cpp +++ b/src/FileSystem/FileSystem.cpp @@ -103,7 +103,7 @@ QList FileSystem::readContactsOldFormat(QString file) { ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); contacts.push_back(contact); - i++; + } _file.close(); diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 28a0f9e..591a9c0 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -39,9 +39,7 @@ void AddressBookModel::loadData() parent->horizontalHeader()->restoreState( QSettings().value( "addresstablegeometry" - ).toByteArray() - - + ).toByteArray() ); } @@ -241,9 +239,14 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) return; - rpc->refresh(true); + // rpc->refresh(true); model.updateUi(); + rpc->refreshContacts( + parent->ui->listContactWidget + + ); + }); // AddressBook::getInstance()->addAddressLabel(newLabel, ab.addr->text(), cid); @@ -394,37 +397,36 @@ void AddressBook::readFromStorage() QList> stuff; in >> stuff; //qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) { - //qDebug() << "0:" << stuff[i][0]; + //qDebug() << "0:" << stuff[i][0]; //qDebug() << "1:" << stuff[i][1]; //qDebug() << "2:" << stuff[i][2]; ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); //qDebug() << "contact=" << contact.toQTString(); allLabels.push_back(contact); } - - { - qDebug() << "Read " << version << " Hush contacts from disk..."; - + + qDebug() << "Read " << version << " Hush contacts from disk..."; file.close(); } - }else{ - { - qDebug() << "No Hush contacts found on disk!"; - } - } - // allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); - - // test to see if the contact items in datastore are correctly dumped to json - for(ContactItem item: allLabels) + else { - DataStore::getContactDataStore()->setData(item.getCid(), item); + qDebug() << "No Hush contacts found on disk!"; } - AddressBook::writeToStorage(); + // Special. + // Add the default silentdragon donation address if it isn't already present + // QList allAddresses; + // std::transform(allLabels.begin(), allLabels.end(), + // std::back_inserter(allAddresses), [=] (auto i) { return i.getPartnerAddress(); }); + // if (!allAddresses.contains(Settings::getDonationAddr(true))) { + // allLabels.append(QPair("silentdragon donation", Settings::getDonationAddr(true))); + // } } + void AddressBook::writeToStorage() { //FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), DataStore::getContactDataStore()->dump()); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index ee3fe6d..3e15300 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -240,16 +240,18 @@ void MainWindow::renderContactRequest(){ qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); - QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); + QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); + rpc->refreshContacts( + ui->listContactWidget + + ); + }); dialog.exec(); - rpc->refreshContacts( - ui->listContactWidget - - ); + } void ChatModel::addCid(QString tx, QString cid) @@ -374,10 +376,7 @@ Tx MainWindow::createTxFromChatPage() { QString hmemo= createHeaderMemo(type,cid,myAddr); - QString memo = ui->memoTxtChat->toPlainText().trimmed(); - - - + QString memo = ui->memoTxtChat->toPlainText().trimmed(); tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); @@ -547,7 +546,8 @@ void::MainWindow::addContact() request.setupUi(&dialog); Settings::saveRestore(&dialog); - + try + { bool sapling = true; rpc->createNewZaddr(sapling, [=] (json reply) { QString myAddr = QString::fromStdString(reply.get()[0]); @@ -557,8 +557,20 @@ void::MainWindow::addContact() ui->listReceiveAddresses->setCurrentIndex(0); qDebug() << "new generated myAddr add Contact" << myAddr; }); + + }catch(...) + { + + + qDebug() << QString("Caught something nasty with myZaddr Contact"); + } + + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + + + - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); + From 715317087f4878ec83bd8c41e28f9f51b205dd38 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 30 May 2020 23:09:35 +0200 Subject: [PATCH 183/253] refresh when a new contact get add --- src/chatmodel.cpp | 28 ++++++++++++---------------- src/controller.cpp | 8 +------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 3e15300..770e93c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -239,19 +239,15 @@ void MainWindow::renderContactRequest(){ qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); + rpc->refreshContacts( + ui->listContactWidget); QMessageBox::information(this, "Added Contact","successfully added your new contact. You can now Chat with this contact"); - rpc->refreshContacts( - ui->listContactWidget - - ); - }); dialog.exec(); - } void ChatModel::addCid(QString tx, QString cid) @@ -565,15 +561,7 @@ void::MainWindow::addContact() qDebug() << QString("Caught something nasty with myZaddr Contact"); } - QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); - - - - - - - - + QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); QObject::connect(request.sendRequestButton, &QPushButton::clicked, [&] () { @@ -723,7 +711,10 @@ void MainWindow::ContactRequest() { delete d; }); - QString addr = contactRequest.getReceiverAddress(); + + /////Add this contact after we sent the request + + QString addr = contactRequest.getReceiverAddress(); QString newLabel = contactRequest.getLabel(); QString myAddr = contactRequest.getSenderAddress(); QString cid = contactRequest.getCid(); @@ -756,17 +747,22 @@ void MainWindow::ContactRequest() { ////// Success, so show it AddressBook::getInstance()->addAddressLabel(newLabel, addr, myAddr, cid, avatar); + rpc->refreshContacts( + ui->listContactWidget); QMessageBox::information( this, QObject::tr("Added Contact"), QObject::tr("successfully added your new contact").arg(newLabel), QMessageBox::Ok + ); return; // Force a UI update so we get the unconfirmed Tx // rpc->refresh(true); ui->memoTxtChat->clear(); rpc->refresh(true); + rpc->refreshContacts( + ui->listContactWidget); }, // Errored out diff --git a/src/controller.cpp b/src/controller.cpp index 17f80bc..0c79240 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -922,8 +922,6 @@ void Controller::refreshTransactions() { isNotarized = false; } - qDebug()<<"Conf : " << confirmations; - ChatItem item = ChatItem( datetime, address, @@ -1078,7 +1076,6 @@ void Controller::refreshTransactions() { } } } - qDebug()<<"get Lag" << getLag(); // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds @@ -1098,10 +1095,7 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); - // refreshContacts( - // ui->listContactWidget - - // ); + }); } From d32d7cf11ada3e8c3e2796ba9b7856fac89630df Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 30 May 2020 23:11:21 +0200 Subject: [PATCH 184/253] add SDLogo icon to combo box --- src/addressbook.ui | 2 +- src/contactrequest.ui | 2 +- src/requestContactDialog.ui | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/addressbook.ui b/src/addressbook.ui index 1bcf214..dd0d06d 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -69,7 +69,7 @@ - :/icons/res/sdlogo.png + :/icons/res/SDLogo.png diff --git a/src/contactrequest.ui b/src/contactrequest.ui index cd4120b..9b28dca 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -42,7 +42,7 @@ - :/icons/res/sdlogo.png + :/icons/res/SDLogo.png diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index f8cb244..4beeced 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -209,7 +209,7 @@ - :/icons/res/sdlogo.png + :/icons/res/SDLogo.png From 55b11480478ac77bf099d1692bee88e7723c5116 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 31 May 2020 00:29:03 +0200 Subject: [PATCH 185/253] comments for debug issues --- src/chatmodel.cpp | 213 ++++++++++++++++++++++------------------------ 1 file changed, 102 insertions(+), 111 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index f25fe79..6d6a216 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -370,21 +370,23 @@ Tx MainWindow::createTxFromChatPage() { QString type = "Memo"; QString addr = c.getPartnerAddress(); - + QString hmemo= createHeaderMemo(type,cid,myAddr); + + /////////User input for chatmemos QString memounencrypt = ui->memoTxtChat->toPlainText().trimmed(); - + /////////We convert the user input from QString to unsigned char*, so we can encrypt it later int length = memounencrypt.length(); char *sequence = NULL; sequence = new char[length+1]; strncpy(sequence, memounencrypt.toLocal8Bit(), length +1); -////////////////////////////////////////////////////Important: If we can decrypt the output of QString memo, after we encrypt it, Bobs code must be in Controller.cpp +//////////////////////////////////////////////////Lets create Alice keys for the conversation/////////////////////////////////// /////////////////Alice Pubkey - #define MESSAGEAP ((const unsigned char *) "Ioesd") + #define MESSAGEAP ((const unsigned char *) "Ioesd")///////////static atm, in future we will use the CID here #define MESSAGEAP_LEN 5 unsigned char alice_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; @@ -398,7 +400,7 @@ Tx MainWindow::createTxFromChatPage() { /////////////////Alice Secretkey - #define MESSAGEAS ((const unsigned char *) "Hallo") + #define MESSAGEAS ((const unsigned char *) "Hallo")///////////static atm, in future we will use the Passphrase here #define MESSAGEAS_LEN 5 unsigned char alice_secretkey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; @@ -408,7 +410,7 @@ Tx MainWindow::createTxFromChatPage() { NULL, 0); /////////////////Bob Pubkey that Alice creates - #define MESSAGEBAP ((const unsigned char *) "Hal11") + #define MESSAGEBAP ((const unsigned char *) "Hal11")///////////static atm, in future we will use the CID here #define MESSAGEBAP_LEN 5 unsigned char bob_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; @@ -420,55 +422,67 @@ Tx MainWindow::createTxFromChatPage() { qDebug()<<"Alice version of Bobs Pubkey created"; - ////////////Alice creates the Shared key - unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES]; -/* Generate the server's key pair */ -crypto_kx_keypair(alice_publickey, alice_secretkey); + ////////////Now we create shared keys for the conversation////////////////////////////// -/* Prerequisite after this point: the client's public key must be known by the server */ + unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES]; + /* Generate the server's key pair */ + crypto_kx_keypair(alice_publickey, alice_secretkey); -/* Compute two shared keys using the client's public key and the server's secret key. - server_rx will be used by the server to receive data from the client, - server_tx will by used by the server to send data to the client. */ -if (crypto_kx_server_session_keys(server_rx, server_tx, - alice_publickey, alice_secretkey, bob_publickey) != 0) { + /* Prerequisite after this point: the client's public key must be known by the server */ + + /* Compute two shared keys using the client's public key and the server's secret key. + server_rx will be used by the server to receive data from the client, + server_tx will by used by the server to send data to the client. */ + if (crypto_kx_server_session_keys(server_rx, server_tx, + alice_publickey, alice_secretkey, bob_publickey) != 0) { /* Suspicious client public key, bail out */ } - + ////////////Now lets encrypt the message Alice send to Bob////////////////////////////// #define MESSAGE (const unsigned char *) sequence #define MESSAGE_LEN length #define CIPHERTEXT_LEN (MESSAGE_LEN + crypto_secretstream_xchacha20poly1305_ABYTES) -crypto_secretstream_xchacha20poly1305_state state; -//unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; -unsigned char c1[CIPHERTEXT_LEN]; + + crypto_secretstream_xchacha20poly1305_state state; + /////The Header must be known by both, so we can use alice or bobs pubkey here + + //unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + + unsigned char c1[CIPHERTEXT_LEN]; + + /* Shared secret key required to encrypt/decrypt the stream */ + crypto_secretstream_xchacha20poly1305_keygen(alice_publickey); + + /* Set up a new stream: initialize the state and create the header */ + ////////////Bobs pubkey will be use as header here, and alice_publickey as Key. Just for testing, we will switch to server_tx here ////////////////////////////// + crypto_secretstream_xchacha20poly1305_init_push(&state, bob_publickey, alice_publickey); + + ////Now encrypt the Message/////////////////////////////////// + crypto_secretstream_xchacha20poly1305_push + (&state, c1, NULL, MESSAGE, MESSAGE_LEN, NULL, 0, 0); + + ///////////Ciphertext is now in c1 as unsigned char*, we need it as QString, to send it as memo to Bob////////////////////// + + /////This is not working. It seems the QString has not exact the ciphertext in it. It will not decrypt with it//////////////// + QString memo( reinterpret_cast< char* >( c1 ) ); + + qDebug()<<"Size QString with encrypted data :"<< memo.length(); ////We check the length here, to compare it with the length our QString + + ///////Just for testing we convert the unsigned char* to std::string, to see if we can decrypt,and that works.//////////// + + std::string encryptedMemo(reinterpret_cast(c1), CIPHERTEXT_LEN); -/* Shared secret key required to encrypt/decrypt the stream */ -crypto_secretstream_xchacha20poly1305_keygen(alice_publickey); + qDebug()<<"Size std::string with encrypted data :"<< encryptedMemo.length(); ////We check the length here, to compare it with the length our QString -/* Set up a new stream: initialize the state and create the header */ -crypto_secretstream_xchacha20poly1305_init_push(&state, bob_publickey, alice_publickey); + -/* Now, encrypt the first chunk. `c1` will contain an encrypted, - * authenticated representation of `MESSAGE_PART1`. */ -crypto_secretstream_xchacha20poly1305_push - (&state, c1, NULL, MESSAGE, MESSAGE_LEN, NULL, 0, 0); - - -///////////get a std:string....QString will give us not good results - - std::string encryptedMemo(reinterpret_cast(c1), CIPHERTEXT_LEN); - - qDebug()<<"Size Controller Memo :"<< encryptedMemo.length(); - - QString memo = QString::fromUtf8( encryptedMemo.data(), encryptedMemo.size()); - - - /////////////////Bob Pubkey - #define MESSAGEBAP1 ((const unsigned char *) "Hal12") + /////////////////////////////////Now we create Bobs keys, just for testing at this place. If the encryption/decryption works we put it in Controller.cpp (RefreshTransactions) + + /////////////////Bob Pubkey///////////////////////////////// + #define MESSAGEBAP1 ((const unsigned char *) "Hal12")///////////static atm, in future we will use the CID here #define MESSAGEBAP1_LEN 5 unsigned char bob1_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; @@ -480,7 +494,7 @@ crypto_secretstream_xchacha20poly1305_push qDebug()<<"Bobs Pubkey created"; /////////////////Bob Secretkey - #define MESSAGEBS ((const unsigned char *) "Hal11") + #define MESSAGEBS ((const unsigned char *) "Hal11")///////////static atm, in future we will use the Passphrase here #define MESSAGEBS_LEN 5 unsigned char bob_secretkey[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; @@ -492,7 +506,7 @@ crypto_secretstream_xchacha20poly1305_push qDebug()<<"Bobs Pubkey created"; /////////////////Alice Pubkey bob creates - #define MESSAGEA121 ((const unsigned char *) "Ioesd") + #define MESSAGEA121 ((const unsigned char *) "Ioesd")///////////static atm, in future we will use the CID here #define MESSAGEAP121_LEN 5 unsigned char alice1_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; @@ -507,104 +521,81 @@ crypto_secretstream_xchacha20poly1305_push -////////////BOB creates the Shared key -//unsigned char bob_publickey[crypto_kx_PUBLICKEYBYTES], bob_secretkey[crypto_kx_SECRETKEYBYTES]; -unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; +////////////Now we create the shared keys for Bob/////////////////////////////////////////////// -/* Generate the client's key pair */ -crypto_kx_keypair(bob1_publickey, bob_secretkey); + unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; -/* Prerequisite after this point: the server's public key must be known by the client */ + /* Generate the client's key pair */ + crypto_kx_keypair(bob1_publickey, bob_secretkey); -/* Compute two shared keys using the server's public key and the client's secret key. - client_rx will be used by the client to receive data from the server, - client_tx will by used by the client to send data to the server. */ -if (crypto_kx_client_session_keys(client_rx, client_tx, - bob1_publickey, bob_secretkey, alice1_publickey) != 0) { - /* Suspicious server public key, bail out */ -} + /* Prerequisite after this point: the server's public key must be known by the client */ -qDebug()<<"1 : "; + /* Compute two shared keys using the server's public key and the client's secret key. + client_rx will be used by the client to receive data from the server, + client_tx will by used by the client to send data to the server. */ + if (crypto_kx_client_session_keys(client_rx, client_tx, + bob1_publickey, bob_secretkey, alice1_publickey) != 0) { + /* Suspicious server public key, bail out */ + } -qDebug()<<"Size of QString memo send as Transaction:" << memo.length(); - -QString memo1 = QString::fromUtf8( encryptedMemo.data(), encryptedMemo.size()); - -int lenght1 = encryptedMemo.length(); - -qDebug()<<"std::string Memo size : "<(m),MESSAGE1_LEN); + /////Now we can convert it to QString + QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); - - //QString memodecrypt = QString::fromLocal8Bit((char*)m2); - std::string decryptedMemo(reinterpret_cast(m2),MESSAGE_LEN); - qDebug()<<"7: "; - QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); - - - - qDebug()<<"OUT decrypt:" << memodecrypt; - - - + //////////////Give us the output of the decrypted message as debug to see if it was successfully + qDebug()<<"OUT decrypt:" << memodecrypt; tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); From af4a555fb031915e97a751b5fdd0d05e763c36f0 Mon Sep 17 00:00:00 2001 From: Denio <41270280+DenioD@users.noreply.github.com> Date: Sun, 31 May 2020 11:13:56 +0200 Subject: [PATCH 186/253] Update chatmodel.cpp --- src/chatmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 6d6a216..8b5f97d 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -545,8 +545,8 @@ Tx MainWindow::createTxFromChatPage() { ////QString to char+ (not working, it will not decrypt) /*char *memoIncoming = NULL; - memoIncoming = new char[lenght1+1]; - strncpy(memoIncoming, memo.toLocal8Bit(), lenght1+1);*/ + memoIncoming = new char[memo.length()+1]; + strncpy(memoIncoming, memo.toLocal8Bit(), [memo.length()+1);*/ ///////////////////////////if we take the std::string (of the encryption output) instead of QString memo, it will decrypt//////// From 4d74555c171011d52f7912a7fa4c672293f42299 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 00:03:11 +0200 Subject: [PATCH 187/253] first message encryption with static keys - work in progress --- src/chatmodel.cpp | 196 ++++----------------------------------------- src/controller.cpp | 112 ++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 187 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 8b5f97d..9a2e5f5 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -386,217 +386,53 @@ Tx MainWindow::createTxFromChatPage() { //////////////////////////////////////////////////Lets create Alice keys for the conversation/////////////////////////////////// /////////////////Alice Pubkey - #define MESSAGEAP ((const unsigned char *) "Ioesd")///////////static atm, in future we will use the CID here + #define MESSAGEAP ((const unsigned char *) "Hallo")///////////static atm, in future we will use the CID here #define MESSAGEAP_LEN 5 - unsigned char alice_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; crypto_generichash(alice_publickey, sizeof alice_publickey, MESSAGEAP, MESSAGEAP_LEN, NULL, 0); QString alice = QString::fromLocal8Bit((char*)alice_publickey); - qDebug()<<"Alice Pubkey : "<( c1 ) ); - - qDebug()<<"Size QString with encrypted data :"<< memo.length(); ////We check the length here, to compare it with the length our QString - - ///////Just for testing we convert the unsigned char* to std::string, to see if we can decrypt,and that works.//////////// - - std::string encryptedMemo(reinterpret_cast(c1), CIPHERTEXT_LEN); - - - qDebug()<<"Size std::string with encrypted data :"<< encryptedMemo.length(); ////We check the length here, to compare it with the length our QString - - - - /////////////////////////////////Now we create Bobs keys, just for testing at this place. If the encryption/decryption works we put it in Controller.cpp (RefreshTransactions) - - /////////////////Bob Pubkey///////////////////////////////// - #define MESSAGEBAP1 ((const unsigned char *) "Hal12")///////////static atm, in future we will use the CID here - #define MESSAGEBAP1_LEN 5 - - unsigned char bob1_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; - - crypto_generichash(bob1_publickey, sizeof bob1_publickey, - MESSAGEBAP1, MESSAGEBAP1_LEN, - NULL, 0); - - qDebug()<<"Bobs Pubkey created"; - - /////////////////Bob Secretkey - #define MESSAGEBS ((const unsigned char *) "Hal11")///////////static atm, in future we will use the Passphrase here - #define MESSAGEBS_LEN 5 - - unsigned char bob_secretkey[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; - - crypto_generichash(bob_secretkey, sizeof bob_secretkey, - MESSAGEBS, MESSAGEBS_LEN, - NULL, 0); - - qDebug()<<"Bobs Pubkey created"; - - /////////////////Alice Pubkey bob creates - #define MESSAGEA121 ((const unsigned char *) "Ioesd")///////////static atm, in future we will use the CID here - #define MESSAGEAP121_LEN 5 - - unsigned char alice1_publickey[crypto_secretstream_xchacha20poly1305_KEYBYTES]; - - crypto_generichash(alice1_publickey, sizeof alice1_publickey, - MESSAGEA121, MESSAGEAP121_LEN, - NULL, 0); - - QString alice1 = QString::fromLocal8Bit((char*)alice1_publickey); - qDebug()<<"Alice Pubkey Bob create: "<(m),MESSAGE1_LEN); - /////Now we can convert it to QString - QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); - - //////////////Give us the output of the decrypted message as debug to see if it was successfully - qDebug()<<"OUT decrypt:" << memodecrypt; - + /////CIphertext Memo + QString memo = QByteArray(reinterpret_cast(ciphertext), CIPHERTEXT_LEN).toHex(); + + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); tx.toAddrs.push_back(ToFields{addr, amt, memo}); diff --git a/src/controller.cpp b/src/controller.cpp index 0c79240..39efa6a 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -907,10 +907,12 @@ void Controller::refreshTransactions() { this->refresh(true); } + // QString memo1; + QString memo; if (!o["memo"].is_null()) { - memo = QString::fromStdString(o["memo"]); - + QString memo = QString::fromStdString(o["memo"].get()); + QString cid; bool isNotarized; @@ -921,8 +923,106 @@ void Controller::refreshTransactions() { isNotarized = false; } +/////////////////////////////////Now we create Bobs keys, just for testing at this place. If the encryption/decryption works we put it in Controller.cpp (RefreshTransactions) + + /////////////////Alice Pubkey bob create + #define MESSAGEAP ((const unsigned char *) "Hallo")///////////static atm, in future we will use the CID here + #define MESSAGEAP_LEN 5 - ChatItem item = ChatItem( + unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; + + crypto_generichash(alice_publickey, sizeof alice_publickey, + MESSAGEAP, MESSAGEAP_LEN, + NULL, 0); + + + /////////////////Bob Secretkey + + #define MESSAGEAS ((const unsigned char *) "Hallo")///////////static atm, in future we will use the Passphrase here + #define MESSAGEAS_LEN 5 + + unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES]; + + crypto_generichash(bob_secretkey, sizeof bob_secretkey, + MESSAGEAS, MESSAGEAS_LEN, + NULL, 0); + + /////////////////Bob Pubkey + #define MESSAGEBAP ((const unsigned char *) "Hallo")///////////static atm, in future we will use the CID here + #define MESSAGEBAP_LEN 5 + + unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES]; + + crypto_generichash(bob_publickey, sizeof bob_publickey, + MESSAGEBAP, MESSAGEBAP_LEN, + NULL, 0); + + + + /////We need to filter out Memos smaller then the ciphertext size, or it will dump + + if ((memo.length() > 120) && (memo.startsWith("{") == false)) + { + + + const QByteArray ba = QByteArray::fromHex(memo.toLatin1()); + const unsigned char *encryptedMemo = reinterpret_cast(ba.constData()); + + int encryptedMemoSize1 = ba.length(); + + //////unsigned char* as message from QString + #define MESSAGE2 (const unsigned char *) encryptedMemo + + ///////// length of the encrypted message + #define CIPHERTEXT1_LEN encryptedMemoSize1 + + ///////Message length is smaller then the encrypted message + #define MESSAGE1_LEN encryptedMemoSize1 - crypto_box_MACBYTES + + //////Set the length of the decrypted message + + unsigned char decrypted[MESSAGE1_LEN]; + + ///////Decrypt the message + if (crypto_box_open_easy(decrypted, MESSAGE2, CIPHERTEXT1_LEN, alice_publickey, + alice_publickey, alice_publickey) != 0) { + /* message for Bob pretending to be from Alice has been forged! */ + } + + /////Our decrypted message is now in decrypted. We need it as QString to render it + /////Only the QString gives weird data, so convert first to std::string + + std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); + + /////Now we can convert it to QString + QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + + //////////////Give us the output of the decrypted message as debug to see if it was successfully + qDebug()<<"OUT decrypt:" << memodecrypt; + + + ChatItem item = ChatItem( + datetime, + address, + QString(""), + memodecrypt, + QString(""), + QString(""), + cid, + txid, + confirmations, + true, + isNotarized, + false + ); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + + + + }else{ + + + ChatItem item = ChatItem( datetime, address, QString(""), @@ -938,11 +1038,9 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + } - } - - + } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } From e1863058da78d90f67ce166d650d385c0f253616 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 00:17:47 +0200 Subject: [PATCH 188/253] use cid as key for the moment --- src/chatmodel.cpp | 23 +++++++++++++++-------- src/controller.cpp | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 9a2e5f5..1ac2acc 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -374,19 +374,26 @@ Tx MainWindow::createTxFromChatPage() { QString hmemo= createHeaderMemo(type,cid,myAddr); /////////User input for chatmemos - QString memounencrypt = ui->memoTxtChat->toPlainText().trimmed(); + QString memoplain = ui->memoTxtChat->toPlainText().trimmed(); /////////We convert the user input from QString to unsigned char*, so we can encrypt it later - int length = memounencrypt.length(); + int lengthmemo = memoplain.length(); - char *sequence = NULL; - sequence = new char[length+1]; - strncpy(sequence, memounencrypt.toLocal8Bit(), length +1); + char *memoplainchar = NULL; + memoplainchar = new char[lengthmemo+1]; + strncpy(memoplainchar, memoplain.toLocal8Bit(), lengthmemo +1); + + /////////We convert the CID from QString to unsigned char*, so we can encrypt it later + int lengthcid = cid.length(); + + char *cidchar = NULL; + cidchar = new char[lengthcid+1]; + strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1); //////////////////////////////////////////////////Lets create Alice keys for the conversation/////////////////////////////////// /////////////////Alice Pubkey - #define MESSAGEAP ((const unsigned char *) "Hallo")///////////static atm, in future we will use the CID here + #define MESSAGEAP ((const unsigned char *) cidchar)///////////static atm, in future we will use the CID here #define MESSAGEAP_LEN 5 unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; @@ -418,8 +425,8 @@ Tx MainWindow::createTxFromChatPage() { NULL, 0); ////////////Now lets encrypt the message Alice send to Bob////////////////////////////// - #define MESSAGE (const unsigned char *) sequence - #define MESSAGE_LEN length + #define MESSAGE (const unsigned char *) memoplainchar + #define MESSAGE_LEN lengthmemo #define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN) unsigned char ciphertext[CIPHERTEXT_LEN]; diff --git a/src/controller.cpp b/src/controller.cpp index 39efa6a..4069022 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -910,10 +910,24 @@ void Controller::refreshTransactions() { // QString memo1; QString memo; + QString cid; if (!o["memo"].is_null()) { QString memo = QString::fromStdString(o["memo"].get()); + + if (memo.startsWith("{")) { + + QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); + + cid = headermemo["cid"].toString(); + + + + chatModel->addCid(txid, cid); + + + } + - QString cid; bool isNotarized; if (confirmations > getLag()) @@ -923,10 +937,25 @@ void Controller::refreshTransactions() { isNotarized = false; } + + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ + + cid = chatModel->getCidByTx(txid); + + }else{ + cid = ""; + } + + int lengthcid = cid.length(); + + char *cidchar = NULL; + cidchar = new char[lengthcid+1]; + strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1); + /////////////////////////////////Now we create Bobs keys, just for testing at this place. If the encryption/decryption works we put it in Controller.cpp (RefreshTransactions) /////////////////Alice Pubkey bob create - #define MESSAGEAP ((const unsigned char *) "Hallo")///////////static atm, in future we will use the CID here + #define MESSAGEAP ((const unsigned char *) cidchar)///////////static atm, in future we will use the CID here #define MESSAGEAP_LEN 5 unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; From a8c9a8e2efea81db8b263342e70f231790f19bf6 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 00:47:46 +0200 Subject: [PATCH 189/253] use length of cid --- src/chatmodel.cpp | 2 +- src/controller.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 1ac2acc..b033d7e 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -394,7 +394,7 @@ Tx MainWindow::createTxFromChatPage() { /////////////////Alice Pubkey #define MESSAGEAP ((const unsigned char *) cidchar)///////////static atm, in future we will use the CID here - #define MESSAGEAP_LEN 5 + #define MESSAGEAP_LEN lengthcid unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; diff --git a/src/controller.cpp b/src/controller.cpp index 4069022..342a24a 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -956,7 +956,7 @@ void Controller::refreshTransactions() { /////////////////Alice Pubkey bob create #define MESSAGEAP ((const unsigned char *) cidchar)///////////static atm, in future we will use the CID here - #define MESSAGEAP_LEN 5 + #define MESSAGEAP_LEN lengthcid unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; From 21c727efb006ecc5b215a3c831f734a2524fb5a5 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 21:24:39 +0200 Subject: [PATCH 190/253] switch to secretstream for encryption - work in progress --- src/Model/ContactItem.cpp | 2 + src/Model/ContactItem.h | 1 + src/chatmodel.cpp | 156 ++++++++++++++++------- src/chatmodel.h | 3 + src/controller.cpp | 254 ++++++++++++++++++++++++++++---------- src/mainwindow.h | 2 +- 6 files changed, 308 insertions(+), 110 deletions(-) diff --git a/src/Model/ContactItem.cpp b/src/Model/ContactItem.cpp index 589ca9f..b542270 100644 --- a/src/Model/ContactItem.cpp +++ b/src/Model/ContactItem.cpp @@ -19,6 +19,7 @@ ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress _myAddress = myAddress; _partnerAddress = partnerAddress; _cid = cid; + } ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress, QString cid, QString avatar) @@ -28,6 +29,7 @@ ContactItem::ContactItem(QString name, QString partnerAddress, QString myAddress _partnerAddress = partnerAddress; _cid = cid; _avatar = avatar; + } QString ContactItem::getName() const diff --git a/src/Model/ContactItem.h b/src/Model/ContactItem.h index 63b4b39..e5e313d 100644 --- a/src/Model/ContactItem.h +++ b/src/Model/ContactItem.h @@ -16,6 +16,7 @@ private: QString _name; QString _cid; QString _avatar; + QString _pubkey; public: ContactItem(); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index b033d7e..bc45d8b 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -255,6 +255,11 @@ void ChatModel::addCid(QString tx, QString cid) this->cidMap[tx] = cid; } +void ChatModel::addHeader(QString tx, QString headerbytes) +{ + this->headerMap[tx] = headerbytes; +} + void ChatModel::addrequestZaddr(QString tx, QString requestZaddr) { this->requestZaddrMap[tx] = requestZaddr; @@ -280,6 +285,21 @@ QString ChatModel::getCidByTx(QString tx) return QString("0xdeadbeef"); } +QString ChatModel::getHeaderByTx(QString tx) +{ + for(auto& pair : this->headerMap) + { + + } + + if(this->headerMap.count(tx) > 0) + { + return this->headerMap[tx]; + } + + return QString("0xdeadbeef"); +} + QString ChatModel::getConfirmationByTx(QString tx) { for(auto& pair : this->confirmationsMap) @@ -325,7 +345,7 @@ void ChatModel::killConfirmationCache() this->confirmationsMap.clear(); } -QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, int version=0, int headerNumber=1) +QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, QString headerbytes, QString publickey, int version=0, int headerNumber=1) { QString header=""; @@ -338,6 +358,9 @@ QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, h["z"] = zaddr; // zaddr to respond to h["cid"] = cid; // conversation id h["t"] = type; // Memo or incoming contact request + h["e"] = headerbytes; // Memo or incoming contact request + h["p"] = publickey; // Memo or incoming contact request + j.setObject(h); header = j.toJson(); @@ -346,6 +369,7 @@ QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, } + // Create a Tx from the current state of the Chat page. Tx MainWindow::createTxFromChatPage() { Tx tx; @@ -370,8 +394,7 @@ Tx MainWindow::createTxFromChatPage() { QString type = "Memo"; QString addr = c.getPartnerAddress(); - - QString hmemo= createHeaderMemo(type,cid,myAddr); + /////////User input for chatmemos QString memoplain = ui->memoTxtChat->toPlainText().trimmed(); @@ -390,58 +413,76 @@ Tx MainWindow::createTxFromChatPage() { cidchar = new char[lengthcid+1]; strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1); -//////////////////////////////////////////////////Lets create Alice keys for the conversation/////////////////////////////////// + - /////////////////Alice Pubkey - #define MESSAGEAP ((const unsigned char *) cidchar)///////////static atm, in future we will use the CID here - #define MESSAGEAP_LEN lengthcid + QString pubkey = "test"; + QString passphrase = this->getPassword(); + QString hashEncryptionKey = passphrase; + int length = hashEncryptionKey.length(); - unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES]; + qDebug()<<"Encryption String :"<(ba2.constData()); - #define MESSAGEAS ((const unsigned char *) "Hallo")///////////static atm, in future we will use the Passphrase here - #define MESSAGEAS_LEN 5 + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) + #define MESSAGEAS1_LEN length + unsigned char hash[crypto_kx_SEEDBYTES]; - unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES]; + crypto_hash_sha256(hash,MESSAGEAS1, MESSAGEAS1_LEN); - crypto_generichash(alice_secretkey, sizeof alice_secretkey, - MESSAGEAS, MESSAGEAS_LEN, - NULL, 0); - /////////////////Bob Pubkey that Alice creates - #define MESSAGEBAP ((const unsigned char *) "Hallo")///////////static atm, in future we will use the CID here - #define MESSAGEBAP_LEN 5 + unsigned char sk[crypto_kx_SECRETKEYBYTES]; + unsigned char pk[crypto_kx_PUBLICKEYBYTES]; + unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES]; + + if (crypto_kx_seed_keypair(pk,sk, + hash) !=0) { + } + ////////////////Get the pubkey from Bob, so we can create the share key - unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES]; + const QByteArray pubkeyBobArray = QByteArray::fromHex(pubkey.toLatin1()); + const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); + /////Create the shared key for sending the message - crypto_generichash(bob_publickey, sizeof bob_publickey, - MESSAGEBAP, MESSAGEBAP_LEN, - NULL, 0); + if (crypto_kx_server_session_keys(server_rx, server_tx, + pk, sk, pubkeyBob) != 0) { + /* Suspicious client public key, bail out */ + } - ////////////Now lets encrypt the message Alice send to Bob////////////////////////////// - #define MESSAGE (const unsigned char *) memoplainchar - #define MESSAGE_LEN lengthmemo - #define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN) - unsigned char ciphertext[CIPHERTEXT_LEN]; - - //////Encrypt the message. ATM static keys, this will change! - if (crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, alice_publickey, - alice_publickey, alice_publickey) != 0) { - /* error */ - } - /////CIphertext Memo - QString memo = QByteArray(reinterpret_cast(ciphertext), CIPHERTEXT_LEN).toHex(); + + ////////////Now lets encrypt the message Alice send to Bob////////////////////////////// + #define MESSAGE (const unsigned char *) memoplainchar + #define MESSAGE_LEN lengthmemo + #define CIPHERTEXT_LEN (crypto_secretstream_xchacha20poly1305_ABYTES + MESSAGE_LEN) + unsigned char ciphertext[CIPHERTEXT_LEN]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + + crypto_secretstream_xchacha20poly1305_state state; + + /* Set up a new stream: initialize the state and create the header */ + crypto_secretstream_xchacha20poly1305_init_push(&state, header, server_tx); + + + /* Now, encrypt the first chunk. `c1` will contain an encrypted, + * authenticated representation of `MESSAGE_PART1`. */ + crypto_secretstream_xchacha20poly1305_push + (&state, ciphertext, NULL, MESSAGE, MESSAGE_LEN, NULL, 0, crypto_secretstream_xchacha20poly1305_TAG_FINAL); + + ////Create the HM for this message + QString headerbytes = QByteArray(reinterpret_cast(header), crypto_secretstream_xchacha20poly1305_HEADERBYTES).toHex(); + + QString hmemo= createHeaderMemo(type,cid,myAddr,"",headerbytes); + + /////Ciphertext Memo + QString memo = QByteArray(reinterpret_cast(ciphertext), CIPHERTEXT_LEN).toHex(); - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); - tx.toAddrs.push_back(ToFields{addr, amt, memo}); + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + tx.toAddrs.push_back(ToFields{addr, amt, memo}); @@ -670,6 +711,7 @@ Tx MainWindow::createTxForSafeContactRequest() CAmount totalAmt; QString amtStr = "0"; CAmount amt; + QString headerbytes = ""; amt = CAmount::fromDecimalString("0"); totalAmt = totalAmt + amt; @@ -678,8 +720,38 @@ Tx MainWindow::createTxForSafeContactRequest() QString type = "Cont"; QString addr = contactRequest.getReceiverAddress(); - QString hmemo= createHeaderMemo(type,cid,myAddr); + QString memo = contactRequest.getMemo(); + // QString privkey = rpc->fetchPrivKey(myAddr); + QString passphrase = this->getPassword(); + QString hashEncryptionKey = passphrase; + int length = hashEncryptionKey.length(); + + qDebug()<<"Encryption String :"<(ba2.constData()); + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) + #define MESSAGEAS1_LEN length + + + unsigned char hash[crypto_kx_SEEDBYTES]; + + crypto_hash_sha256(hash,MESSAGEAS1, MESSAGEAS1_LEN); + + + unsigned char sk[crypto_kx_SECRETKEYBYTES]; + unsigned char pk[crypto_kx_PUBLICKEYBYTES]; + + if (crypto_kx_seed_keypair(pk,sk, + hash) !=0) { + } + + QString publicKey = QByteArray(reinterpret_cast(pk), crypto_kx_PUBLICKEYBYTES).toHex(); + + QString hmemo= createHeaderMemo(type,cid,myAddr,"", publicKey); tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); diff --git a/src/chatmodel.h b/src/chatmodel.h index 1768b9f..b7203ad 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -35,6 +35,7 @@ class ChatModel std::map requestZaddrMap; std::map confirmationsMap; std::map> sendrequestMap; + std::map headerMap; std::map AddressbyLabelMap; public: @@ -52,10 +53,12 @@ class ChatModel void addMessage(ChatItem item); void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); + void addHeader(QString tx, QString headerbytes); void addrequestZaddr(QString tx, QString requestZaddr); void addconfirmations(QString tx, int confirmation); void addSendRequest(int i, QString myAddr, QString cid, QString addr ); QString getCidByTx(QString tx); + QString getHeaderByTx(QString tx); QString getrequestZaddrByTx(QString tx); QString getConfirmationByTx(QString tx); QString Addressbylabel(QString addr); diff --git a/src/controller.cpp b/src/controller.cpp index 342a24a..50bcdd6 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -907,27 +907,25 @@ void Controller::refreshTransactions() { this->refresh(true); } - // QString memo1; - QString memo; - QString cid; + QString cid; + QString headerbytes; + QString pubkey; if (!o["memo"].is_null()) { - QString memo = QString::fromStdString(o["memo"].get()); - + memo = QString::fromStdString(o["memo"].get()); + if (memo.startsWith("{")) { QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); cid = headermemo["cid"].toString(); - - + headerbytes = headermemo["e"].toString(); - chatModel->addCid(txid, cid); - + chatModel->addCid(txid, cid); + chatModel->addHeader(txid, headerbytes); } - - + bool isNotarized; if (confirmations > getLag()) @@ -942,62 +940,81 @@ void Controller::refreshTransactions() { cid = chatModel->getCidByTx(txid); + }else{ + cid = ""; + } + + + if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef")){ + + headerbytes = chatModel->getHeaderByTx(txid); + }else{ - cid = ""; + headerbytes = ""; } + qDebug()<<"Headerbytes :"< 120) && (memo.startsWith("{") == false)) + if ((memo.startsWith("{") == false) && (headerbytes > 0)) { + /*for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) + { + + if (p.getPartnerAddress() == address) + { pubkey = p.getPubkey(); + }else {pubkey = ""; + }*/ + + //QString myAddr = p.getMyAddress(); + QString passphrase = main->getPassword(); + QString hashEncryptionKey = passphrase; + int length = hashEncryptionKey.length(); + + qDebug()<<"Encryption String :"<(ba2.constData()); + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) + #define MESSAGEAS1_LEN length + + + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)///////////static atm, in future we will use the Passphrase here + #define MESSAGEAS1_LEN 12 + + + unsigned char hash1[crypto_kx_SECRETKEYBYTES]; + + crypto_hash_sha256(hash1,MESSAGEAS1, MESSAGEAS1_LEN); + unsigned char sk[crypto_kx_SECRETKEYBYTES]; + unsigned char pk[crypto_kx_PUBLICKEYBYTES]; + + if (crypto_kx_seed_keypair(pk,sk, + hash1) !=0) { + + + } + + unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; + - const QByteArray ba = QByteArray::fromHex(memo.toLatin1()); const unsigned char *encryptedMemo = reinterpret_cast(ba.constData()); + const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1()); + const unsigned char *header = reinterpret_cast(ba1.constData()); + int encryptedMemoSize1 = ba.length(); + int headersize = ba1.length(); //////unsigned char* as message from QString #define MESSAGE2 (const unsigned char *) encryptedMemo @@ -1006,20 +1023,25 @@ void Controller::refreshTransactions() { #define CIPHERTEXT1_LEN encryptedMemoSize1 ///////Message length is smaller then the encrypted message - #define MESSAGE1_LEN encryptedMemoSize1 - crypto_box_MACBYTES + #define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES //////Set the length of the decrypted message unsigned char decrypted[MESSAGE1_LEN]; + unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL]; + crypto_secretstream_xchacha20poly1305_state state; - ///////Decrypt the message - if (crypto_box_open_easy(decrypted, MESSAGE2, CIPHERTEXT1_LEN, alice_publickey, - alice_publickey, alice_publickey) != 0) { - /* message for Bob pretending to be from Alice has been forged! */ - } - /////Our decrypted message is now in decrypted. We need it as QString to render it /////Only the QString gives weird data, so convert first to std::string + // crypto_secretstream_xchacha20poly1305_keygen(client_rx); + if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, client_rx) != 0) { + /* Invalid header, no need to go any further */ + } + + if (crypto_secretstream_xchacha20poly1305_pull + (&state, decrypted, NULL, tag, MESSAGE2, CIPHERTEXT1_LEN, NULL, 0) != 0) { + /* Invalid/incomplete/corrupted ciphertext - abort */ + } std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); @@ -1047,7 +1069,7 @@ void Controller::refreshTransactions() { DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + // } }else{ @@ -1068,8 +1090,8 @@ void Controller::refreshTransactions() { DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } + } - } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; } @@ -1114,6 +1136,8 @@ void Controller::refreshTransactions() { txdata.push_back(tx); QString type; + QString publickey; + QString headerbytes; QString cid; int position; QString requestZaddr; @@ -1149,9 +1173,12 @@ void Controller::refreshTransactions() { cid = headermemo["cid"].toString(); type = headermemo["t"].toString(); requestZaddr = headermemo["z"].toString(); + headerbytes = headermemo["e"].toString(); + publickey = headermemo["p"].toString(); chatModel->addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); + chatModel->addHeader(txid, headerbytes); } @@ -1169,9 +1196,18 @@ void Controller::refreshTransactions() { requestZaddr = chatModel->getrequestZaddrByTx(txid); }else{ requestZaddr = ""; - } + } - position = it["position"].get(); + + if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef")){ + + headerbytes = chatModel->getHeaderByTx(txid); + + }else{ + headerbytes = ""; + } + + //position = it["position"].get(); bool isNotarized; @@ -1183,7 +1219,90 @@ void Controller::refreshTransactions() { isNotarized = false; } - ChatItem item = ChatItem( + + int lengthcid = cid.length(); + + char *cidchar = NULL; + cidchar = new char[lengthcid+1]; + strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1); + + if ((memo.startsWith("{") == false) && (headerbytes > 0)) + { + + #define MESSAGEAS ((const unsigned char *) cidchar) + #define MESSAGEAS_LEN lengthcid + + unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + + crypto_hash_sha256(hash,MESSAGEAS, MESSAGEAS_LEN); + + const QByteArray ba = QByteArray::fromHex(memo.toLatin1()); + const unsigned char *encryptedMemo = reinterpret_cast(ba.constData()); + + const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1()); + const unsigned char *header = reinterpret_cast(ba1.constData()); + + int encryptedMemoSize1 = ba.length(); + int headersize = ba1.length(); + + //////unsigned char* as message from QString + #define MESSAGE2 (const unsigned char *) encryptedMemo + + ///////// length of the encrypted message + #define CIPHERTEXT1_LEN encryptedMemoSize1 + + ///////Message length is smaller then the encrypted message + #define MESSAGE1_LEN encryptedMemoSize1 - crypto_secretstream_xchacha20poly1305_ABYTES + + //////Set the length of the decrypted message + + unsigned char decrypted[MESSAGE1_LEN]; + unsigned char tag[crypto_secretstream_xchacha20poly1305_TAG_FINAL]; + crypto_secretstream_xchacha20poly1305_state state; + + /////Our decrypted message is now in decrypted. We need it as QString to render it + /////Only the QString gives weird data, so convert first to std::string + + if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, hash) != 0) { + /* Invalid header, no need to go any further */ + } + + if (crypto_secretstream_xchacha20poly1305_pull + (&state, decrypted, NULL, tag, MESSAGE2, CIPHERTEXT1_LEN, NULL, 0) != 0) { + /* Invalid/incomplete/corrupted ciphertext - abort */ + } + + std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); + + /////Now we can convert it to QString + QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + + //////////////Give us the output of the decrypted message as debug to see if it was successfully + qDebug()<<"OUT decrypt:" << memodecrypt; + + + ChatItem item = ChatItem( + datetime, + address, + QString(""), + memodecrypt, + requestZaddr, + type, + cid, + txid, + confirmations, + false, + isNotarized, + isContact + ); + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + + + + }else{ + + + ChatItem item = ChatItem( datetime, address, QString(""), @@ -1197,9 +1316,10 @@ void Controller::refreshTransactions() { isNotarized, isContact ); - - DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - } + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + + } + } } } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 56bfbc6..815fd84 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -90,7 +90,7 @@ public: void doClose(); void doClosePw(); - QString createHeaderMemo(QString type, QString cid, QString zaddr, int version, int headerNumber); + QString createHeaderMemo(QString type, QString cid, QString zaddr,QString headerbytes,QString publickey, int version, int headerNumber); public slots: void slot_change_theme(const QString& themeName); From 74de61d265caa7e6c21e2b739b25d8350e15c309 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 22:21:17 +0200 Subject: [PATCH 191/253] add pubkey cache --- src/chatmodel.cpp | 12 ++++++++++-- src/chatmodel.h | 1 + src/controller.cpp | 28 +++++++++++++++++++++++----- src/mainwindow.cpp | 20 ++++++++++++++++++++ src/mainwindow.h | 5 +++++ 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index bc45d8b..f29be0f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -260,6 +260,8 @@ void ChatModel::addHeader(QString tx, QString headerbytes) this->headerMap[tx] = headerbytes; } + + void ChatModel::addrequestZaddr(QString tx, QString requestZaddr) { this->requestZaddrMap[tx] = requestZaddr; @@ -285,6 +287,9 @@ QString ChatModel::getCidByTx(QString tx) return QString("0xdeadbeef"); } + + + QString ChatModel::getHeaderByTx(QString tx) { for(auto& pair : this->headerMap) @@ -415,7 +420,7 @@ Tx MainWindow::createTxFromChatPage() { - QString pubkey = "test"; + QString pubkey = this->getPubkeyByAddress(addr); QString passphrase = this->getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); @@ -474,8 +479,9 @@ Tx MainWindow::createTxFromChatPage() { ////Create the HM for this message QString headerbytes = QByteArray(reinterpret_cast(header), crypto_secretstream_xchacha20poly1305_HEADERBYTES).toHex(); + QString publickeyAlice = QByteArray(reinterpret_cast(pk), crypto_kx_PUBLICKEYBYTES).toHex(); - QString hmemo= createHeaderMemo(type,cid,myAddr,"",headerbytes); + QString hmemo= createHeaderMemo(type,cid,myAddr,publickeyAlice,headerbytes); /////Ciphertext Memo QString memo = QByteArray(reinterpret_cast(ciphertext), CIPHERTEXT_LEN).toHex(); @@ -751,6 +757,8 @@ Tx MainWindow::createTxForSafeContactRequest() QString publicKey = QByteArray(reinterpret_cast(pk), crypto_kx_PUBLICKEYBYTES).toHex(); + qDebug()<<"Publickey created Request: "<> sendrequestMap; std::map headerMap; std::map AddressbyLabelMap; + public: ChatModel() {}; diff --git a/src/controller.cpp b/src/controller.cpp index 50bcdd6..0f5b4f3 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -910,7 +910,7 @@ void Controller::refreshTransactions() { QString memo; QString cid; QString headerbytes; - QString pubkey; + QString publickey; if (!o["memo"].is_null()) { memo = QString::fromStdString(o["memo"].get()); @@ -953,7 +953,15 @@ void Controller::refreshTransactions() { headerbytes = ""; } - qDebug()<<"Headerbytes :"<getPubkeyByAddress(address) != QString("0xdeadbeef")){ + + publickey = main->getPubkeyByAddress(address); + + }else{ + publickey = ""; + } + + qDebug()<<"Pubkey :"<addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); chatModel->addHeader(txid, headerbytes); + main->addPubkey(requestZaddr, publickey); - } + } if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ @@ -1207,6 +1216,14 @@ void Controller::refreshTransactions() { headerbytes = ""; } + if (main->getPubkeyByAddress(requestZaddr) != QString("0xdeadbeef")){ + + publickey = main->getPubkeyByAddress(requestZaddr); + + }else{ + publickey = ""; + } + //position = it["position"].get(); bool isNotarized; @@ -1226,7 +1243,7 @@ void Controller::refreshTransactions() { cidchar = new char[lengthcid+1]; strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1); - if ((memo.startsWith("{") == false) && (headerbytes > 0)) + if ((memo.startsWith("{") == false) && (headerbytes > 0)) { #define MESSAGEAS ((const unsigned char *) cidchar) @@ -1298,7 +1315,7 @@ void Controller::refreshTransactions() { DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + }else{ @@ -1320,6 +1337,7 @@ void Controller::refreshTransactions() { } } + } } } } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 27c567e..bd12d90 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1062,6 +1062,26 @@ void MainWindow::exportSeed() { }); } +void MainWindow::addPubkey(QString requestZaddr, QString pubkey) +{ + this->pubkeyMap[requestZaddr] = pubkey; +} + +QString MainWindow::getPubkeyByAddress(QString requestZaddr) +{ + for(auto& pair : this->pubkeyMap) + { + + } + + if(this->pubkeyMap.count(requestZaddr) > 0) + { + return this->pubkeyMap[requestZaddr]; + } + + return QString("0xdeadbeef"); +} + void MainWindow::exportAllKeys() { exportKeys(""); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 815fd84..8c63540 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -12,6 +12,7 @@ class Controller; class Settings; class WSServer; class WormholeClient; +class ChatModel; using json = nlohmann::json; @@ -52,7 +53,11 @@ public: QString doSendRequestTxValidations(Tx tx); QString getCid(); QString getPassword(); + std::map pubkeyMap; + QString getPubkeyByAddress(QString requestZaddr); void setPassword(QString Password); + void addPubkey(QString requestZaddr, QString pubkey); + void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); From 875d1a16a13bf3c744f30154f3e9191107263bea Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 22:32:38 +0200 Subject: [PATCH 192/253] add pubkey cache --- src/controller.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/controller.cpp b/src/controller.cpp index 0f5b4f3..f4475cd 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -957,6 +957,8 @@ void Controller::refreshTransactions() { publickey = main->getPubkeyByAddress(address); + qDebug()<<"Pubkey outgoing found"<addCid(txid, cid); chatModel->addrequestZaddr(txid, requestZaddr); chatModel->addHeader(txid, headerbytes); + + if (publickey.length() > 0){ main->addPubkey(requestZaddr, publickey); + } } @@ -1336,7 +1341,7 @@ void Controller::refreshTransactions() { DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); } - } + } } } From 173ec6ccdc7bb9f2f075a0ec3a605e6fcd1a6b21 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 1 Jun 2020 22:47:13 +0200 Subject: [PATCH 193/253] fix for incoming memos --- src/controller.cpp | 69 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index f4475cd..a4f315d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -995,10 +995,13 @@ void Controller::refreshTransactions() { const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) - #define MESSAGEAS1_LEN length + #define MESSAGEAS1_LEN length + + const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); + const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); - #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)///////////static atm, in future we will use the Passphrase here + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)/////////// #define MESSAGEAS1_LEN 12 @@ -1015,6 +1018,17 @@ void Controller::refreshTransactions() { } unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; + + + ////////////////Get the pubkey from Bob, so we can create the share key + + + /////Create the shared key for sending the message + + if (crypto_kx_server_session_keys(client_rx, client_tx, + pk, sk, pubkeyBob) != 0) { + /* Suspicious client public key, bail out */ + } const QByteArray ba = QByteArray::fromHex(memo.toLatin1()); @@ -1243,6 +1257,11 @@ void Controller::refreshTransactions() { int lengthcid = cid.length(); + QString passphrase = main->getPassword(); + QString hashEncryptionKey = passphrase; + int length = hashEncryptionKey.length(); + + qDebug()<<"Encryption String :"< 0)) { - #define MESSAGEAS ((const unsigned char *) cidchar) - #define MESSAGEAS_LEN lengthcid + const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); + const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) + #define MESSAGEAS1_LEN length - unsigned char hash[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); + const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); - crypto_hash_sha256(hash,MESSAGEAS, MESSAGEAS_LEN); + + #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)/////////// + #define MESSAGEAS1_LEN 12 + + + unsigned char hash1[crypto_kx_SECRETKEYBYTES]; + + crypto_hash_sha256(hash1,MESSAGEAS1, MESSAGEAS1_LEN); + unsigned char sk[crypto_kx_SECRETKEYBYTES]; + unsigned char pk[crypto_kx_PUBLICKEYBYTES]; + + if (crypto_kx_seed_keypair(pk,sk, + hash1) !=0) { + + + } + + unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; + + + ////////////////Get the pubkey from Bob, so we can create the share key + + + /////Create the shared key for sending the message + + if (crypto_kx_server_session_keys(client_rx, client_tx, + pk, sk, pubkeyBob) != 0) { + /* Suspicious client public key, bail out */ + } + const QByteArray ba = QByteArray::fromHex(memo.toLatin1()); const unsigned char *encryptedMemo = reinterpret_cast(ba.constData()); @@ -1284,8 +1335,8 @@ void Controller::refreshTransactions() { /////Our decrypted message is now in decrypted. We need it as QString to render it /////Only the QString gives weird data, so convert first to std::string - - if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, hash) != 0) { + // crypto_secretstream_xchacha20poly1305_keygen(client_rx); + if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, client_rx) != 0) { /* Invalid header, no need to go any further */ } @@ -1300,7 +1351,7 @@ void Controller::refreshTransactions() { QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); //////////////Give us the output of the decrypted message as debug to see if it was successfully - qDebug()<<"OUT decrypt:" << memodecrypt; + qDebug()<<"OUT decrypt:" << memodecrypt; ChatItem item = ChatItem( From 1aed6e9ed004d11e2d8669ee462651541035ce57 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 00:26:06 +0200 Subject: [PATCH 194/253] change server to client --- src/chatmodel.cpp | 8 +++++--- src/controller.cpp | 49 +++++++++++++++++++++++----------------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index f29be0f..69751ad 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -422,10 +422,10 @@ Tx MainWindow::createTxFromChatPage() { QString pubkey = this->getPubkeyByAddress(addr); QString passphrase = this->getPassword(); - QString hashEncryptionKey = passphrase; + QString hashEncryptionKey = "Test"; int length = hashEncryptionKey.length(); - qDebug()<<"Encryption String :"<(header), crypto_secretstream_xchacha20poly1305_HEADERBYTES).toHex(); QString publickeyAlice = QByteArray(reinterpret_cast(pk), crypto_kx_PUBLICKEYBYTES).toHex(); - QString hmemo= createHeaderMemo(type,cid,myAddr,publickeyAlice,headerbytes); + qDebug()<<"Headerbyte erstellung : "<(ciphertext), CIPHERTEXT_LEN).toHex(); diff --git a/src/controller.cpp b/src/controller.cpp index a4f315d..cd1c3e4 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -948,6 +948,7 @@ void Controller::refreshTransactions() { if (chatModel->getHeaderByTx(txid) != QString("0xdeadbeef")){ headerbytes = chatModel->getHeaderByTx(txid); + qDebug()<<"headerbytes outgoing found"<getPassword(); - QString hashEncryptionKey = passphrase; + QString hashEncryptionKey = "Test"; int length = hashEncryptionKey.length(); qDebug()<<"Encryption String :"<(ba2.constData()); - #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) - #define MESSAGEAS1_LEN length - const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); - const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); + const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); + const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); + + qDebug()<<"Pubkey benutzt incoming transaction:"<(ba1.constData()); + qDebug()<<"Header benutzt incoming transaction:"<getHeaderByTx(txid) != QString("0xdeadbeef")){ headerbytes = chatModel->getHeaderByTx(txid); + qDebug()<<"HEADERBYTE INCOMING"<getPassword(); - QString hashEncryptionKey = passphrase; + int lengthcid = cid.length(); + QString passphrase = main->getPassword(); + QString hashEncryptionKey = "Test"; int length = hashEncryptionKey.length(); qDebug()<<"Encryption String :"<(ba2.constData()); - #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) - #define MESSAGEAS1_LEN length - - const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); + + const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw)/////////// - #define MESSAGEAS1_LEN 12 + #define MESSAGEAS1_LEN length unsigned char hash1[crypto_kx_SECRETKEYBYTES]; @@ -1303,7 +1302,7 @@ void Controller::refreshTransactions() { /////Create the shared key for sending the message - if (crypto_kx_server_session_keys(client_rx, client_tx, + if (crypto_kx_client_session_keys(client_rx, client_tx, pk, sk, pubkeyBob) != 0) { /* Suspicious client public key, bail out */ } From 04575afd5a1eb64036595c22832129ac6c5aa5d3 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 01:24:12 +0200 Subject: [PATCH 195/253] change decrypt key to shared --- src/controller.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index cd1c3e4..66b7823 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1239,6 +1239,8 @@ void Controller::refreshTransactions() { if (main->getPubkeyByAddress(requestZaddr) != QString("0xdeadbeef")){ publickey = main->getPubkeyByAddress(requestZaddr); + qDebug()<<"Incoming Pubkey :"<(ba.constData()); @@ -1335,7 +1337,7 @@ void Controller::refreshTransactions() { /////Our decrypted message is now in decrypted. We need it as QString to render it /////Only the QString gives weird data, so convert first to std::string // crypto_secretstream_xchacha20poly1305_keygen(client_rx); - if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, client_rx) != 0) { + if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, server_tx) != 0) { /* Invalid header, no need to go any further */ } From ce3120dcd1a60ef584f8f62d1274a064bbe6bf38 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 01:56:28 +0200 Subject: [PATCH 196/253] we use seedbytes --- src/chatmodel.cpp | 13 +++++++------ src/controller.cpp | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 69751ad..5df7693 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -429,8 +429,9 @@ Tx MainWindow::createTxFromChatPage() { ////////////////Generate the secretkey for our message encryption - const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); - const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); + char *hashEncryptionKeyraw = NULL; + hashEncryptionKeyraw = new char[length+1]; + strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1); #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) #define MESSAGEAS1_LEN length @@ -732,15 +733,15 @@ Tx MainWindow::createTxForSafeContactRequest() QString memo = contactRequest.getMemo(); // QString privkey = rpc->fetchPrivKey(myAddr); QString passphrase = this->getPassword(); - QString hashEncryptionKey = passphrase; + QString hashEncryptionKey = "Test"; int length = hashEncryptionKey.length(); qDebug()<<"Encryption String :"<(ba2.constData()); + char *hashEncryptionKeyraw = NULL; + hashEncryptionKeyraw = new char[length+1]; + strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1); #define MESSAGEAS1 ((const unsigned char *) hashEncryptionKeyraw) #define MESSAGEAS1_LEN length diff --git a/src/controller.cpp b/src/controller.cpp index 66b7823..6ca80cd 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -993,8 +993,9 @@ void Controller::refreshTransactions() { ////////////////Generate the secretkey for our message encryption - const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); - const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); + char *hashEncryptionKeyraw = NULL; + hashEncryptionKeyraw = new char[length+1]; + strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1); const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); @@ -1006,7 +1007,7 @@ void Controller::refreshTransactions() { #define MESSAGEAS1_LEN length - unsigned char hash1[crypto_kx_SECRETKEYBYTES]; + unsigned char hash1[crypto_kx_SEEDBYTES]; crypto_hash_sha256(hash1,MESSAGEAS1, MESSAGEAS1_LEN); unsigned char sk[crypto_kx_SECRETKEYBYTES]; @@ -1266,15 +1267,15 @@ void Controller::refreshTransactions() { qDebug()<<"Encryption String :"< 0)) { - const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); - const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); + //const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); + // const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); @@ -1284,7 +1285,7 @@ void Controller::refreshTransactions() { #define MESSAGEAS1_LEN length - unsigned char hash1[crypto_kx_SECRETKEYBYTES]; + unsigned char hash1[crypto_kx_SEEDBYTES]; crypto_hash_sha256(hash1,MESSAGEAS1, MESSAGEAS1_LEN); unsigned char sk[crypto_kx_SECRETKEYBYTES]; From 4b7af93e0d8a6a6b2c86aca1a96331672679f0b0 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 18:10:19 +0200 Subject: [PATCH 197/253] on/off switch for rendering encrypted messages --- src/addressbook.cpp | 4 +- src/chatmodel.cpp | 6 +-- src/controller.cpp | 97 +++++++++++++++++++++++++++------------------ src/mainwindow.ui | 14 +++++++ 4 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 591a9c0..ae81ae2 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -392,7 +392,7 @@ void AddressBook::readFromStorage() QDataStream in(&file); // read the data serialized from the file QString version; in >> version; - qDebug() << "Detected old addressbook format"; + // qDebug() << "Detected old addressbook format"; // Convert old addressbook format v1 to v2 QList> stuff; in >> stuff; @@ -408,7 +408,7 @@ void AddressBook::readFromStorage() allLabels.push_back(contact); } - qDebug() << "Read " << version << " Hush contacts from disk..."; + // qDebug() << "Read " << version << " Hush contacts from disk..."; file.close(); } else diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 5df7693..8d5d32f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -422,7 +422,7 @@ Tx MainWindow::createTxFromChatPage() { QString pubkey = this->getPubkeyByAddress(addr); QString passphrase = this->getPassword(); - QString hashEncryptionKey = "Test"; + QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); qDebug()<<"Pubkey Erstellung :"<refresh(true); + rpc->refresh(true); } QString MainWindow::doSendChatTxValidations(Tx tx) { @@ -733,7 +733,7 @@ Tx MainWindow::createTxForSafeContactRequest() QString memo = contactRequest.getMemo(); // QString privkey = rpc->fetchPrivKey(myAddr); QString passphrase = this->getPassword(); - QString hashEncryptionKey = "Test"; + QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); qDebug()<<"Encryption String :"<getHeaderByTx(txid) != QString("0xdeadbeef")){ headerbytes = chatModel->getHeaderByTx(txid); - qDebug()<<"headerbytes outgoing found"<getPubkeyByAddress(address); - qDebug()<<"Pubkey outgoing found"< 0)) { - /*for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) - { - - if (p.getPartnerAddress() == address) - { pubkey = p.getPubkey(); - }else {pubkey = ""; - }*/ + //QString myAddr = p.getMyAddress(); QString passphrase = main->getPassword(); - QString hashEncryptionKey = "Test"; + QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); - qDebug()<<"Encryption String :"<(pubkeyBobArray.constData()); - qDebug()<<"Pubkey benutzt incoming transaction:"<(ba1.constData()); - qDebug()<<"Header benutzt incoming transaction:"<(decrypted),MESSAGE1_LEN); - + QString memodecrypt; /////Now we can convert it to QString - QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + if (ui->decryptionMessage->isChecked()){ + memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + DataStore::getChatDataStore()->clear(); + this->refresh(true); + chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); + }else{ memodecrypt = memo; + DataStore::getChatDataStore()->clear(); + this->refresh(true); + chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); + } + //////////////Give us the output of the decrypted message as debug to see if it was successfully qDebug()<<"OUT decrypt:" << memodecrypt; @@ -1094,7 +1098,7 @@ void Controller::refreshTransactions() { DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - // } + }else{ @@ -1143,7 +1147,6 @@ void Controller::refreshTransactions() { model->markAddressUsed(address); QString memo; - QString test; if (!it["memo"].is_null()) { memo = QString::fromStdString(it["memo"]); } @@ -1205,10 +1208,11 @@ void Controller::refreshTransactions() { chatModel->addrequestZaddr(txid, requestZaddr); chatModel->addHeader(txid, headerbytes); - if (publickey.length() > 0){ + if (publickey.length() > 10){ main->addPubkey(requestZaddr, publickey); } - + qDebug()<<"Scane HM Incoming:"; + qDebug()<<"Scane HM Incoming:"<getHeaderByTx(txid) != QString("0xdeadbeef")){ headerbytes = chatModel->getHeaderByTx(txid); - qDebug()<<"HEADERBYTE INCOMING"<getPubkeyByAddress(requestZaddr) != QString("0xdeadbeef")){ publickey = main->getPubkeyByAddress(requestZaddr); - qDebug()<<"Incoming Pubkey :"< 20)) + { + + int lengthcid = cid.length(); QString passphrase = main->getPassword(); - QString hashEncryptionKey = "Test"; + QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); - qDebug()<<"Encryption String :"< 0)) - { - //const QByteArray ba2 = QByteArray::fromHex(hashEncryptionKey.toLatin1()); // const unsigned char *hashEncryptionKeyraw = reinterpret_cast(ba2.constData()); @@ -1296,7 +1301,7 @@ void Controller::refreshTransactions() { } - unsigned char server_rx[crypto_kx_SESSIONKEYBYTES], server_tx[crypto_kx_SESSIONKEYBYTES]; + unsigned char client_rx[crypto_kx_SESSIONKEYBYTES], client_tx[crypto_kx_SESSIONKEYBYTES]; ////////////////Get the pubkey from Bob, so we can create the share key @@ -1304,7 +1309,7 @@ void Controller::refreshTransactions() { /////Create the shared key for sending the message - if (crypto_kx_server_session_keys(server_rx, server_tx, + if (crypto_kx_client_session_keys(client_rx, client_tx, pk, sk, pubkeyBob) != 0) { /* Suspicious client public key, bail out */ } @@ -1338,7 +1343,7 @@ void Controller::refreshTransactions() { /////Our decrypted message is now in decrypted. We need it as QString to render it /////Only the QString gives weird data, so convert first to std::string // crypto_secretstream_xchacha20poly1305_keygen(client_rx); - if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, server_tx) != 0) { + if (crypto_secretstream_xchacha20poly1305_init_pull(&state, header, client_rx) != 0) { /* Invalid header, no need to go any further */ } @@ -1350,10 +1355,22 @@ void Controller::refreshTransactions() { std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); /////Now we can convert it to QString - QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + QString memodecrypt; + if (ui->decryptionMessage->isChecked()){ + memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + DataStore::getChatDataStore()->clear(); + this->refresh(true); + chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); + }else{ memodecrypt = memo; + DataStore::getChatDataStore()->clear(); + this->refresh(true); + chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); + } + + // } //////////////Give us the output of the decrypted message as debug to see if it was successfully - qDebug()<<"OUT decrypt:" << memodecrypt; + ChatItem item = ChatItem( @@ -1372,12 +1389,13 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + qDebug()<<"Pushe decrypte Items:"; }else{ - - ChatItem item = ChatItem( + qDebug()<<"Pushe plain Items 1:"; + ChatItem item = ChatItem( datetime, address, QString(""), @@ -1392,13 +1410,15 @@ void Controller::refreshTransactions() { isContact ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); + + qDebug()<<"Pushe Plain items 2:"; } } } - } } + } // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds @@ -1410,7 +1430,8 @@ void Controller::refreshTransactions() { } } } - getModel()->setTotalPending(totalPending); + + getModel()->setTotalPending(totalPending); // Update UI Balance updateUIBalances(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index de58411..a715861 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1703,6 +1703,19 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + 900 + 10 + 281 + 23 + + + + Message encryption/decryption ON + + listContactWidget label_39 contactNameMemo @@ -1714,6 +1727,7 @@ listChat memoTxtChat sendChatButton + decryptionMessage From 8ffed6683c012ca87e14d5aa030f4ac2ca95607c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 20:19:18 +0200 Subject: [PATCH 198/253] dont refresh to often --- src/DataStore/ChatDataStore.cpp | 3 ++- src/chatmodel.cpp | 2 +- src/controller.cpp | 35 +++++++++++++-------------------- src/controller.h | 1 + src/mainwindow.cpp | 4 +++- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 7bb3840..7b03c0e 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -60,7 +60,8 @@ std::map ChatDataStore::getAllNewContactRequests() if ( (c.second.isOutgoing() == false) && (c.second.getType() == "Cont") && - (c.second.isContact() == false) + (c.second.isContact() == false) && + (c.second.getMemo().isEmpty()) ) { diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 8d5d32f..2358ae9 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -618,7 +618,7 @@ void MainWindow::sendChat() { } ); - rpc->refresh(true); + // rpc->refresh(true); } QString MainWindow::doSendChatTxValidations(Tx tx) { diff --git a/src/controller.cpp b/src/controller.cpp index 4c7edfe..66c00b8 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -963,22 +963,12 @@ void Controller::refreshTransactions() { }else{ publickey = ""; } - - - - int lengthcid = cid.length(); - - char *cidchar = NULL; - cidchar = new char[lengthcid+1]; - strncpy(cidchar, cid.toLocal8Bit(), lengthcid +1); /////We need to filter out Memos smaller then the ciphertext size, or it will dump if ((memo.startsWith("{") == false) && (headerbytes > 0)) { - - //QString myAddr = p.getMyAddress(); QString passphrase = main->getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); @@ -1068,11 +1058,11 @@ void Controller::refreshTransactions() { if (ui->decryptionMessage->isChecked()){ memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); DataStore::getChatDataStore()->clear(); - this->refresh(true); + // this->refresh(true); chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); }else{ memodecrypt = memo; DataStore::getChatDataStore()->clear(); - this->refresh(true); + // this->refresh(true); chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); } @@ -1097,7 +1087,7 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + updateUIBalances(); }else{ @@ -1117,7 +1107,7 @@ void Controller::refreshTransactions() { false ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + updateUIBalances(); } } @@ -1181,7 +1171,7 @@ void Controller::refreshTransactions() { chatModel->addAddressbylabel(address, requestZaddr); } else{} - + } if (chatModel->Addressbylabel(address) != QString("0xdeadbeef")){ isContact = true; @@ -1359,12 +1349,15 @@ void Controller::refreshTransactions() { if (ui->decryptionMessage->isChecked()){ memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); DataStore::getChatDataStore()->clear(); - this->refresh(true); - chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); - }else{ memodecrypt = memo; - DataStore::getChatDataStore()->clear(); - this->refresh(true); + // this->refresh(true); chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); + + }else{ + + memodecrypt = memo; + DataStore::getChatDataStore()->clear(); + //this->refresh(true); + chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); } @@ -1415,7 +1408,7 @@ void Controller::refreshTransactions() { } - } + // } } } } diff --git a/src/controller.h b/src/controller.h index 9fd445b..f66596f 100644 --- a/src/controller.h +++ b/src/controller.h @@ -80,6 +80,7 @@ public: void refreshGBPCAP(); void refreshAUDCAP(); + void refreshChat(QListView *listWidget, QLabel *label); void refreshContacts(QListView *listWidget); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bd12d90..4984811 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1357,7 +1357,9 @@ void MainWindow::setupchatTab() { ui->memoTxtChat->setTextColor("Black"); } - + + ui->decryptionMessage->setChecked(true); + QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); From e2caf2b3e87cd7bae13410d356d403f2bf03b60a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 21:01:18 +0200 Subject: [PATCH 199/253] only one passphrase at beginning --- src/DataStore/ChatDataStore.cpp | 3 +-- src/mainwindow.cpp | 29 ++++----------------- src/startupencryption.ui | 45 --------------------------------- 3 files changed, 6 insertions(+), 71 deletions(-) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 7b03c0e..dfa7d54 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -60,8 +60,7 @@ std::map ChatDataStore::getAllNewContactRequests() if ( (c.second.isOutgoing() == false) && (c.second.getType() == "Cont") && - (c.second.isContact() == false) && - (c.second.getMemo().isEmpty()) + (c.second.isContact() == false) ) { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4984811..fd1cdd6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -538,34 +538,15 @@ void MainWindow::removeWalletEncryptionStartUp() { QDialog d(this); Ui_startup ed; ed.setupUi(&d); - - // Handle edits on the password box - auto fnPasswordEdited = [=](const QString&) { - QString password = ed.txtPassword->text(); - // Enable the OK button if the passwords match. - if (!ed.txtPassword->text().isEmpty() && - ed.txtPassword->text() == ed.txtConfirmPassword->text() && password.size() >= 16) { - ed.lblPasswordMatch->setText(""); - ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); - } else { - ed.lblPasswordMatch->setText(tr("Passwords don't match or under-lettered")); - ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); - } - - }; - - QObject::connect(ed.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); - QObject::connect(ed.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); - if (d.exec() == QDialog::Accepted) { - QString str = ed.txtPassword->text(); // data comes from user inputs - int length = str.length(); - this->setPassword(str); + QString password = ed.txtPassword->text(); // data comes from user inputs + int length = password.length(); + this->setPassword(password); char *sequence = NULL; sequence = new char[length+1]; - strncpy(sequence, str.toLocal8Bit(), length +1); + strncpy(sequence, password.toLocal8Bit(), length +1); #define MESSAGE ((const unsigned char *) sequence) #define MESSAGE_LEN length @@ -614,7 +595,7 @@ void MainWindow::removeWalletEncryptionStartUp() { { - QMessageBox::warning(this, tr("You have still Plaintextdata on your disk!"), + QMessageBox::information(this, tr("You have still Plaintextdata on your disk!"), QString("WARNING: Delete it only if you have a backup of your Wallet Seed."), QMessageBox::Ok ); diff --git a/src/startupencryption.ui b/src/startupencryption.ui index 6abdad1..819a698 100644 --- a/src/startupencryption.ui +++ b/src/startupencryption.ui @@ -29,19 +29,6 @@ QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - 10 - 229 - 127 - 25 - - - - Confirm Password: - - @@ -55,19 +42,6 @@ Qt::Horizontal - - - - 162 - 229 - 230 - 25 - - - - QLineEdit::Password - - @@ -113,25 +87,6 @@ Encryption Password: - - - - 10 - 175 - 382 - 17 - - - - color: red; - - - Passwords don't match - - - Qt::AlignCenter - - From 98431babb3463aee50c9d103ffdb81a2b010ff16 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 2 Jun 2020 21:26:34 +0200 Subject: [PATCH 200/253] set maximum chars to 235 --- src/chatmodel.cpp | 8 ++++---- src/mainwindow.h | 2 +- src/mainwindow.ui | 2 +- src/requestdialog.ui | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 2358ae9..09e54f3 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -526,14 +526,14 @@ void MainWindow::sendChat() { return; } - int max = 512; + int max = 235; QString chattext = ui->memoTxtChat->toPlainText(); int size = chattext.size(); if (size > max){ QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"), - tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 512 character."), + tr("You can only write messages with 235 character maximum \n") + tr("\n Please reduce your message to 235 character."), QMessageBox::Ok, this); msg.exec(); @@ -790,7 +790,7 @@ void MainWindow::ContactRequest() { return; } - int max = 512; + int max = 235; QString chattext = contactRequest.getMemo();; int size = chattext.size(); @@ -799,7 +799,7 @@ void MainWindow::ContactRequest() { // auto addr = ""; // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { QMessageBox msg(QMessageBox::Critical, tr("Your Message is too long"), - tr("You can only write messages with 512 character maximum \n") + tr("\n Please reduce your message to 512 character."), + tr("You can only write messages with 235 character maximum \n") + tr("\n Please reduce your message to 235 character."), QMessageBox::Ok, this); msg.exec(); diff --git a/src/mainwindow.h b/src/mainwindow.h index 8c63540..bb56d5b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -211,7 +211,7 @@ public: void updateDisplayChat(); private: - int maxlenchat = 512; + int maxlenchat = 235; QLabel* lenDisplayLabelchat = nullptr; QPushButton* sendChatButton = nullptr; }; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index a715861..33e2b16 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1697,7 +1697,7 @@ QFrame::Sunken - 0 / 512 + 0 / 235 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/src/requestdialog.ui b/src/requestdialog.ui index e52c475..f12e3e6 100644 --- a/src/requestdialog.ui +++ b/src/requestdialog.ui @@ -101,7 +101,7 @@ - 0 / 512 + 0 / 235 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter From 32a706339cd8f22147cd3c697c525c42868807de Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 3 Jun 2020 09:12:45 +0200 Subject: [PATCH 201/253] copy hushchat addr --- src/mainwindow.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fd1cdd6..0e42cdd 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1861,8 +1861,11 @@ void MainWindow::on_givemeZaddr_clicked() bool sapling = true; rpc->createNewZaddr(sapling, [=] (json reply) { QString hushchataddr = QString::fromStdString(reply.get()[0]); - QMessageBox::information(this, "Your new Hushchataddress",hushchataddr); - // ui->listReceiveAddresses->insertItem(0, hushchataddr); - // ui->listReceiveAddresses->setCurrentIndex(0); + QClipboard *zaddr_Clipboard = QApplication::clipboard(); + zaddr_Clipboard ->setText(hushchataddr); + QMessageBox::information(this, "Your new Hushchataddress was copied in your clipboard",hushchataddr); + ui->listReceiveAddresses->insertItem(0, hushchataddr); + ui->listReceiveAddresses->setCurrentIndex(0); + }); } From e105cee439e6bf35be294e830ff94e95eb1cb63e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 3 Jun 2020 09:52:55 +0200 Subject: [PATCH 202/253] rename password to passphrase --- src/chatmodel.cpp | 2 +- src/mainwindow.ui | 2 +- src/removeencryption.ui | 2 +- src/startupencryption.ui | 142 +++++++++++++++------------------------ 4 files changed, 57 insertions(+), 91 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 09e54f3..3d26cd1 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -516,7 +516,7 @@ void MainWindow::sendChat() { QString Name = ui->contactNameMemo->text(); int sizename = Name.size(); qDebug()<< sizename; - if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { + if ((sizename < 1) || (ui->memoTxtChat->toPlainText().trimmed().isEmpty())) { QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 33e2b16..10a2018 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1442,7 +1442,7 @@ 460 20 - 161 + 291 20 diff --git a/src/removeencryption.ui b/src/removeencryption.ui index 77d7239..c29db42 100644 --- a/src/removeencryption.ui +++ b/src/removeencryption.ui @@ -91,7 +91,7 @@ - <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If yo remove your encryption, all your Data is Plaintext on your Disk!</p></body></html> + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your encryption, all your transactions and Contacts are plaintext on disk! Messages are still encrypt.</p></body></html> Qt::AlignCenter diff --git a/src/startupencryption.ui b/src/startupencryption.ui index 819a698..6b8d1ac 100644 --- a/src/startupencryption.ui +++ b/src/startupencryption.ui @@ -7,99 +7,65 @@ 0 0 400 - 300 + 177 SDL Startup Decryption - - - - 50 - 260 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 10 - 166 - 382 - 3 - - - - Qt::Horizontal - - - - - - 10 - 58 - 382 - 56 - - - - <html><head/><body><p>If you have forgotten your password, restore your wallet with your seed!</p></body></html> - - - Qt::AlignCenter - - - true - - - - - - 10 - 260 - 382 - 3 - - - - Qt::Horizontal - - - - - - 10 - 198 - 146 - 25 - - - - Encryption Password: - - - - - - 162 - 198 - 230 - 25 - - - - QLineEdit::Password - - + + + + + <html><head/><body><p>If you have forgotten your passphrase restore your wallet with your seed!</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + Qt::Horizontal + + + + + + + Encryption Passphrase: + + + + + + + QLineEdit::Password + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + From f46068681cb25241a2f719abc2c41ffdc6416ca7 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 3 Jun 2020 10:00:37 +0200 Subject: [PATCH 203/253] remove recurring from ui Issue #77 --- src/mainwindow.ui | 31 ++-------------------- src/sendtab.cpp | 66 +++++++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 62 deletions(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 10a2018..a978389 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -59,7 +59,7 @@ - 5 + 1 @@ -426,7 +426,7 @@ 0 0 1226 - 488 + 493 @@ -611,33 +611,6 @@ - - - - Recurring payment - - - - - - - Every month, starting 12-May-2012, for 6 payments - - - - - - - Edit Schedule - - - false - - - false - - - diff --git a/src/sendtab.cpp b/src/sendtab.cpp index ce04a54..6f3fc11 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -138,7 +138,7 @@ void MainWindow::setupSendTab() { ui->MemoTxt1->setFont(f); // Recurring button - QObject::connect(ui->chkRecurring, &QCheckBox::stateChanged, [=] (int checked) { + /*QObject::connect(ui->chkRecurring, &QCheckBox::stateChanged, [=] (int checked) { if (checked) { ui->btnRecurSchedule->setEnabled(true); @@ -150,23 +150,23 @@ void MainWindow::setupSendTab() { ui->btnRecurSchedule->setEnabled(false); ui->lblRecurDesc->setText(""); } - }); + });*/ // Recurring schedule button - QObject::connect(ui->btnRecurSchedule, &QPushButton::clicked, this, &MainWindow::editSchedule); + // QObject::connect(ui->btnRecurSchedule, &QPushButton::clicked, this, &MainWindow::editSchedule); // Set the default state for the whole page clearSendForm(); } void MainWindow::disableRecurring() { - if (!Settings::getInstance()->isTestnet()) { +/* if (!Settings::getInstance()->isTestnet()) { ui->chkRecurring->setVisible(false); ui->chkRecurring->setEnabled(false); ui->btnRecurSchedule->setVisible(false); ui->btnRecurSchedule->setEnabled(false); - ui->action_Recurring_Payments->setVisible(false); - } + ui->action_Recurring_Payments->setVisible(false);*/ + // } } void MainWindow::editSchedule() { @@ -185,21 +185,21 @@ void MainWindow::editSchedule() { } // Open the edit schedule dialog - auto recurringInfo = Recurring::getInstance()->getNewRecurringFromTx(this, this, - createTxFromSendPage(), this->sendTxRecurringInfo); - if (recurringInfo == nullptr) { + // auto recurringInfo = Recurring::getInstance()->getNewRecurringFromTx(this, this, + // createTxFromSendPage(), this->sendTxRecurringInfo); + // if (recurringInfo == nullptr) { // User pressed cancel. // If there is no existing recurring info, uncheck the recurring box - if (sendTxRecurringInfo == nullptr) { - ui->chkRecurring->setCheckState(Qt::Unchecked); - } - } - else { - delete this->sendTxRecurringInfo; + // if (sendTxRecurringInfo == nullptr) { + // ui->chkRecurring->setCheckState(Qt::Unchecked); + // } + // } + // else { + // delete this->sendTxRecurringInfo; - this->sendTxRecurringInfo = recurringInfo; - ui->lblRecurDesc->setText(recurringInfo->getScheduleDescription()); - } + // this->sendTxRecurringInfo = recurringInfo; + // ui->lblRecurDesc->setText(recurringInfo->getScheduleDescription()); + //} } void MainWindow::updateLabelsAutoComplete() { @@ -311,11 +311,11 @@ void MainWindow::addAddressSection() { // Disable recurring payments if a address section is added, since recurring payments // aren't supported for more than 1 address - delete sendTxRecurringInfo; - sendTxRecurringInfo = nullptr; - ui->lblRecurDesc->setText(""); - ui->chkRecurring->setChecked(false); - ui->chkRecurring->setEnabled(false); + // delete sendTxRecurringInfo; + // sendTxRecurringInfo = nullptr; + // ui->lblRecurDesc->setText(""); + // ui->chkRecurring->setChecked(false); + // ui->chkRecurring->setEnabled(false); // Set focus into the address Address1->setFocus(); @@ -358,10 +358,10 @@ void MainWindow::amountChanged(int item, const QString& text) { } // If there is a recurring payment, update the info there as well - if (sendTxRecurringInfo != nullptr) { - Recurring::getInstance()->updateInfoWithTx(sendTxRecurringInfo, createTxFromSendPage()); - ui->lblRecurDesc->setText(sendTxRecurringInfo->getScheduleDescription()); - } + //if (sendTxRecurringInfo != nullptr) { + // Recurring::getInstance()->updateInfoWithTx(sendTxRecurringInfo, createTxFromSendPage()); + // ui->lblRecurDesc->setText(sendTxRecurringInfo->getScheduleDescription()); + // } } void MainWindow::setMemoEnabled(int number, bool enabled) { @@ -457,14 +457,14 @@ void MainWindow::clearSendForm() { // Reset the recurring button if (Settings::getInstance()->isTestnet()) { - ui->chkRecurring->setEnabled(true); + // ui->chkRecurring->setEnabled(true); } - ui->chkRecurring->setCheckState(Qt::Unchecked); - ui->btnRecurSchedule->setEnabled(false); - ui->lblRecurDesc->setText(""); - delete sendTxRecurringInfo; - sendTxRecurringInfo = nullptr; + // ui->chkRecurring->setCheckState(Qt::Unchecked); + // ui->btnRecurSchedule->setEnabled(false); + // ui->lblRecurDesc->setText(""); + // delete sendTxRecurringInfo; + // sendTxRecurringInfo = nullptr; } void MainWindow::maxAmountChecked(int checked) { From a8402141913ea95a4386eeff0fb3a42f478634a5 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 3 Jun 2020 20:19:32 +0200 Subject: [PATCH 204/253] dont delete our chatitems --- src/controller.cpp | 44 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 66c00b8..46f7342 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1055,16 +1055,10 @@ void Controller::refreshTransactions() { std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); QString memodecrypt; /////Now we can convert it to QString - if (ui->decryptionMessage->isChecked()){ + memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); - DataStore::getChatDataStore()->clear(); - // this->refresh(true); - chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); - }else{ memodecrypt = memo; - DataStore::getChatDataStore()->clear(); - // this->refresh(true); - chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); - } + + //////////////Give us the output of the decrypted message as debug to see if it was successfully @@ -1240,7 +1234,7 @@ void Controller::refreshTransactions() { publickey = ""; } - //position = it["position"].get(); + bool isNotarized; @@ -1252,9 +1246,6 @@ void Controller::refreshTransactions() { isNotarized = false; } - - qDebug()<<"Kurz vor decryption:"; - if ((memo.startsWith("{") == false) && (headerbytes > 20)) { @@ -1263,8 +1254,6 @@ void Controller::refreshTransactions() { QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); - qDebug()<<"Encryption passphrase :"<decryptionMessage->isChecked()){ + memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); - DataStore::getChatDataStore()->clear(); - // this->refresh(true); - chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); - - }else{ - - memodecrypt = memo; - DataStore::getChatDataStore()->clear(); - //this->refresh(true); - chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); - } + // } @@ -1382,12 +1361,10 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - qDebug()<<"Pushe decrypte Items:"; }else{ - qDebug()<<"Pushe plain Items 1:"; ChatItem item = ChatItem( datetime, address, @@ -1404,14 +1381,11 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - qDebug()<<"Pushe Plain items 2:"; - } - - // } + } + } } - } - } + } // Calculate the total unspent amount that's pending. This will need to be // shown in the UI so the user can keep track of pending funds From e39c19f75ea0d9c36cd688e3d5d02fedfbeae205 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 3 Jun 2020 20:20:46 +0200 Subject: [PATCH 205/253] rename copy message --- src/mainwindow.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0e42cdd..54ab804 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -284,9 +284,11 @@ void MainWindow::closeEvent(QCloseEvent* event) { // Let the RPC know to shut down any running service. rpc->shutdownhushd(); + int passphraselenght = this->getPassword().length(); + qDebug()<<"LÄNGE PW : "< 0) { // delete old file before @@ -392,13 +394,13 @@ void MainWindow::encryptWallet() { if (d.exec() == QDialog::Accepted) { - QString str = ed.txtPassword->text(); // data comes from user inputs - int length = str.length(); - this->setPassword(str); + QString passphrase = ed.txtPassword->text(); // data comes from user inputs + int length = passphrase.length(); + this->setPassword(passphrase); char *sequence = NULL; sequence = new char[length+1]; - strncpy(sequence, str.toLocal8Bit(), length +1); + strncpy(sequence, passphrase.toLocal8Bit(), length +1); #define MESSAGE ((const unsigned char *) sequence) #define MESSAGE_LEN length @@ -1863,7 +1865,7 @@ void MainWindow::on_givemeZaddr_clicked() QString hushchataddr = QString::fromStdString(reply.get()[0]); QClipboard *zaddr_Clipboard = QApplication::clipboard(); zaddr_Clipboard ->setText(hushchataddr); - QMessageBox::information(this, "Your new Hushchataddress was copied in your clipboard",hushchataddr); + QMessageBox::information(this, "Your new HushChat address was copied to your clipboard!",hushchataddr); ui->listReceiveAddresses->insertItem(0, hushchataddr); ui->listReceiveAddresses->setCurrentIndex(0); From b9a4aa8889eeb168013b3b4b83cbfdeab6767960 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 3 Jun 2020 22:15:46 +0200 Subject: [PATCH 206/253] fix for outgoing messages --- src/controller.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 46f7342..b5754a4 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -882,12 +882,13 @@ void Controller::refreshTransactions() { auto txid = QString::fromStdString(it["txid"]); auto datetime = it["datetime"].get(); - + // First, check if there's outgoing metadata if (!it["outgoing_metadata"].is_null()) { - for (auto o: it["outgoing_metadata"].get()) { - + for (auto o: it["outgoing_metadata"].get()) + { + // if (chatModel->getCidByTx(txid) == QString("0xdeadbeef")){ QString address; address = QString::fromStdString(o["address"]); @@ -966,7 +967,7 @@ void Controller::refreshTransactions() { /////We need to filter out Memos smaller then the ciphertext size, or it will dump - if ((memo.startsWith("{") == false) && (headerbytes > 0)) + if ((memo.startsWith("{") == false) && (headerbytes.length() > 20)) { QString passphrase = main->getPassword(); @@ -1053,13 +1054,11 @@ void Controller::refreshTransactions() { } std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); - QString memodecrypt; + /////Now we can convert it to QString - memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); - - - + QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + //////////////Give us the output of the decrypted message as debug to see if it was successfully qDebug()<<"OUT decrypt:" << memodecrypt; @@ -1080,10 +1079,11 @@ void Controller::refreshTransactions() { false ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + updateUIBalances(); - }else{ + } + /*else{ ChatItem item = ChatItem( @@ -1102,12 +1102,17 @@ void Controller::refreshTransactions() { ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); updateUIBalances(); - } + }*/ } items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; - } + // }else{ + + + // } + // } + } { QList addresses; From 789b4f5fb7f7545fefe815d2ef92829a036f3241 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 4 Jun 2020 01:39:54 +0200 Subject: [PATCH 207/253] use chatitems instead of decryption every time --- src/chatmodel.cpp | 24 ++++++++++++++++++++++++ src/chatmodel.h | 4 ++++ src/controller.cpp | 30 ++++++++++++++++++++++-------- src/mainwindow.ui | 17 ++++++++++++++++- src/settings.cpp | 2 +- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 3d26cd1..caa704c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -260,6 +260,11 @@ void ChatModel::addHeader(QString tx, QString headerbytes) this->headerMap[tx] = headerbytes; } +void ChatModel::addMemo(QString tx, QString memo) +{ + this->OldMemoByTx[tx] = memo; +} + void ChatModel::addrequestZaddr(QString tx, QString requestZaddr) @@ -287,6 +292,21 @@ QString ChatModel::getCidByTx(QString tx) return QString("0xdeadbeef"); } +QString ChatModel::getMemoByTx(QString tx) +{ + for(auto& pair : this->OldMemoByTx) + { + + } + + if(this->OldMemoByTx.count(tx) > 0) + { + return this->OldMemoByTx[tx]; + } + + return QString("0xdeadbeef"); +} + @@ -349,6 +369,10 @@ void ChatModel::killConfirmationCache() { this->confirmationsMap.clear(); } +void ChatModel::killMemoCache() +{ + this->OldMemoByTx.clear(); +} QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, QString headerbytes, QString publickey, int version=0, int headerNumber=1) { diff --git a/src/chatmodel.h b/src/chatmodel.h index 6e6008e..1676993 100644 --- a/src/chatmodel.h +++ b/src/chatmodel.h @@ -37,6 +37,7 @@ class ChatModel std::map> sendrequestMap; std::map headerMap; std::map AddressbyLabelMap; + std::map OldMemoByTx; public: @@ -55,6 +56,7 @@ class ChatModel void addMessage(QString timestamp, ChatItem item); void addCid(QString tx, QString cid); void addHeader(QString tx, QString headerbytes); + void addMemo(QString tx, QString memo); void addrequestZaddr(QString tx, QString requestZaddr); void addconfirmations(QString tx, int confirmation); void addSendRequest(int i, QString myAddr, QString cid, QString addr ); @@ -62,10 +64,12 @@ class ChatModel QString getHeaderByTx(QString tx); QString getrequestZaddrByTx(QString tx); QString getConfirmationByTx(QString tx); + QString getMemoByTx(QString tx); QString Addressbylabel(QString addr); void killCidCache(); void killConfirmationCache(); void killrequestZaddrCache(); + void killMemoCache(); }; diff --git a/src/controller.cpp b/src/controller.cpp index b5754a4..f47ca17 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -905,6 +905,7 @@ void Controller::refreshTransactions() { if ((confirmations == 1) && (chatModel->getConfirmationByTx(txid) != QString("0xdeadbeef"))){ DataStore::getChatDataStore()->clear(); chatModel->killConfirmationCache(); + chatModel->killMemoCache(); this->refresh(true); } @@ -1107,11 +1108,7 @@ void Controller::refreshTransactions() { items.push_back(TransactionItemDetail{address, amount, memo}); total_amount = total_amount + amount; - // }else{ - - - // } - // } + } { @@ -1200,8 +1197,7 @@ void Controller::refreshTransactions() { if (publickey.length() > 10){ main->addPubkey(requestZaddr, publickey); } - qDebug()<<"Scane HM Incoming:"; - qDebug()<<"Scane HM Incoming:"< 20)) + int position = it["position"].get(); + + if ((memo.startsWith("{") == false) && (headerbytes > 0)) { + if (chatModel->getMemoByTx(txid) == QString("0xdeadbeef")){ + + + if (position == 1) + { + + chatModel->addMemo(txid, headerbytes); + }else{} + + + qDebug()<<"Position message :"<getPassword(); QString hashEncryptionKey = passphrase; @@ -1369,6 +1379,10 @@ void Controller::refreshTransactions() { }else{ + + } + + }else{ ChatItem item = ChatItem( datetime, diff --git a/src/mainwindow.ui b/src/mainwindow.ui index a978389..4cc5012 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -59,7 +59,7 @@ - 1 + 5 @@ -1502,9 +1502,21 @@ QAbstractScrollArea::AdjustToContents + + true + QAbstractItemView::NoEditTriggers + + QAbstractItemView::ContiguousSelection + + + QAbstractItemView::ScrollPerItem + + + QListView::Snap + QListView::Adjust @@ -1517,6 +1529,9 @@ true + + true + diff --git a/src/settings.cpp b/src/settings.cpp index 2d99ff7..f4b3e41 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -302,7 +302,7 @@ QString Settings::getDonationAddr() { if (Settings::getInstance()->isTestnet()) return "ztestsaplingXXX"; else - return "zs1kwp3h4rwz76zfqzmwqqextq696kndtjskg4fzc80l9ygfal4hchcsst83ua8tjwzzy9nja7v5rr"; + return "zs1fq9f7vg797qaeac9lyx0njyjmjg4w7m60hwq6lhyhvdcqltl5hdkm8vwx9cxy60ehuuz2x49jxt"; } From e668a703d3ada7622537f762b102aa798c384004 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 4 Jun 2020 13:37:14 +0200 Subject: [PATCH 208/253] fix file for apple --- src/mainwindow.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 54ab804..96cc217 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -40,12 +40,19 @@ auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLo auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet-enc.dat"); auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.datBackup"); #endif -#ifdef Q_OS_UNIX +#ifdef Q_OS_MACOS +auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.dat"); +auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet-enc.dat"); +auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite/silentdragonlite-wallet.datBackup"); +#endif +#ifdef Q_OS_LINUX auto dirwallet = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.dat"); auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet-enc.dat"); auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup"); #endif + + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) From 4aa1eb33b86022466207b9c0dc212aebadc86c17 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 4 Jun 2020 23:07:11 +0200 Subject: [PATCH 209/253] dialog box for encryption issue #95 --- src/mainwindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 96cc217..77eafb0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -446,6 +446,11 @@ void MainWindow::encryptWallet() { QFile address(dir.filePath("addresslabels.dat")); wallet.rename(dirwalletbackup); address.rename(dir.filePath("addresslabels.datBackup")); + + QMessageBox::information(this, tr("Wallet encryption Success"), + QString("Successfully encrypt your wallet"), + QMessageBox::Ok + ); } } From b1290454bd921f80d99efcd907bc1a42134ef87e Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 4 Jun 2020 23:08:05 +0200 Subject: [PATCH 210/253] fix typo --- src/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 77eafb0..57c193d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -447,7 +447,7 @@ void MainWindow::encryptWallet() { wallet.rename(dirwalletbackup); address.rename(dir.filePath("addresslabels.datBackup")); - QMessageBox::information(this, tr("Wallet encryption Success"), + QMessageBox::information(this, tr("Wallet Encryption Success"), QString("Successfully encrypt your wallet"), QMessageBox::Ok ); From 4f9c31474239f06bb3eb24f822fc38d586b2fa9f Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 4 Jun 2020 23:12:45 +0200 Subject: [PATCH 211/253] dont allow to remove wallet encryption if wallet is not encrypt issue #91 --- src/mainwindow.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 57c193d..73f2af4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -459,6 +459,14 @@ void MainWindow::removeWalletEncryption() { Ui_removeencryption ed; ed.setupUi(&d); + if (fileExists(dirwalletenc) == false) { + QMessageBox::information(this, tr("Wallet is not encrypted"), + tr("Your wallet is not encrypted with a passphrase."), + QMessageBox::Ok + ); + return; + } + auto fnPasswordEdited = [=](const QString&) { QString password = ed.txtPassword->text(); // Enable the OK button if the passwords match. From 6e4dc28badbedce95597294c6ee1560ad5b88f81 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Thu, 4 Jun 2020 22:20:08 -0400 Subject: [PATCH 212/253] Midnight Theme fixes & English updates. --- res/css/dark.css | 2 +- src/contactrequest.ui | 18 ------------------ src/removeencryption.ui | 2 +- src/requestContactDialog.ui | 12 ------------ src/startupencryption.ui | 2 +- 5 files changed, 3 insertions(+), 33 deletions(-) diff --git a/res/css/dark.css b/res/css/dark.css index 6dc6cfe..29dc683 100644 --- a/res/css/dark.css +++ b/res/css/dark.css @@ -25,7 +25,7 @@ QTabWidget QTabBar::tab:hover { background-color:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.25, stop: 0 #747577, stop: 1 #3E4244); color:#fff; border: 1px ridge #fff; -min-height: 20px +min-height: 20px; } QHeaderView { /* Table Header */ diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 9b28dca..d46676f 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -282,12 +282,6 @@ - - - 80 - 25 - - 100 @@ -320,18 +314,6 @@ - - - 300 - 25 - - - - - 100 - 0 - - Add Contact and send request diff --git a/src/removeencryption.ui b/src/removeencryption.ui index c29db42..11bee22 100644 --- a/src/removeencryption.ui +++ b/src/removeencryption.ui @@ -91,7 +91,7 @@ - <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your encryption, all your transactions and Contacts are plaintext on disk! Messages are still encrypt.</p></body></html> + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your encryption, all your transactions and contacts are plaintext on disk! Messages are still encrypt.</p></body></html> Qt::AlignCenter diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 4beeced..bc312dd 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -337,12 +337,6 @@ - - - 80 - 25 - - 100 @@ -362,12 +356,6 @@ - - - 153 - 25 - - Add this new Contact diff --git a/src/startupencryption.ui b/src/startupencryption.ui index 6b8d1ac..56fc02c 100644 --- a/src/startupencryption.ui +++ b/src/startupencryption.ui @@ -17,7 +17,7 @@ - <html><head/><body><p>If you have forgotten your passphrase restore your wallet with your seed!</p></body></html> + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> Qt::AlignCenter From 47c9b765975ca6767e815b6db404ac5c8dc39181 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Fri, 5 Jun 2020 15:22:28 -0400 Subject: [PATCH 213/253] Responsiveness for Chat Tab --- src/mainwindow.ui | 810 ++++++++++++++++++++++++---------------------- 1 file changed, 431 insertions(+), 379 deletions(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 4cc5012..82b43ab 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -426,7 +426,7 @@ 0 0 1226 - 493 + 509 @@ -1338,384 +1338,436 @@ HushChat - - - - 0 - 120 - 341 - 521 - - - - true - - - QAbstractItemView::NoEditTriggers - - - false - - - false - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectItems - - - - - - 0 - 100 - 341 - 20 - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> - - - - - - 340 - 560 - 921 - 81 - - - - false - - - font: 11pt "Noto Color Emoji"; - - - QTextEdit::AutoNone - - - QTextEdit::FixedPixelWidth - - - 600 - - - false - - - Qt::TextEditorInteraction - - - - - - 460 - 20 - 291 - 20 - - - - - 75 - true - - - - <html><head/><body><p align="center"><br/></p></body></html> - - - - - - 1160 - 560 - 91 - 81 - - - - - 100 - 0 - - - - false - - - - - - - :/icons/res/sendBlack.png - - - - - 50 - 49 - - - - false - - - true - - - - - - 340 - 20 - 111 - 20 - - - - <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> - - - - - - 340 - 40 - 921 - 521 - - - - The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustToContents - - - true - - - QAbstractItemView::NoEditTriggers - - - QAbstractItemView::ContiguousSelection - - - QAbstractItemView::ScrollPerItem - - - QListView::Snap - - - QListView::Adjust - - - 0 - - - false - - - true - - - true - - - - - - 10 - 20 - 51 - 51 - - - - - 51 - 51 - - - - - 51 - 51 - - - - - 100 - 0 - - - - Add a new contact - - - - - - - :/icons/res/addContactBlack.png - - - - - 50 - 45 - - - - true - - - - - - 80 - 20 - 51 - 51 - - - - - 51 - 51 - - - - - 51 - 51 - - - - - 100 - 0 - - - - Incoming contact request - - - false - - - - - - - :/icons/res/requestBlack.png:/icons/res/requestBlack.png - - - - 50 - 45 - - - - true - - - - - - 150 - 20 - 51 - 51 - - - - - 51 - 51 - - - - - 51 - 51 - - - - Get a new Address - - - - - - - :/icons/res/getAddrBlack.png:/icons/res/getAddrBlack.png - - - - 50 - 45 - - - - true - - - - - - 1140 - 640 - 91 - 17 - - - - QFrame::Sunken - - - 0 / 235 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 900 - 10 - 281 - 23 - - - - Message encryption/decryption ON - - - listContactWidget - label_39 - contactNameMemo - contactNameMemo_3 - safeContactRequest - pushContact - givemeZaddr - memoSizeChat - listChat - memoTxtChat - sendChatButton - decryptionMessage + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 15 + + + + + + 51 + 51 + + + + + 51 + 51 + + + + + 100 + 0 + + + + Incoming contact request + + + false + + + + + + + :/icons/res/requestBlack.png:/icons/res/requestBlack.png + + + + 50 + 45 + + + + true + + + + + + + + 51 + 51 + + + + + 51 + 51 + + + + + 100 + 0 + + + + Add a new contact + + + + + + + :/icons/res/addContactBlack.png + + + + + 50 + 45 + + + + true + + + + + + + + 51 + 51 + + + + + 51 + 51 + + + + Get a new Address + + + + + + + :/icons/res/getAddrBlack.png:/icons/res/getAddrBlack.png + + + + 50 + 45 + + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Preferred + + + + 100 + 20 + + + + + + + + + + + 0 + 0 + + + + + 300 + 0 + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + + + + + + + QLayout::SetDefaultConstraint + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + + + + 75 + true + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + Message encryption/decryption ON + + + + + + + + + + 0 + 0 + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustToContents + + + true + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::ContiguousSelection + + + QAbstractItemView::ScrollPerItem + + + QListView::Snap + + + QListView::Adjust + + + 0 + + + false + + + true + + + true + + + + + + + QLayout::SetDefaultConstraint + + + 0 + + + + + + 0 + 0 + + + + false + + + font: 11pt "Noto Color Emoji"; + + + QTextEdit::AutoNone + + + QTextEdit::WidgetWidth + + + 600 + + + false + + + Qt::TextEditorInteraction + + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + false + + + + + + + :/icons/res/sendBlack.png + + + + + 50 + 49 + + + + false + + + true + + + + + + + + 0 + 0 + + + + QFrame::Sunken + + + 0 / 235 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + From c69abfc7f9c5fe84cfc9301244183cccd088ba6d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 5 Jun 2020 22:26:58 +0200 Subject: [PATCH 214/253] change animation for sending messages #84 --- application.qrc | 2 + res/loaderblack.gif | Bin 0 -> 5627 bytes res/loaderwhite.gif | Bin 0 -> 5586 bytes src/chatmodel.cpp | 94 +++++++++++++++++++++++++------------------- src/mainwindow.ui | 2 +- 5 files changed, 56 insertions(+), 42 deletions(-) create mode 100644 res/loaderblack.gif create mode 100644 res/loaderwhite.gif diff --git a/application.qrc b/application.qrc index d62ea29..345aac4 100644 --- a/application.qrc +++ b/application.qrc @@ -55,6 +55,8 @@ res/silentdragonlite-animated-dark.gif res/silentdragonlite-animated-startup.gif res/silentdragonlite-animated-startup-dark.gif + res/loaderblack.gif + res/loaderwhite.gif res/silentdragonlite_de.qm diff --git a/res/loaderblack.gif b/res/loaderblack.gif new file mode 100644 index 0000000000000000000000000000000000000000..764a3f87be851954989c67de2ce51051cef211ec GIT binary patch literal 5627 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 literal 0 HcmV?d00001 diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index caa704c..d88e95f 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -580,44 +580,51 @@ void MainWindow::sendChat() { qDebug() << "Tx aborted"; } - // Create a new Dialog to show that we are computing/sending the Tx - auto d = new QDialog(this); - auto connD = new Ui_ConnectionDialog(); - connD->setupUi(d); - QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif");; - QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif");; + auto movie = new QMovie(this); + auto movie1 = new QMovie(this); + movie->setFileName(":/img/res/loaderblack.gif"); + movie1->setFileName(":/img/res/loaderwhite.gif"); + auto theme = Settings::getInstance()->get_theme_name(); if (theme == "dark" || theme == "midnight") { - movie2->setScaledSize(QSize(512,512)); - connD->topIcon->setMovie(movie2); - movie2->start(); + + connect(movie, &QMovie::frameChanged, [=]{ + ui->sendChatButton->setIcon(movie->currentPixmap()); + }); + movie->start(); + ui->sendChatButton->show(); + } else { - movie1->setScaledSize(QSize(512,512)); - connD->topIcon->setMovie(movie1); - movie1->start(); + + connect(movie1, &QMovie::frameChanged, [=]{ + ui->sendChatButton->setIcon(movie1->currentPixmap()); + }); + movie1->start(); + ui->sendChatButton->show(); } - connD->status->setText(tr("Please wait...")); - connD->statusDetail->setText(tr("Your Message will be sent")); - - d->show(); ui->memoTxtChat->clear(); - // And send the Tx rpc->executeTransaction(tx, [=] (QString txid) { ui->statusBar->showMessage(Settings::txidStatusMessage + " " + txid); - - connD->status->setText(tr("Done!")); - connD->statusDetail->setText(txid); - QTimer::singleShot(1000, [=]() { - d->accept(); - d->close(); - delete connD; - delete d; + QTimer::singleShot(1000, [=]() { + + if (theme == "dark" || theme == "midnight") { + QPixmap send(":/icons/res/send-white.png"); + QIcon sendIcon(send); + ui->sendChatButton->setIcon(sendIcon); + movie->stop(); + }else{ + + QPixmap send(":/icons/res/sendBlack.png"); + QIcon sendIcon(send); + ui->sendChatButton->setIcon(sendIcon); + movie1->stop(); + } }); @@ -630,19 +637,31 @@ void MainWindow::sendChat() { [=] (QString opid, QString errStr) { ui->statusBar->showMessage(QObject::tr(" Tx ") % opid % QObject::tr(" failed"), 15 * 1000); - d->accept(); - d->close(); - delete connD; - delete d; - if (!opid.isEmpty()) errStr = QObject::tr("The transaction with id ") % opid % QObject::tr(" failed. The error was") + ":\n\n" + errStr; - QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); + QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); + movie->stop(); + + + if (theme == "dark" || theme == "midnight") { + QPixmap send(":/icons/res/send-white.png"); + QIcon sendIcon(send); + ui->sendChatButton->setIcon(sendIcon); + movie->stop(); + }else{ + + QPixmap send(":/icons/res/sendBlack.png"); + QIcon sendIcon(send); + ui->sendChatButton->setIcon(sendIcon); + movie1->stop(); + } + + + } ); - // rpc->refresh(true); } QString MainWindow::doSendChatTxValidations(Tx tx) { @@ -760,8 +779,6 @@ Tx MainWindow::createTxForSafeContactRequest() QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); - qDebug()<<"Encryption String :"<(pk), crypto_kx_PUBLICKEYBYTES).toHex(); - qDebug()<<"Publickey created Request: "<setupUi(d); - QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif");; - QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif");; + QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif"); + QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif"); auto theme = Settings::getInstance()->get_theme_name(); if (theme == "dark" || theme == "midnight") { movie2->setScaledSize(QSize(512,512)); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 82b43ab..c6a5fc1 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -426,7 +426,7 @@ 0 0 1226 - 509 + 493 From 495d588b307cd105dab67163e7614cc611d5b561 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 5 Jun 2020 22:36:36 +0200 Subject: [PATCH 215/253] set default theme to dark --- src/settings.cpp | 2 +- src/settings.ui | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index f4b3e41..dfe1e11 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -230,7 +230,7 @@ void Settings::set_currency_name(QString currency_name) { QString Settings::get_theme_name() { // Load from the QT Settings. - return QSettings().value("options/theme_name", false).toString(); + return QSettings().value("options/theme_name", "dark").toString(); } void Settings::set_theme_name(QString theme_name) { diff --git a/src/settings.ui b/src/settings.ui index 6871c7b..ac730fb 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -95,6 +95,11 @@ 0 + + + dark + + default @@ -110,11 +115,6 @@ light - - - dark - - midnight From 70dbc1f13151910a08b7dcc24a957506a1570df1 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 5 Jun 2020 23:13:03 +0200 Subject: [PATCH 216/253] dont write message over the border of chatbubble --- src/Chat/Helper/ChatDelegator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chat/Helper/ChatDelegator.h b/src/Chat/Helper/ChatDelegator.h index 10b45e5..72f3c1e 100644 --- a/src/Chat/Helper/ChatDelegator.h +++ b/src/Chat/Helper/ChatDelegator.h @@ -37,7 +37,7 @@ class ListViewDelegate : public QAbstractItemDelegate inline QSize sizeHint(QStyleOptionViewItem const &option, QModelIndex const &index) const; }; -inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(7), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(10), d_pointerheight(17), d_widthfraction(.7) +inline ListViewDelegate::ListViewDelegate(QObject *parent): QAbstractItemDelegate(parent), d_radius(5), d_toppadding(5), d_bottompadding(3), d_leftpadding(5), d_rightpadding(5), d_verticalmargin(5), d_horizontalmargin(10), d_pointerwidth(4), d_pointerheight(17), d_widthfraction(.6) { } From 65dd00919e96b747fed8f084d07cd9d15deea775 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 5 Jun 2020 23:28:15 +0200 Subject: [PATCH 217/253] change date format to yyyy-MM-dd #82 --- src/Chat/Chat.cpp | 2 +- src/Chat/Chat.h | 14 -------------- src/Model/ChatItem.cpp | 2 +- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/Chat/Chat.cpp b/src/Chat/Chat.cpp index cdc3814..672808c 100644 --- a/src/Chat/Chat.cpp +++ b/src/Chat/Chat.cpp @@ -66,7 +66,7 @@ void Chat::renderChatBox(Ui::MainWindow *ui, QListView *view, QLabel *label) Items->setData(OUTGOING, Qt::UserRole + 1); chat->appendRow(Items); - ui->listChat->setModel(chat); + ui->listChat->setModel(chat); } diff --git a/src/Chat/Chat.h b/src/Chat/Chat.h index efe5b56..6d8b01a 100644 --- a/src/Chat/Chat.h +++ b/src/Chat/Chat.h @@ -27,21 +27,7 @@ class Chat // Chat Controller std::map requestZaddrMap; public: Chat(); - //QString zaddr(); void renderChatBox(Ui::MainWindow* ui, QListView *view, QLabel *label); // action - // void renderContactRequest(); - /*void triggerRequest(); - void showMessages(); - void clear(); - //void renderContactRequest(Ui::MainWindow* ui, QListView *view); - void addMessage(ChatItem item); - void addMessage(QString timestamp, ChatItem item); - void addCid(QString tx, QString cid); - void addrequestZaddr(QString tx, QString requestZaddr); - QString getCidByTx(QString tx); - QString getrequestZaddrByTx(QString tx); - void killCidCache(); - void killrequestZaddrCache();*/ }; diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index 6a30f56..722d2f6 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -179,7 +179,7 @@ QString ChatItem::toChatLine() qDebug()<<_notarize; - QString line = QString("") + myDateTime.toString("dd.MM.yyyy hh:mm"); + QString line = QString("") + myDateTime.toString("yyyy-MM-dd hh:mm"); line += QString(lock) + QString(""); line += QString("

") + _memo.toHtmlEscaped() + QString("

"); return line; From e65cc54e799bd1300b0d727e8f1b00929c167f44 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 5 Jun 2020 23:54:35 +0200 Subject: [PATCH 218/253] prevent to send message without contact #81 --- src/fundhushchat.ui | 72 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/fundhushchat.ui diff --git a/src/fundhushchat.ui b/src/fundhushchat.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/src/fundhushchat.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From ec3afa57ce5cc640296929153d375ad11e0530be Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Fri, 5 Jun 2020 23:55:31 +0200 Subject: [PATCH 219/253] prevent to send message without contact #81 --- src/chatmodel.cpp | 2 +- src/mainwindow.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index d88e95f..4bc12f5 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -540,7 +540,7 @@ void MainWindow::sendChat() { QString Name = ui->contactNameMemo->text(); int sizename = Name.size(); qDebug()<< sizename; - if ((sizename < 1) || (ui->memoTxtChat->toPlainText().trimmed().isEmpty())) { + if ((ui->contactNameMemo->text().isEmpty()) || (ui->memoTxtChat->toPlainText().trimmed().isEmpty())) { QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 73f2af4..c79dee4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1368,6 +1368,7 @@ void MainWindow::setupchatTab() { QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); ///////// Set selected Zaddr for Chat with Klick + ui->contactNameMemo->setText(""); QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { @@ -1401,6 +1402,7 @@ void MainWindow::setupchatTab() { ui->listContactWidget->addAction(HushAction); ui->listContactWidget->addAction(requestHushAction); ui->listContactWidget->addAction(subatomicAction); + QObject::connect(requestHushAction, &QAction::triggered, [=]() { QModelIndex index = ui->listContactWidget->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); @@ -1411,8 +1413,8 @@ void MainWindow::setupchatTab() { rpc->refresh(true); } - - MainWindow::showRequesthush(); + MainWindow::showRequesthush(); + }); QObject::connect(editAction, &QAction::triggered, [=]() { From 56fb612452b7e1ab55b1771263932f913558a64a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 00:05:51 +0200 Subject: [PATCH 220/253] disable sendbutton while loading --- src/chatmodel.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 4bc12f5..53203de 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -593,6 +593,7 @@ void MainWindow::sendChat() { }); movie->start(); ui->sendChatButton->show(); + ui->sendChatButton->setEnabled(false); } else { @@ -601,6 +602,7 @@ void MainWindow::sendChat() { }); movie1->start(); ui->sendChatButton->show(); + ui->sendChatButton->setEnabled(false); } ui->memoTxtChat->clear(); @@ -618,12 +620,14 @@ void MainWindow::sendChat() { QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); movie->stop(); + ui->sendChatButton->setEnabled(true); }else{ QPixmap send(":/icons/res/sendBlack.png"); QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); movie1->stop(); + ui->sendChatButton->setEnabled(true); } }); @@ -649,12 +653,14 @@ void MainWindow::sendChat() { QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); movie->stop(); + ui->sendChatButton->setEnabled(true); }else{ QPixmap send(":/icons/res/sendBlack.png"); QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); movie1->stop(); + ui->sendChatButton->setEnabled(true); } From 79ef0000069cf96a06a74ef52826a653492131a7 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 07:17:19 +0200 Subject: [PATCH 221/253] disbale drag and drop for chattab --- src/mainwindow.ui | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/mainwindow.ui b/src/mainwindow.ui index c6a5fc1..5426af5 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1636,8 +1636,17 @@ QAbstractItemView::NoEditTriggers + + false + + + QAbstractItemView::NoDragDrop + + + Qt::IgnoreAction + - QAbstractItemView::ContiguousSelection + QAbstractItemView::NoSelection QAbstractItemView::ScrollPerItem From 3254d99c6fef0a8b3521fe1060999cebdbeba1f2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 07:34:28 +0200 Subject: [PATCH 222/253] set max username size to 25 --- src/addressbook.ui | 2 +- src/contactrequest.ui | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/addressbook.ui b/src/addressbook.ui index dd0d06d..cd98ad9 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -40,7 +40,7 @@ - 40 + 25 diff --git a/src/contactrequest.ui b/src/contactrequest.ui index d46676f..43900d9 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -169,7 +169,11 @@
- + + + 25 + + From 38e404def5064426ce6465fef22416bc53b1ced8 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 07:34:39 +0200 Subject: [PATCH 223/253] set max username size to 25 --- src/requestContactDialog.ui | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index bc312dd..27e6650 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -180,7 +180,11 @@ - + + + 25 + + From 9b89ed5f2ed32cd420133a8cacb9e0899d598ae4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 07:43:00 +0200 Subject: [PATCH 224/253] delete checkbox for message encryption --- src/mainwindow.cpp | 2 -- src/mainwindow.ui | 16 ---------------- 2 files changed, 18 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c79dee4..cf6b039 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1360,8 +1360,6 @@ void MainWindow::setupchatTab() { ui->memoTxtChat->setTextColor("Black"); } - - ui->decryptionMessage->setChecked(true); QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChat); QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 5426af5..505be91 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1592,22 +1592,6 @@ - - - - - 0 - 0 - - - - Qt::LeftToRight - - - Message encryption/decryption ON - - -
From cdb1277b91a6c77ec79d3ca7dd1f76f6c0a5b5c0 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 11:26:49 +0200 Subject: [PATCH 225/253] dont show context menu without contact #94 --- src/Chat/Helper/ChatDelegator.h | 1 - src/Model/ChatItem.cpp | 1 - src/chatmodel.cpp | 14 ++------- src/controller.cpp | 29 +------------------ src/mainwindow.cpp | 51 +++++++++++++++------------------ 5 files changed, 26 insertions(+), 70 deletions(-) diff --git a/src/Chat/Helper/ChatDelegator.h b/src/Chat/Helper/ChatDelegator.h index 72f3c1e..e4474a8 100644 --- a/src/Chat/Helper/ChatDelegator.h +++ b/src/Chat/Helper/ChatDelegator.h @@ -56,7 +56,6 @@ inline void ListViewDelegate::paint(QPainter *painter, QStyleOptionViewItem cons qreal bodyheight = bodydoc.size().height(); int outgoing = index.data(Qt::UserRole + 1).toInt(); int outdate = index.data(Qt::UserRole + 1).toInt(); - int indate = index.data(Qt::UserRole + 1).toInt(); painter->save(); painter->setRenderHint(QPainter::Antialiasing); diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index 722d2f6..9d8ede4 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -178,7 +178,6 @@ QString ChatItem::toChatLine() } -qDebug()<<_notarize; QString line = QString("") + myDateTime.toString("yyyy-MM-dd hh:mm"); line += QString(lock) + QString(""); line += QString("

") + _memo.toHtmlEscaped() + QString("

"); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 53203de..32ecb78 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -237,7 +237,7 @@ void MainWindow::renderContactRequest(){ return; } - qDebug()<<"Beginn kopiert" <addAddressLabel(newLabel, addr, myAddr, cid, avatar); rpc->refreshContacts( ui->listContactWidget); @@ -393,7 +393,6 @@ QString MainWindow::createHeaderMemo(QString type, QString cid, QString zaddr, Q j.setObject(h); header = j.toJson(); - qDebug() << "made header=" << header; return header; } @@ -449,7 +448,6 @@ Tx MainWindow::createTxFromChatPage() { QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); - qDebug()<<"Pubkey Erstellung :"<(header), crypto_secretstream_xchacha20poly1305_HEADERBYTES).toHex(); QString publickeyAlice = QByteArray(reinterpret_cast(pk), crypto_kx_PUBLICKEYBYTES).toHex(); - qDebug()<<"Headerbyte erstellung : "<contactNameMemo->text(); - int sizename = Name.size(); - qDebug()<< sizename; + if ((ui->contactNameMemo->text().isEmpty()) || (ui->memoTxtChat->toPlainText().trimmed().isEmpty())) { QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), @@ -577,7 +569,6 @@ void MainWindow::sendChat() { // abort the Tx return; - qDebug() << "Tx aborted"; } auto movie = new QMovie(this); @@ -716,7 +707,6 @@ void::MainWindow::addContact() request.myzaddr->setText(myAddr); ui->listReceiveAddresses->insertItem(0, myAddr); ui->listReceiveAddresses->setCurrentIndex(0); - qDebug() << "new generated myAddr add Contact" << myAddr; }); }catch(...) diff --git a/src/controller.cpp b/src/controller.cpp index f47ca17..5b1c979 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1025,7 +1025,6 @@ void Controller::refreshTransactions() { int encryptedMemoSize1 = ba.length(); - int headersize = ba1.length(); //////unsigned char* as message from QString #define MESSAGE2 (const unsigned char *) encryptedMemo @@ -1062,8 +1061,6 @@ void Controller::refreshTransactions() { //////////////Give us the output of the decrypted message as debug to see if it was successfully - qDebug()<<"OUT decrypt:" << memodecrypt; - ChatItem item = ChatItem( datetime, @@ -1084,26 +1081,7 @@ void Controller::refreshTransactions() { updateUIBalances(); } - /*else{ - - - ChatItem item = ChatItem( - datetime, - address, - QString(""), - memo, - QString(""), - QString(""), - cid, - txid, - confirmations, - true, - isNotarized, - false - ); - DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - updateUIBalances(); - }*/ + } items.push_back(TransactionItemDetail{address, amount, memo}); @@ -1153,7 +1131,6 @@ void Controller::refreshTransactions() { QString publickey; QString headerbytes; QString cid; - int position; QString requestZaddr; bool isContact; @@ -1261,10 +1238,6 @@ void Controller::refreshTransactions() { chatModel->addMemo(txid, headerbytes); }else{} - - qDebug()<<"Position message :"<getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cf6b039..6e9af7e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -292,7 +292,6 @@ void MainWindow::closeEvent(QCloseEvent* event) { // Let the RPC know to shut down any running service. rpc->shutdownhushd(); int passphraselenght = this->getPassword().length(); - qDebug()<<"LÄNGE PW : "< 0) @@ -542,9 +541,7 @@ void MainWindow::removeWalletEncryption() { filencrypted.remove(); }else{ - - qDebug()<<"verschlüsselung gescheitert "; - + QMessageBox::critical(this, tr("Wallet Encryption Failed"), QString("False password, please try again"), QMessageBox::Ok @@ -632,8 +629,6 @@ void MainWindow::removeWalletEncryptionStartUp() { }else{ - - qDebug()<<"verschlüsselung gescheitert "; QMessageBox::critical(this, tr("Wallet Encryption Failed"), QString("false password please try again"), @@ -1365,24 +1360,10 @@ void MainWindow::setupchatTab() { QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::addContact); QObject::connect(ui->pushContact, &QPushButton::clicked, this , &MainWindow::renderContactRequest); -///////// Set selected Zaddr for Chat with Klick ui->contactNameMemo->setText(""); - QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { - - - QModelIndex index = ui->listContactWidget->currentIndex(); - QString label_contact = index.data(Qt::DisplayRole).toString(); - - for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) - if (label_contact == p.getName()) { - ui->contactNameMemo->setText(p.getName()); - rpc->refresh(true); - - } - }); - - QMenu* contextMenu; +///////// Add contextmenu + QMenu* contextMenu; QAction* requestAction; QAction* editAction; QAction* HushAction; @@ -1394,16 +1375,22 @@ void MainWindow::setupchatTab() { HushAction = new QAction("Send a friend some Hush - coming soon",contextMenu); requestHushAction = new QAction("Request some Hush - coming soon",contextMenu); subatomicAction = new QAction("Make a subatomic swap with a friend- coming soon",contextMenu); + + +///////// Set selected Zaddr for Chat with click + + QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { + ui->listContactWidget->setContextMenuPolicy(Qt::ActionsContextMenu); ui->listContactWidget->addAction(requestAction); ui->listContactWidget->addAction(editAction); ui->listContactWidget->addAction(HushAction); ui->listContactWidget->addAction(requestHushAction); ui->listContactWidget->addAction(subatomicAction); - - QObject::connect(requestHushAction, &QAction::triggered, [=]() { + + QObject::connect(requestHushAction, &QAction::triggered, [=]() { QModelIndex index = ui->listContactWidget->currentIndex(); - QString label_contact = index.data(Qt::DisplayRole).toString(); + QString label_contact = index.data(Qt::DisplayRole).toString(); for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) if (label_contact == p.getName()) { @@ -1415,7 +1402,7 @@ void MainWindow::setupchatTab() { }); - QObject::connect(editAction, &QAction::triggered, [=]() { + QObject::connect(editAction, &QAction::triggered, [=]() { QModelIndex index = ui->listContactWidget->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); @@ -1436,12 +1423,20 @@ void MainWindow::setupchatTab() { } }); + QModelIndex index = ui->listContactWidget->currentIndex(); + QString label_contact = index.data(Qt::DisplayRole).toString(); + + for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + if (label_contact == p.getName()) { + ui->contactNameMemo->setText(p.getName()); + rpc->refresh(true); + } + }); + ui->memoTxtChat->setLenDisplayLabelChat(ui->memoSizeChat); } - - void MainWindow::updateChat() { rpc->refreshChat(ui->listChat,ui->memoSizeChat); From cae2c12b56b01c12f34e4120e943e3b222f56a00 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 17:12:40 +0200 Subject: [PATCH 226/253] add contextmenu for chatitems #78 --- src/chatmodel.cpp | 19 +++++--- src/mainwindow.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++ src/mainwindow.ui | 9 ++++ 3 files changed, 135 insertions(+), 6 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 32ecb78..6622416 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -115,9 +115,11 @@ void MainWindow::renderContactRequest(){ QStandardItemModel* contactRequest = new QStandardItemModel(); + + for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) - + { @@ -134,6 +136,7 @@ void MainWindow::renderContactRequest(){ } + QStandardItemModel* contactRequestOld = new QStandardItemModel(); for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) @@ -157,13 +160,16 @@ void MainWindow::renderContactRequest(){ QModelIndex index = requestContact.requestContact->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); + + + if ((c.second.isOutgoing() == false) && (requestContact.zaddrnew->text() == c.second.getAddress()) && (c.second.getType() != "Cont")) { QStandardItem* Items = new QStandardItem(c.second.getMemo()); - contactMemo->appendRow(Items); + contactMemo->appendRow(Items); requestContact.requestMemo->setModel(contactMemo); requestContact.requestMemo->show(); @@ -172,17 +178,18 @@ void MainWindow::renderContactRequest(){ requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); }else{} - } - + } }); + + QObject::connect(requestContact.requestContactOld, &QTableView::clicked, [&] () { for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ - /* QModelIndex index = requestContact.requestContactOld->currentIndex(); - QString label_contactold = index.data(Qt::DisplayRole).toString();*/ + QModelIndex index = requestContact.requestContactOld->currentIndex(); + QString label_contactold = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); if ((c.second.isOutgoing() == false) && (requestContact.zaddrold->text() == c.second.getAddress()) && (c.second.getType() != "Cont")) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6e9af7e..4e9a126 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -30,6 +30,7 @@ #include "FileSystem/FileSystem.h" #include "Crypto/passwd.h" #include "Crypto/FileEncryption.h" +#include "DataStore/DataStore.h" using json = nlohmann::json; @@ -1362,6 +1363,118 @@ void MainWindow::setupchatTab() { ui->contactNameMemo->setText(""); + /////Copy Chatmessages + + QMenu* contextMenuChat; + QAction* copymessage; + QAction* viewexplorer; + QAction* copytxid; + contextMenuChat = new QMenu(ui->listChat); + copymessage = new QAction("Copy message to clipboard",contextMenuChat); + viewexplorer = new QAction("View on block explorerr",contextMenuChat); + copytxid = new QAction("Copy txid to clipboard ",contextMenuChat); + + QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { + + ui->listChat->setContextMenuPolicy(Qt::ActionsContextMenu); + ui->listChat->addAction(copymessage); + ui->listChat->addAction(viewexplorer); + ui->listChat->addAction(copytxid); + + QObject::connect(copymessage, &QAction::triggered, [=] { + + + QModelIndex index = ui->listChat->currentIndex(); + QString memo_chat = index.data(Qt::DisplayRole).toString(); + QClipboard *clipboard = QGuiApplication::clipboard(); + int startPos = memo_chat.indexOf("

") + 3; + int endPos = memo_chat.indexOf("

"); + int length = endPos - startPos; + QString copymemo = memo_chat.mid(startPos, length); + + clipboard->setText(copymemo); + ui->statusBar->showMessage(tr("Copied message to clipboard"), 3 * 1000); + +}); + QObject::connect(copytxid, &QAction::triggered, [=] { + + QModelIndex index = ui->listChat->currentIndex(); + QString memo_chat = index.data(Qt::DisplayRole).toString(); + QClipboard *clipboard = QGuiApplication::clipboard(); + + int startPos = memo_chat.indexOf("

") + 3; + int endPos = memo_chat.indexOf("

"); + int length = endPos - startPos; + QString copymemo = memo_chat.mid(startPos, length); + int startPosT = memo_chat.indexOf("") + 7; + int endPosT = memo_chat.indexOf(""); + int lengthT = endPosT - startPosT; + + QString time = memo_chat.mid(startPosT, lengthT); + + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ + + if (c.second.getMemo() == copymemo) + { + int timestamp = c.second.getTimestamp(); + QDateTime myDateTime; + QString lock; + myDateTime.setTime_t(timestamp); + QString timestamphtml = myDateTime.toString("yyyy-MM-dd hh:mm"); + + if(timestamphtml == time) + + { + clipboard->setText(c.second.getTxid()); + ui->statusBar->showMessage(tr("Copied Txid to clipboard"), 3 * 1000); + }else{} + + } + +} + +}); + + QObject::connect(viewexplorer, &QAction::triggered, [=] { + + QModelIndex index = ui->listChat->currentIndex(); + QString memo_chat = index.data(Qt::DisplayRole).toString(); + + int startPos = memo_chat.indexOf("

") + 3; + int endPos = memo_chat.indexOf("

"); + int length = endPos - startPos; + QString copymemo = memo_chat.mid(startPos, length); + int startPosT = memo_chat.indexOf("") + 7; + int endPosT = memo_chat.indexOf(""); + int lengthT = endPosT - startPosT; + + QString time = memo_chat.mid(startPosT, lengthT); + + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ + + if (c.second.getMemo() == copymemo) + { + int timestamp = c.second.getTimestamp(); + QDateTime myDateTime; + QString lock; + myDateTime.setTime_t(timestamp); + QString timestamphtml = myDateTime.toString("yyyy-MM-dd hh:mm"); + + if(timestamphtml == time) + + { + + Settings::openTxInExplorer(c.second.getTxid()); + + }else{} + + } + +} +}); + +}); + ///////// Add contextmenu QMenu* contextMenu; QAction* requestAction; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 505be91..2fa544c 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -1602,6 +1602,9 @@ 0 + + Qt::NoFocus + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized @@ -1638,9 +1641,15 @@ QListView::Snap + + QListView::TopToBottom + QListView::Adjust + + QListView::SinglePass + 0 From cfe8955b44faa3f3adf2a4faa72558bd3054310c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 20:54:44 +0200 Subject: [PATCH 227/253] fix typo --- src/mainwindow.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4e9a126..0e7f00a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -363,11 +363,9 @@ void MainWindow::closeEvent(QCloseEvent* event) { void MainWindow::closeEventpw(QCloseEvent* event) { // Let the RPC know to shut down any running service. - rpc->shutdownhushd(); + rpc->shutdownhushdStartup(); + - // Bubble up - if (event) - QMainWindow::closeEvent(event); } @@ -1371,7 +1369,7 @@ void MainWindow::setupchatTab() { QAction* copytxid; contextMenuChat = new QMenu(ui->listChat); copymessage = new QAction("Copy message to clipboard",contextMenuChat); - viewexplorer = new QAction("View on block explorerr",contextMenuChat); + viewexplorer = new QAction("View on block explorer",contextMenuChat); copytxid = new QAction("Copy txid to clipboard ",contextMenuChat); QObject::connect(ui->listContactWidget, &QTableView::clicked, [=] () { From d4e51fd19a2922df6cd997d4366a0b1c16b4fdd3 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 6 Jun 2020 20:56:49 +0200 Subject: [PATCH 228/253] fix typo --- src/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0e7f00a..497503d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -363,7 +363,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { void MainWindow::closeEventpw(QCloseEvent* event) { // Let the RPC know to shut down any running service. - rpc->shutdownhushdStartup(); + rpc->shutdownhushd(); } From 852207199f58463869b306d1ff2ba9cd69ea87b4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 7 Jun 2020 21:19:41 +0200 Subject: [PATCH 229/253] fix for incoming requests --- src/DataStore/ChatDataStore.cpp | 9 ++++-- src/Model/ChatItem.cpp | 2 +- src/addressbook.cpp | 6 +++- src/addressbook.h | 2 -- src/chatmodel.cpp | 39 +++++++++++++------------ src/contactmodel.cpp | 44 +++++++++++++++++++--------- src/contactmodel.h | 6 ++++ src/controller.cpp | 52 ++++++++++++++------------------- src/mainwindow.cpp | 13 +++++---- src/mainwindow.h | 1 + 10 files changed, 99 insertions(+), 75 deletions(-) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index dfa7d54..5563fab 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -60,7 +60,9 @@ std::map ChatDataStore::getAllNewContactRequests() if ( (c.second.isOutgoing() == false) && (c.second.getType() == "Cont") && - (c.second.isContact() == false) + (c.second.isContact() == false) && + (c.second.getMemo().startsWith("{")) + ) { @@ -73,13 +75,14 @@ std::map ChatDataStore::getAllNewContactRequests() std::map ChatDataStore::getAllOldContactRequests() { std::map filteredItems; - for(auto &p : AddressBook::getInstance()->getAllAddressLabels()) + for(auto &c: this->data) { if ( (c.second.isOutgoing() == false) && (c.second.getType() == "Cont") && - (p.getPartnerAddress() == c.second.getRequestZaddr()) + (c.second.isContact() == true) && + (c.second.getMemo().startsWith("{")) ) { filteredItems[c.first] = c.second; diff --git a/src/Model/ChatItem.cpp b/src/Model/ChatItem.cpp index 9d8ede4..66b5176 100644 --- a/src/Model/ChatItem.cpp +++ b/src/Model/ChatItem.cpp @@ -180,7 +180,7 @@ QString ChatItem::toChatLine() QString line = QString("") + myDateTime.toString("yyyy-MM-dd hh:mm"); line += QString(lock) + QString(""); - line += QString("

") + _memo.toHtmlEscaped() + QString("

"); + line +=QString("

") + _memo.toHtmlEscaped() + QString("

"); return line; } diff --git a/src/addressbook.cpp b/src/addressbook.cpp index ae81ae2..68ead74 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -41,7 +41,7 @@ void AddressBookModel::loadData() "addresstablegeometry" ).toByteArray() ); - + } void AddressBookModel::addNewLabel(QString label, QString addr, QString myAddr, QString cid, QString avatar) @@ -108,7 +108,9 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const case 2: return labels.at(index.row()).getPartnerAddress(); case 3: return labels.at(index.row()).getMyAddress(); case 4: return labels.at(index.row()).getCid(); + } + } return QVariant(); @@ -405,8 +407,10 @@ void AddressBook::readFromStorage() //qDebug() << "2:" << stuff[i][2]; ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); //qDebug() << "contact=" << contact.toQTString(); + // main->addLabel(stuff[i][2], stuff[i][1]); allLabels.push_back(contact); } + // qDebug() << "Read " << version << " Hush contacts from disk..."; file.close(); diff --git a/src/addressbook.h b/src/addressbook.h index fbd361b..b4fe7a8 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -24,8 +24,6 @@ public: QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; - - private: void loadData(); void saveData(); diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 6622416..694908c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -119,44 +119,41 @@ void MainWindow::renderContactRequest(){ for (auto &c : DataStore::getChatDataStore()->getAllNewContactRequests()) - - { - QStandardItem* Items = new QStandardItem(QString("Unknown Sender")); + QStandardItem* Items = new QStandardItem(QString(c.second.getRequestZaddr())); contactRequest->appendRow(Items); - requestContact.requestContact->setModel(contactRequest); - + requestContact.requestContact->setModel(contactRequest); Items->setData(QIcon(addnewAddrIcon),Qt::DecorationRole); requestContact.requestContact->setIconSize(QSize(40,50)); requestContact.requestContact->setUniformItemSizes(true); requestContact.requestContact->show(); requestContact.zaddrnew->setVisible(false); - requestContact.zaddrnew->setText(c.second.getAddress()); + requestContact.zaddrnew->setText(c.second.getRequestZaddr()); + + } QStandardItemModel* contactRequestOld = new QStandardItemModel(); - for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) for (auto &c : DataStore::getChatDataStore()->getAllOldContactRequests()) { - if (p.getPartnerAddress() == c.second.getRequestZaddr()) - { - QStandardItem* Items = new QStandardItem(p.getName()); + QStandardItem* Items = new QStandardItem(c.second.getContact()); contactRequestOld->appendRow(Items); requestContact.requestContactOld->setModel(contactRequestOld); requestContact.zaddrold->setVisible(false); - requestContact.zaddrold->setText(c.second.getAddress()); - requestContact.requestContactOld->show(); - }else{} + requestContact.zaddrold->setText(c.second.getRequestZaddr()); + + } + QObject::connect(requestContact.requestContact, &QTableView::clicked, [&] () { - for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ + for (auto &c : DataStore::getChatDataStore()->getAllRawChatItems()){ QModelIndex index = requestContact.requestContact->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); @@ -164,7 +161,7 @@ void MainWindow::renderContactRequest(){ - if ((c.second.isOutgoing() == false) && (requestContact.zaddrnew->text() == c.second.getAddress()) && (c.second.getType() != "Cont")) + if ((c.second.isOutgoing() == false) && (label_contact == c.second.getContact())) { @@ -177,7 +174,10 @@ void MainWindow::renderContactRequest(){ requestContact.requestCID->setVisible(false); requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); - }else{} + + }else{ + + } } @@ -192,7 +192,7 @@ void MainWindow::renderContactRequest(){ QString label_contactold = index.data(Qt::DisplayRole).toString(); QStandardItemModel* contactMemo = new QStandardItemModel(); - if ((c.second.isOutgoing() == false) && (requestContact.zaddrold->text() == c.second.getAddress()) && (c.second.getType() != "Cont")) + if ((c.second.isOutgoing() == false) && (label_contactold == c.second.getContact())) { @@ -205,7 +205,10 @@ void MainWindow::renderContactRequest(){ requestContact.requestCID->setVisible(false); requestContact.requestZaddr->setText(c.second.getRequestZaddr()); requestContact.requestMyAddr->setText(c.second.getAddress()); - }else{} + + }else{ + + } } diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 7f9d097..f3d529f 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -11,7 +11,25 @@ #include "settings.h" #include "controller.h" +void ContactModel::addLabel(QString addr, QString label) +{ + this->AddressMap[addr] = label; +} +QString ContactModel::getContactbyAddress(QString addr) +{ + for(auto& pair : this->AddressMap) + { + + } + + if(this->AddressMap.count(addr) > 0) + { + return this->AddressMap[addr]; + } + + return QString("0xdeadbeef"); +} void ContactModel::renderContactList(QListView* view) { @@ -19,22 +37,20 @@ void ContactModel::renderContactList(QListView* view) for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) { + QString avatar = c.getAvatar(); - - QString avatar = c.getAvatar(); - - QStandardItem* Items1 = new QStandardItem(c.getName()); - Items1->setData(QIcon(avatar),Qt::DecorationRole); + QStandardItem* Items1 = new QStandardItem(c.getName()); + Items1->setData(QIcon(avatar),Qt::DecorationRole); - contact->appendRow(Items1); - view->setModel(contact); - view->setIconSize(QSize(60,70)); - view->setUniformItemSizes(true); - view->setDragDropMode(QAbstractItemView::DropOnly); - view->show(); - - - + contact->appendRow(Items1); + view->setModel(contact); + view->setIconSize(QSize(60,70)); + view->setUniformItemSizes(true); + view->setDragDropMode(QAbstractItemView::DropOnly); + view->show(); + QString addr = c.getPartnerAddress(); + QString label = c.getName(); + this->addLabel(addr, label); } } diff --git a/src/contactmodel.h b/src/contactmodel.h index 5f79c47..584b5f9 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -12,9 +12,15 @@ class ContactModel { public: + MainWindow* main; + std::map AddressMap; + + QString getContactbyAddress(QString addr); + void addLabel(QString addr, QString label); ContactModel() {} void renderContactList(QListView* view); + }; diff --git a/src/controller.cpp b/src/controller.cpp index 5b1c979..fa4ef9a 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1132,28 +1132,8 @@ void Controller::refreshTransactions() { QString headerbytes; QString cid; QString requestZaddr; + QString contactname; bool isContact; - - - for (auto &p : AddressBook::getInstance()->getAllAddressLabels()) - { - - if (p.getPartnerAddress() == requestZaddr) - { - - chatModel->addAddressbylabel(address, requestZaddr); - } else{} - - } - if (chatModel->Addressbylabel(address) != QString("0xdeadbeef")){ - - isContact = true; - - }else{ - - isContact = false; - - } if (!it["memo"].is_null()) { @@ -1176,8 +1156,7 @@ void Controller::refreshTransactions() { } } - - + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ cid = chatModel->getCidByTx(txid); @@ -1212,7 +1191,20 @@ void Controller::refreshTransactions() { publickey = ""; } - + if (contactModel->getContactbyAddress(requestZaddr) != QString("0xdeadbeef")){ + + isContact = true; + contactname = contactModel->getContactbyAddress(requestZaddr); + + }else{ + + isContact = false; + contactname = ""; + + } + + + qDebug()<<"Name :" << contactname; bool isNotarized; @@ -1336,7 +1328,7 @@ void Controller::refreshTransactions() { ChatItem item = ChatItem( datetime, address, - QString(""), + contactname, memodecrypt, requestZaddr, type, @@ -1347,9 +1339,7 @@ void Controller::refreshTransactions() { isNotarized, isContact ); - DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - - + DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); }else{ @@ -1360,7 +1350,7 @@ void Controller::refreshTransactions() { ChatItem item = ChatItem( datetime, address, - QString(""), + contactname, memo, requestZaddr, type, @@ -1372,7 +1362,9 @@ void Controller::refreshTransactions() { isContact ); DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - + qDebug()<<"requestZaddrt? :"<listChat->currentIndex(); QString memo_chat = index.data(Qt::DisplayRole).toString(); QClipboard *clipboard = QGuiApplication::clipboard(); - int startPos = memo_chat.indexOf("

") + 3; - int endPos = memo_chat.indexOf("

"); + int startPos = memo_chat.indexOf("
") + 3;
+    int endPos = memo_chat.indexOf("
"); int length = endPos - startPos; QString copymemo = memo_chat.mid(startPos, length); @@ -1400,8 +1401,8 @@ void MainWindow::setupchatTab() { QString memo_chat = index.data(Qt::DisplayRole).toString(); QClipboard *clipboard = QGuiApplication::clipboard(); - int startPos = memo_chat.indexOf("

") + 3; - int endPos = memo_chat.indexOf("

"); + int startPos = memo_chat.indexOf("
") + 3;
+    int endPos = memo_chat.indexOf("
"); int length = endPos - startPos; QString copymemo = memo_chat.mid(startPos, length); int startPosT = memo_chat.indexOf("") + 7; @@ -1438,8 +1439,8 @@ void MainWindow::setupchatTab() { QModelIndex index = ui->listChat->currentIndex(); QString memo_chat = index.data(Qt::DisplayRole).toString(); - int startPos = memo_chat.indexOf("

") + 3; - int endPos = memo_chat.indexOf("

"); + int startPos = memo_chat.indexOf("
") + 3;
+    int endPos = memo_chat.indexOf("
"); int length = endPos - startPos; QString copymemo = memo_chat.mid(startPos, length); int startPosT = memo_chat.indexOf("") + 7; diff --git a/src/mainwindow.h b/src/mainwindow.h index bb56d5b..53032df 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -58,6 +58,7 @@ public: void setPassword(QString Password); void addPubkey(QString requestZaddr, QString pubkey); + void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); From d9f51aa8334086c95869fd7394e79b5300ae6ab2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 7 Jun 2020 21:29:15 +0200 Subject: [PATCH 230/253] fix wrong gif at exit #100 --- src/controller.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/controller.cpp b/src/controller.cpp index fa4ef9a..a8ea783 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1966,9 +1966,27 @@ void Controller::shutdownhushd() QDialog d(main); Ui_ConnectionDialog connD; connD.setupUi(&d); - connD.topIcon->setPixmap(QIcon(":/icons/res/icon.ico").pixmap(256, 256)); + auto theme = Settings::getInstance()->get_theme_name(); + auto size = QSize(512,512); + + if (theme == "dark" || theme == "midnight") { + QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-startup-dark.gif");; + movie2->setScaledSize(size); + qDebug() << "Animation dark loaded"; + connD.topIcon->setMovie(movie2); + movie2->start(); connD.status->setText(QObject::tr("Please wait for SilentDragonLite to exit")); connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit")); + } else { + QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated-startup.gif");; + movie1->setScaledSize(size); + qDebug() << "Animation light loaded"; + connD.topIcon->setMovie(movie1); + movie1->start(); + connD.status->setText(QObject::tr("Please wait for SilentDragonLite to exit")); + connD.statusDetail->setText(QObject::tr("Waiting for hushd to exit")); + } + bool finished = false; zrpc->saveWallet([&] (json) { if (!finished) From 1bc63f41f6bddfb0e5a7b8e5fd481fc89747f01d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 7 Jun 2020 21:55:39 +0200 Subject: [PATCH 231/253] add button to create a new zaddr --- src/addressbook.cpp | 18 ++- src/addressbook.ui | 115 +++++++++--------- src/chatmodel.cpp | 14 ++- src/contactrequest.ui | 275 ++++++++++++++++++++++-------------------- src/controller.cpp | 9 +- 5 files changed, 222 insertions(+), 209 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 68ead74..11dc0c4 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -147,8 +147,9 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) // Connect the dialog's closing to updating the label address completor QObject::connect(&d, &QDialog::finished, [=] (auto) { parent->updateLabels(); }); + Controller* rpc = parent->getRPC(); + QObject::connect(ab.newZaddr, &QPushButton::clicked, [&] () { - Controller* rpc = parent->getRPC(); bool sapling = true; try { @@ -174,6 +175,7 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) qDebug() << QString("Caught something nasty with myZaddr Addressbook"); } + }); // model.updateUi(); //todo fix updating gui after adding @@ -193,7 +195,6 @@ void AddressBook::open(MainWindow* parent, QLineEdit* target) QString avatar = QString(":/icons/res/") + ab.comboBoxAvatar->currentText() + QString(".png"); - qDebug()<<"AVATAR NAME : " << avatar; if (addr.isEmpty() || newLabel.isEmpty()) { @@ -394,20 +395,15 @@ void AddressBook::readFromStorage() QDataStream in(&file); // read the data serialized from the file QString version; in >> version; - // qDebug() << "Detected old addressbook format"; - // Convert old addressbook format v1 to v2 - QList> stuff; + QList> stuff; in >> stuff; - //qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) { - //qDebug() << "0:" << stuff[i][0]; - //qDebug() << "1:" << stuff[i][1]; - //qDebug() << "2:" << stuff[i][2]; + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); - //qDebug() << "contact=" << contact.toQTString(); - // main->addLabel(stuff[i][2], stuff[i][1]); + allLabels.push_back(contact); } diff --git a/src/addressbook.ui b/src/addressbook.ui index cd98ad9..08b2356 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -14,6 +14,43 @@ Address Book + + + + + + Import Address Book + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Ok + + + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + false + + + @@ -51,17 +88,27 @@ - - - - <html><head/><body><p align="right">Avatar :</p></body></html> - - - - + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + + + + + + Add to Address Book + + + + @@ -195,63 +242,23 @@ - - + + - <html><head/><body><p>Conversation ID (editable):</p></body></html> + <html><head/><body><p align="right">Avatar :</p></body></html> - - - - - + + - Add to Address Book + Create a new HushChat zaddr
- - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - true - - - false - - - - - - - - - Import Address Book - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Close|QDialogButtonBox::Ok - - - - - diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 694908c..7fda03a 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -708,6 +708,7 @@ void::MainWindow::addContact() request.setupUi(&dialog); Settings::saveRestore(&dialog); +QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () { try { bool sapling = true; @@ -725,6 +726,7 @@ void::MainWindow::addContact() qDebug() << QString("Caught something nasty with myZaddr Contact"); } +}); QString cid = QUuid::createUuid().toString(QUuid::WithoutBraces); @@ -823,8 +825,6 @@ void MainWindow::ContactRequest() { if (contactRequest.getReceiverAddress().isEmpty() || contactRequest.getMemo().isEmpty()) { - // auto addr = ""; - // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), QMessageBox::Ok, this); @@ -833,6 +833,16 @@ void MainWindow::ContactRequest() { return; } + if (contactRequest.getSenderAddress().size() > 80) { + + QMessageBox msg(QMessageBox::Critical, tr("Missing HushChat Address"), + tr("You have to create your HushChat address to send a contact request,\n"), + QMessageBox::Ok, this); + + msg.exec(); + return; + } + int max = 235; QString chattext = contactRequest.getMemo();; int size = chattext.size(); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 43900d9..eb231ee 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -34,140 +34,6 @@
- - - - - SDLogo - - - - :/icons/res/SDLogo.png - - - - - - Duke - - - - :/icons/res/Duke.png - - - - - - Denio - - - - :/icons/res/Denio.png - - - - - - Berg - - - - :/icons/res/Berg.png - - - - - - Stag - - - - :/icons/res/Stag.png - - - - - - Sharpee - - - - :/icons/res/Sharpee.png - - - - - - Elsa - - - - :/icons/res/Elsa.png - - - - - - Yoda - - - - :/icons/res/Yoda.png - - - - - - Garfield - - - - :/icons/res/Garfield.png - - - - - - Snoopy - - - - :/icons/res/Snoopy.png - - - - - - Popey - - - - :/icons/res/Popey.png - - - - - - Pinguin - - - - :/icons/res/Pinguin.png - - - - - - Mickey - - - - :/icons/res/Mickey.png - - - - - @@ -329,6 +195,147 @@ + + + + + SDLogo + + + + :/icons/res/SDLogo.png + + + + + + Duke + + + + :/icons/res/Duke.png + + + + + + Denio + + + + :/icons/res/Denio.png + + + + + + Berg + + + + :/icons/res/Berg.png + + + + + + Stag + + + + :/icons/res/Stag.png + + + + + + Sharpee + + + + :/icons/res/Sharpee.png + + + + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + + + + Garfield + + + + :/icons/res/Garfield.png + + + + + + Snoopy + + + + :/icons/res/Snoopy.png + + + + + + Popey + + + + :/icons/res/Popey.png + + + + + + Pinguin + + + + :/icons/res/Pinguin.png + + + + + + Mickey + + + + :/icons/res/Mickey.png + + + + + + + + + Create new Hushchat address + + + diff --git a/src/controller.cpp b/src/controller.cpp index a8ea783..495ee7d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1202,9 +1202,6 @@ void Controller::refreshTransactions() { contactname = ""; } - - - qDebug()<<"Name :" << contactname; bool isNotarized; @@ -1361,11 +1358,7 @@ void Controller::refreshTransactions() { isNotarized, isContact ); - DataStore::getChatDataStore()->setData(ChatIDGenerator::getInstance()->generateID(item), item); - qDebug()<<"requestZaddrt? :"<setData(ChatIDGenerator::getInstance()->generateID(item), item); } } } From 3dc04ed47fa0bf1d02bf9d8e9314ca4225ad757e Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Mon, 8 Jun 2020 00:31:56 -0400 Subject: [PATCH 232/253] display bug issue #92, plus typos and alignment of dropdown logo and titles --- src/requestContactDialog.ui | 274 ++++++++++++++++++++++-------------- 1 file changed, 167 insertions(+), 107 deletions(-) diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 27e6650..237f206 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -10,9 +10,15 @@ 495 + + + 0 + 0 + + - 812 + 850 495 @@ -20,39 +26,10 @@ Incoming contact request - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> - - - - + - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> - - - - - - - - 256 - 231 - - - - true - - - QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - false - - - QAbstractItemView::SingleSelection + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> @@ -60,7 +37,7 @@ - 521 + 500 231 @@ -90,18 +67,24 @@ - - + + - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + 0 + 0 + + - 256 + 225 190 @@ -119,20 +102,6 @@ - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> - - - - - - - Request from : - - - @@ -149,51 +118,121 @@ - - + + + + + 0 + 0 + + - My Zaddr : - - - - - - - - 351 - 25 - - - - - 351 - 25 - - - - - - - - Give a Nickname: + Request from: + + + 0 + 0 + + + + + 0 + 25 + + 25 - - + + - <html><head/><body><p align="right">Choose a avatar for your contact :</p></body></html> + - + + + + Add New Contact + + + false + + + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + + + + 0 + 0 + + + + My Zaddr: + + + + + + + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Cancel + + + false + + + false + + + + @@ -339,53 +378,74 @@ - - - + + + - 100 - 0 + 225 + 231 - - Cancel + + true - + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + false - - false + + QAbstractItemView::SingleSelection - - + + - Add this new Contact - - - false + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> - - + + + + + 0 + 0 + + - + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> - - + + + + + 0 + 0 + + - + Give a Nickname: - - - - + + + + + 351 + 25 + + + + + 351 + 25 + From 7aa03560fb7bedfb129dd613dab42a2b96da5c05 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Mon, 8 Jun 2020 01:39:17 -0400 Subject: [PATCH 233/253] Updated layout issues with contactrequest.ui, typography, and button alignments, including inputbox fixes for midnight theme --- src/contactrequest.ui | 633 +++++++++++++++++++++++++----------------- 1 file changed, 375 insertions(+), 258 deletions(-) diff --git a/src/contactrequest.ui b/src/contactrequest.ui index eb231ee..286dbdb 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -10,6 +10,12 @@ 427 + + + 0 + 0 + + 780 @@ -20,97 +26,7 @@ Send a contact request - - - - <html><head/><body><p align="right"><span style=" font-weight:600; text-decoration: underline;">Choose a avatar for your contact :</span></p></body></html> - - - - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Please insert a Nickname for your contact :</span></p></body></html> - - - - - - - 25 - - - - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Please insert the Address of your contact :</span></p></body></html> - - - - - - - - 650 - 25 - - - - - 650 - 25 - - - - - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address :</span></p></body></html> - - - - - - - - 650 - 25 - - - - - 650 - 25 - - - - <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> - - - - - - - Qt::Vertical - - - - 20 - 148 - - - - - - - - <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request</span></p></body></html> - - - - + @@ -118,12 +34,6 @@ 71 - - - 500 - 71 - - Qt::NoContextMenu @@ -143,15 +53,69 @@ false - Add some memo to your request + Add a memo to your request true - + + + + + 650 + 25 + + + + + 650 + 25 + + + + + + + + Add Contact and Send Request + + + false + + + false + + + + + + + + 650 + 25 + + + + + 650 + 25 + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + + + 0 + 0 + + 100 @@ -169,173 +133,326 @@ - - - - Qt::Horizontal - - - - 278 - 20 - - - - - - + + - Add Contact and send request - - - false - - - false + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> - - - - - SDLogo - - - - :/icons/res/SDLogo.png - - - - - - Duke - - - - :/icons/res/Duke.png - - - - - - Denio - - - - :/icons/res/Denio.png - - - - - - Berg - - - - :/icons/res/Berg.png - - - - - - Stag - - - - :/icons/res/Stag.png - - - - - - Sharpee - - - - :/icons/res/Sharpee.png - - - - - - Elsa - - - - :/icons/res/Elsa.png - - - - - - Yoda - - - - :/icons/res/Yoda.png - - - - - - Garfield - - - - :/icons/res/Garfield.png - - - - - - Snoopy - - - - :/icons/res/Snoopy.png - - - - - - Popey - - - - :/icons/res/Popey.png - - - - - - Pinguin - - - - :/icons/res/Pinguin.png - - - - - - Mickey - - - - :/icons/res/Mickey.png - - - - - - - + + - Create new Hushchat address + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + 12 + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + + + + 0 + 0 + + + + Create New Address + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + + 250 + 25 + + + + 25 + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + 0 + 25 + + + + + SDLogo + + + + :/icons/res/SDLogo.png + + + + + + Duke + + + + :/icons/res/Duke.png + + + + + + Denio + + + + :/icons/res/Denio.png + + + + + + Berg + + + + :/icons/res/Berg.png + + + + + + Stag + + + + :/icons/res/Stag.png + + + + + + Sharpee + + + + :/icons/res/Sharpee.png + + + + + + Elsa + + + + :/icons/res/Elsa.png + + + + + + Yoda + + + + :/icons/res/Yoda.png + + + + + + Garfield + + + + :/icons/res/Garfield.png + + + + + + Snoopy + + + + :/icons/res/Snoopy.png + + + + + + Popey + + + + :/icons/res/Popey.png + + + + + + Pinguin + + + + :/icons/res/Pinguin.png + + + + + + Mickey + + + + :/icons/res/Mickey.png + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + From e8f987dae48ba6eabd5d3576779aa22e80e3683d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 8 Jun 2020 09:58:00 +0200 Subject: [PATCH 234/253] fix copy message --- src/mainwindow.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4fb9586..22bc64f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1386,8 +1386,8 @@ void MainWindow::setupchatTab() { QModelIndex index = ui->listChat->currentIndex(); QString memo_chat = index.data(Qt::DisplayRole).toString(); QClipboard *clipboard = QGuiApplication::clipboard(); - int startPos = memo_chat.indexOf("
") + 3;
-    int endPos = memo_chat.indexOf("
"); + int startPos = memo_chat.indexOf("

") + 3; + int endPos = memo_chat.indexOf("

"); int length = endPos - startPos; QString copymemo = memo_chat.mid(startPos, length); @@ -1401,8 +1401,8 @@ void MainWindow::setupchatTab() { QString memo_chat = index.data(Qt::DisplayRole).toString(); QClipboard *clipboard = QGuiApplication::clipboard(); - int startPos = memo_chat.indexOf("
") + 3;
-    int endPos = memo_chat.indexOf("
"); + int startPos = memo_chat.indexOf("

") + 3; + int endPos = memo_chat.indexOf("

"); int length = endPos - startPos; QString copymemo = memo_chat.mid(startPos, length); int startPosT = memo_chat.indexOf("") + 7; @@ -1439,8 +1439,8 @@ void MainWindow::setupchatTab() { QModelIndex index = ui->listChat->currentIndex(); QString memo_chat = index.data(Qt::DisplayRole).toString(); - int startPos = memo_chat.indexOf("
") + 3;
-    int endPos = memo_chat.indexOf("
"); + int startPos = memo_chat.indexOf("

") + 3; + int endPos = memo_chat.indexOf("

"); int length = endPos - startPos; QString copymemo = memo_chat.mid(startPos, length); int startPosT = memo_chat.indexOf("") + 7; From c5c3eab002b3c9d3c11c46e1b07b9519c7626e3c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 8 Jun 2020 21:50:58 +0200 Subject: [PATCH 235/253] set passphrase on initial install #64 --- src/DataStore/ChatDataStore.cpp | 12 +++ src/DataStore/ChatDataStore.h | 5 ++ src/chatmodel.cpp | 4 +- src/controller.cpp | 8 +- src/firsttimewizard.cpp | 61 ++++++++++++++-- src/firsttimewizard.h | 12 +++ src/mainwindow.cpp | 17 +++-- src/mainwindow.h | 12 ++- src/newseed.ui | 28 +++---- src/newwallet.ui | 125 +++++++++++++++++++++++--------- 10 files changed, 207 insertions(+), 77 deletions(-) diff --git a/src/DataStore/ChatDataStore.cpp b/src/DataStore/ChatDataStore.cpp index 5563fab..82f9db3 100644 --- a/src/DataStore/ChatDataStore.cpp +++ b/src/DataStore/ChatDataStore.cpp @@ -33,6 +33,18 @@ ChatItem ChatDataStore::getData(QString key) return this->data[key]; } +QString ChatDataStore::getPassword() +{ + + return _password; +} + +void ChatDataStore::setPassword(QString password) +{ + + _password = password; +} + QString ChatDataStore::dump() { json chats; diff --git a/src/DataStore/ChatDataStore.h b/src/DataStore/ChatDataStore.h index 7fb0998..c1233b6 100644 --- a/src/DataStore/ChatDataStore.h +++ b/src/DataStore/ChatDataStore.h @@ -25,6 +25,11 @@ class ChatDataStore std::map getAllNewContactRequests(); std::map getAllOldContactRequests(); std::map getAllMemos(); + QString getPassword(); + + void setPassword(QString Password); + QString _password; + QString dump(); ~ChatDataStore() diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 7fda03a..2fcbbf6 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -454,7 +454,7 @@ Tx MainWindow::createTxFromChatPage() { QString pubkey = this->getPubkeyByAddress(addr); - QString passphrase = this->getPassword(); + QString passphrase = DataStore::getChatDataStore()->getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); @@ -783,7 +783,7 @@ Tx MainWindow::createTxForSafeContactRequest() QString memo = contactRequest.getMemo(); // QString privkey = rpc->fetchPrivKey(myAddr); - QString passphrase = this->getPassword(); + QString passphrase = DataStore::getChatDataStore()->getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); diff --git a/src/controller.cpp b/src/controller.cpp index 495ee7d..6d02a40 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -11,10 +11,6 @@ #include "Model/ChatItem.h" #include "DataStore/DataStore.h" -/*template<> -DataStore* DataStore::instance = nullptr; -template<> -bool DataStore::instanced = false;*/ ChatModel *chatModel = new ChatModel(); Chat *chat = new Chat(); ContactModel *contactModel = new ContactModel(); @@ -971,7 +967,7 @@ void Controller::refreshTransactions() { if ((memo.startsWith("{") == false) && (headerbytes.length() > 20)) { - QString passphrase = main->getPassword(); + QString passphrase = DataStore::getChatDataStore()->getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); @@ -1227,7 +1223,7 @@ void Controller::refreshTransactions() { chatModel->addMemo(txid, headerbytes); }else{} - QString passphrase = main->getPassword(); + QString passphrase = DataStore::getChatDataStore()->getPassword(); QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); diff --git a/src/firsttimewizard.cpp b/src/firsttimewizard.cpp index 438f737..ffcfd84 100644 --- a/src/firsttimewizard.cpp +++ b/src/firsttimewizard.cpp @@ -3,6 +3,8 @@ #include "ui_newseed.h" #include "ui_restoreseed.h" #include "ui_newwallet.h" +#include "mainwindow.h" +#include "DataStore/DataStore.h" #include "../lib/silentdragonlitelib.h" @@ -38,31 +40,75 @@ int FirstTimeWizard::nextId() const { NewOrRestorePage::NewOrRestorePage(FirstTimeWizard *parent) : QWizardPage(parent) { setTitle("Create or Restore wallet."); + + QWidget* pageWidget = new QWidget(); Ui_CreateWalletForm form; form.setupUi(pageWidget); + - // Exclusive buttons + auto fnPasswordEdited = [=](const QString&) { + // Enable the Finish button if the passwords match. + QString Password = form.txtPassword->text(); + + if (!form.txtPassword->text().isEmpty() && + form.txtPassword->text() == form.txtConfirmPassword->text() && Password.size() >= 16) { + + form.lblPasswordMatch->setText(""); + parent->button(QWizard::CommitButton)->setEnabled(true); + setButtonText(QWizard::CommitButton, "Next"); + form.radioRestoreWallet->setEnabled(true); + form.radioNewWallet->setEnabled(true); + form.radioNewWallet->setChecked(true); + qDebug()<<"PW :"<setPassword(Password); + //main->setPassword(Password); + + //qDebug()<<"Objekt gesetzt"; + + + // Exclusive buttons QObject::connect(form.radioNewWallet, &QRadioButton::clicked, [=](bool checked) { if (checked) { form.radioRestoreWallet->setChecked(false); + } }); QObject::connect(form.radioRestoreWallet, &QRadioButton::clicked, [=](bool checked) { if (checked) { form.radioNewWallet->setChecked(false); + } }); - form.radioNewWallet->setChecked(true); + - registerField("intro.new", form.radioNewWallet); + + } else { + form.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)")); + + parent->button(QWizard::CommitButton)->setEnabled(false); + form.radioRestoreWallet->setEnabled(false); + form.radioNewWallet->setEnabled(false); + } + + }; QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(pageWidget); setLayout(layout); + + + QObject::connect(form.txtConfirmPassword, &QLineEdit::textChanged, fnPasswordEdited); + QObject::connect(form.txtPassword, &QLineEdit::textChanged, fnPasswordEdited); + registerField("intro.new", form.radioNewWallet); + form.radioRestoreWallet->setEnabled(false); + form.radioNewWallet->setEnabled(false); setCommitPage(true); - setButtonText(QWizard::CommitButton, "Next"); + + } NewSeedPage::NewSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) { @@ -81,6 +127,7 @@ NewSeedPage::NewSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) { void NewSeedPage::initializePage() { // Call the library to create a new wallet. + char* resp = litelib_initialize_new(parent->dangerous, parent->server.toStdString().c_str()); QString reply = litelib_process_response(resp); @@ -90,7 +137,11 @@ void NewSeedPage::initializePage() { } else { QString seed = QString::fromStdString(parsed["seed"].get()); form.txtSeed->setPlainText(seed); + + } + + } // Will be called just before closing. Make sure we can save the seed in the wallet @@ -175,4 +226,4 @@ bool RestoreSeedPage::validatePage() { return true; } } -} \ No newline at end of file +} diff --git a/src/firsttimewizard.h b/src/firsttimewizard.h index 276c0cd..8d84b61 100644 --- a/src/firsttimewizard.h +++ b/src/firsttimewizard.h @@ -5,11 +5,18 @@ #include "ui_newseed.h" #include "ui_restoreseed.h" +#include "mainwindow.h" + + class FirstTimeWizard: public QWizard { + + + public: FirstTimeWizard(bool dangerous, QString server); + protected: int nextId() const; @@ -27,11 +34,16 @@ private: friend class NewOrRestorePage; friend class NewSeedPage; friend class RestoreSeedPage; + + + }; class NewOrRestorePage: public QWizardPage { public: + NewOrRestorePage(FirstTimeWizard* parent); + }; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 22bc64f..bf5b464 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -31,6 +31,7 @@ #include "Crypto/passwd.h" #include "Crypto/FileEncryption.h" #include "DataStore/DataStore.h" +#include "firsttimewizard.h" using json = nlohmann::json; @@ -52,8 +53,6 @@ auto dirwalletenc = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLo auto dirwalletbackup = QDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation)).filePath(".silentdragonlite/silentdragonlite-wallet.datBackup"); #endif - - MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -289,10 +288,10 @@ void MainWindow::closeEvent(QCloseEvent* event) { s.sync(); - + // Let the RPC know to shut down any running service. rpc->shutdownhushd(); - int passphraselenght = this->getPassword().length(); + int passphraselenght = DataStore::getChatDataStore()->getPassword().length(); // Check is encryption is ON for SDl if(passphraselenght > 0) @@ -305,7 +304,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { fileoldencryption.remove(); // Encrypt our wallet.dat - QString str = this->getPassword(); + QString str = DataStore::getChatDataStore()->getPassword(); // QString str = ed.txtPassword->text(); // data comes from user inputs int length = str.length(); @@ -401,7 +400,7 @@ void MainWindow::encryptWallet() { QString passphrase = ed.txtPassword->text(); // data comes from user inputs int length = passphrase.length(); - this->setPassword(passphrase); + DataStore::getChatDataStore()->setPassword(passphrase); char *sequence = NULL; sequence = new char[length+1]; @@ -561,7 +560,7 @@ void MainWindow::removeWalletEncryptionStartUp() { { QString password = ed.txtPassword->text(); // data comes from user inputs int length = password.length(); - this->setPassword(password); + DataStore::getChatDataStore()->setPassword(password); char *sequence = NULL; sequence = new char[length+1]; strncpy(sequence, password.toLocal8Bit(), length +1); @@ -663,6 +662,7 @@ void MainWindow::setupStatusBar() { loadingMovie->start(); loadingLabel->setAttribute(Qt::WA_NoSystemBackground); loadingLabel->setMovie(loadingMovie); + ui->statusBar->addPermanentWidget(loadingLabel); loadingLabel->setVisible(false); @@ -1159,7 +1159,6 @@ void MainWindow::setupBalancesTab() { ui->lblSyncWarning->setVisible(false); ui->lblSyncWarningReceive->setVisible(false); - // Setup context menu on balances tab ui->balancesTable->setContextMenuPolicy(Qt::CustomContextMenu); QObject::connect(ui->balancesTable, &QTableView::customContextMenuRequested, [=] (QPoint pos) { @@ -1191,6 +1190,8 @@ void MainWindow::setupBalancesTab() { menu.exec(ui->balancesTable->viewport()->mapToGlobal(pos)); }); + + qDebug()<<"PW :"<getPassword(); } void MainWindow::setuphushdTab() { diff --git a/src/mainwindow.h b/src/mainwindow.h index 53032df..62ff3f3 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -5,7 +5,7 @@ #include "logger.h" #include "recurring.h" - +#include "firsttimewizard.h" // Forward declare to break circular dependency. class Controller; @@ -59,6 +59,7 @@ public: void addPubkey(QString requestZaddr, QString pubkey); + void replaceWormholeClient(WormholeClient* newClient); bool isWebsocketListening(); @@ -67,10 +68,7 @@ public: void saveContact(); void saveandsendContact(); void showRequesthush(); - // void setmaxlenChat(int len); - // void updateDisplay(); - - + void balancesReady(); void payhushURI(QString uri = "", QString myAddr = ""); @@ -113,6 +111,7 @@ private: bool fileExists(QString path); void closeEvent(QCloseEvent* event); void closeEventpw(QCloseEvent* event); + QString _password; void setupSendTab(); @@ -122,7 +121,6 @@ private: void setuphushdTab(); void setupchatTab(); void renderContactRequest(); - // void setLenDisplayLabel(QLabel* label); void updateContacts(); void updateChat(); @@ -131,7 +129,7 @@ private: void setupStatusBar(); void clearSendForm(); - QString _password; + Tx createTxFromSendPage(); bool confirmTx(Tx tx, RecurringPaymentInfo* rpi); diff --git a/src/newseed.ui b/src/newseed.ui index ed5d9ae..7657542 100644 --- a/src/newseed.ui +++ b/src/newseed.ui @@ -6,15 +6,15 @@ 0 0 - 400 - 300 + 427 + 416 Form - + This is your new wallet's seed phrase. PLEASE BACK IT UP SECURELY. @@ -24,17 +24,7 @@ - - - - The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it - - - true - - - - + @@ -56,6 +46,16 @@
+ + + + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it + + + true + + + diff --git a/src/newwallet.ui b/src/newwallet.ui index 9cf34c5..ac2a5af 100644 --- a/src/newwallet.ui +++ b/src/newwallet.ui @@ -6,47 +6,15 @@ 0 0 - 400 - 300 + 437 + 381 Form - - - - - 0 - 0 - - - - - - - - - - Restore wallet from seed - - - - - - - Restore an existing wallet, using the 24-word seed. - - - true - - - - - - - + @@ -78,6 +46,93 @@ + + + + Qt::Horizontal + + + + + + + color: red; + + + Passphrase don't match + + + Qt::AlignCenter + + + + + + + <html><head/><body><p>16 letters minimum</p></body></html> + + + + + + + Encryption Passphrase: + + + + + + + QLineEdit::Password + + + + + + + Confirm Passphrase: + + + + + + + QLineEdit::Password + + + + + + + + 0 + 0 + + + + + + + + + + Restore wallet from seed + + + + + + + Restore an existing wallet, using the 24-word seed. + + + true + + + + + + From f734976773cc19c44a55ef479f365bcbcabcfc5d Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Mon, 8 Jun 2020 18:11:18 -0400 Subject: [PATCH 236/253] More GUI fixes, typos and GUI updates for fixed frame sizes encrypt/decrypt boxes. --- src/contactrequest.ui | 287 +++++++++++++++++++-------------------- src/encryption.ui | 164 +++++++++++++--------- src/removeencryption.ui | 272 +++++++++++++++++-------------------- src/startupencryption.ui | 24 ++++ 4 files changed, 388 insertions(+), 359 deletions(-) diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 286dbdb..d8ca0a6 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -7,85 +7,51 @@ 0 0 780 - 427 + 351 - + 0 0 + + + 780 + 351 + + 780 - 427 + 351 Send a contact request - - - - - 500 - 71 - - - - Qt::NoContextMenu - - - false - - - Qt::ImhSensitiveData - - - 512 - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - false - - - Add a memo to your request - - - true - - - - - - - - 650 - 25 - - - - - 650 - 25 - - - - - - + + - Add Contact and Send Request + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> - - false + + + + + + + 0 + 0 + - - false + + + 650 + 25 + @@ -108,99 +74,11 @@ - - - - - 0 - 0 - - - - - 100 - 0 - - - - Cancel - - - false - - - false - - - - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> - - - - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> - - - - - - - 12 - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> - - - - - - - - 0 - 0 - - - - Create New Address - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + + QLayout::SetMaximumSize + @@ -394,8 +272,108 @@ + + + + + 0 + 0 + + + + + 100 + 0 + + + + Cancel + + + false + + + false + + + + + + + Add Contact and Send Request + + + false + + + false + + + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + + + 6 + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + + + + 0 + 0 + + + + Create New Address + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QLayout::SetMaximumSize + @@ -453,6 +431,13 @@ + + + + Add a memo to your request + + + diff --git a/src/encryption.ui b/src/encryption.ui index ae2643b..7f2388c 100644 --- a/src/encryption.ui +++ b/src/encryption.ui @@ -10,12 +10,37 @@ 300 + + + 0 + 0 + + + + + 400 + 300 + + + + + 400 + 300 + + Encrypt Your Wallet - - + + + + Encryption Passphrase: + + + + + Qt::Vertical @@ -29,8 +54,14 @@ + + + 0 + 0 + + - <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase the only way to recover the wallet is from the seed phrase. If you dont have Backup your seed phrase, please do it now!</p></body></html> + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> Qt::AlignCenter @@ -40,8 +71,48 @@ - - + + + + Qt::Horizontal + + + + + + + QLineEdit::Password + + + + + + + Confirm Passphrase: + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + Qt::Vertical @@ -53,78 +124,49 @@ - + Qt::Horizontal - - - - <html><head/><body><p>16 letters minimum</p></body></html> - - - - - - - color: red; - - - Passphrase don't match - - - Qt::AlignCenter - - - - - - - Encryption Passphrase: - - - - - - - QLineEdit::Password - - - - - - - Confirm Passphrase: - - - - + QLineEdit::Password - - - - Qt::Horizontal + + + + + 0 + 0 + + + + color: red; + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + Qt::AlignCenter - - - - Qt::Horizontal + + + + + 0 + 0 + - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - true + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> diff --git a/src/removeencryption.ui b/src/removeencryption.ui index 11bee22..2194997 100644 --- a/src/removeencryption.ui +++ b/src/removeencryption.ui @@ -10,154 +10,132 @@ 300 - - Remove your Wallet encryption + + + 0 + 0 + - - - - 50 - 260 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 260 - 170 - 133 - 23 - - - - <html><head/><body><p>16 letters minimum</p></body></html> - - - - - - 10 - 229 - 157 - 25 - - - - Confirm Passphrase: - - - - - - 10 - 164 - 382 - 3 - - - - Qt::Horizontal - - - - - - 173 - 229 - 219 - 25 - - - - QLineEdit::Password - - - - - - 10 - 56 - 382 - 56 - - - - <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your encryption, all your transactions and contacts are plaintext on disk! Messages are still encrypt.</p></body></html> - - - Qt::AlignCenter - - - true - - - - - - 10 - 260 - 382 - 3 - - - - Qt::Horizontal - - - - - - 10 - 198 - 157 - 25 - - - - Encryption Passphrase: - - - - - - 10 - 175 - 243 - 17 - - - - color: red; - - - Passphrase don't match - - - Qt::AlignCenter - - - - - - 173 - 198 - 219 - 25 - - - - QLineEdit::Password - - + + + 400 + 300 + + + + + 400 + 300 + + + + Decrypt Your Wallet + + + + + + Qt::Horizontal + + + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + QLineEdit::Password + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Encryption Passphrase: + + + + + + + Confirm Passphrase: + + + + + + + Qt::Horizontal + + + + + + + QLineEdit::Password + + + + + + + + 0 + 0 + + + + color: red; + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + Qt::AlignCenter + + + + diff --git a/src/startupencryption.ui b/src/startupencryption.ui index 56fc02c..963d2f0 100644 --- a/src/startupencryption.ui +++ b/src/startupencryption.ui @@ -10,6 +10,24 @@ 177 + + + 0 + 0 + + + + + 400 + 177 + + + + + 400 + 177 + + SDL Startup Decryption @@ -43,6 +61,12 @@ + + + 0 + 25 + + QLineEdit::Password From 38aebf72748c47039ed9caaa7e5ad700d7cf4b88 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Mon, 8 Jun 2020 20:06:40 -0400 Subject: [PATCH 237/253] beginning integration formemo counter of limited characters; changing from QLineEdit to QTextEdit for wrapping of text --- src/chatmodel.cpp | 2 +- src/contactrequest.ui | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 2fcbbf6..c3f5f08 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -734,7 +734,7 @@ QObject::connect(request.newZaddr, &QPushButton::clicked, [&] () { QString addr = request.zaddr->text(); QString myAddr = request.myzaddr->text().trimmed(); - QString memo = request.memorequest->text().trimmed(); + QString memo = request.memorequest->toPlainText().trimmed(); QString avatar = QString(":/icons/res/") + request.comboBoxAvatar->currentText() + QString(".png"); QString label = request.labelRequest->text().trimmed(); diff --git a/src/contactrequest.ui b/src/contactrequest.ui index d8ca0a6..91328db 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -432,12 +432,25 @@ - + Add a memo to your request + + + + + 0 + 0 + + + + 0/235 + + + From f697520049246dde82ed6cbd00917c8aede422fc Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 9 Jun 2020 08:24:45 +0200 Subject: [PATCH 238/253] set maxlen to 512 for request --- src/contactrequest.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 91328db..1b9bd7d 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -447,7 +447,7 @@ - 0/235 + 0/512 From 72357dfc17dfc65196c66b4908767197bc45c437 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 9 Jun 2020 12:06:46 +0200 Subject: [PATCH 239/253] set focus to the last chatItem --- src/controller.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/controller.cpp b/src/controller.cpp index 6d02a40..3bb208b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1379,6 +1379,8 @@ void Controller::refreshTransactions() { // Update model data, which updates the table view transactionsTableModel->replaceData(txdata); chat->renderChatBox(ui, ui->listChat,ui->memoSizeChat); + ui->listChat->verticalScrollBar()->setValue( + ui->listChat->verticalScrollBar()->maximum()); }); } @@ -1386,6 +1388,8 @@ void Controller::refreshTransactions() { void Controller::refreshChat(QListView *listWidget, QLabel *label) { chat->renderChatBox(ui, listWidget, label); + ui->listChat->verticalScrollBar()->setValue( + ui->listChat->verticalScrollBar()->maximum()); } From c44322a5e6cd568db16aacab244bb81b5937b54d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 9 Jun 2020 23:46:51 +0200 Subject: [PATCH 240/253] encrypt zdust memo --- src/controller.cpp | 109 +++++++++++++++++++++++++++++++++------- src/controller.h | 1 + src/firsttimewizard.cpp | 1 - src/mainwindow.cpp | 1 - 4 files changed, 92 insertions(+), 20 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 3bb208b..6bcd569 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -91,7 +91,7 @@ void Controller::setConnection(Connection* c) // Create Sietch zdust addr at startup. // Using DataStore singelton, to store the data outside of lambda, bing bada boom :D - for(uint8_t i = 0; i < 10; i++) + for(uint8_t i = 0; i < 6; i++) { zrpc->createNewSietchZaddr( [=] (json reply) { QString zdust = QString::fromStdString(reply.get()[0]); @@ -104,6 +104,21 @@ void Controller::setConnection(Connection* c) ); } +std::string Controller::encryptDecrypt(std::string toEncrypt) +{ + + int radomInteger = rand() % 1000000000 +100000; + + char key = radomInteger; + std::string output = toEncrypt; + + for (int i = 0; i < toEncrypt.size(); i++) + output[i] = toEncrypt[i] ^ key; + + return output; + +} + // Build the RPC JSON Parameters for this tx void Controller::fillTxJsonParams(json& allRecepients, Tx tx) { @@ -113,12 +128,12 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) json rec = json::object(); //creating the JSON dust parameters in a std::vector to iterate over there during tx - std::vector dust(10); - dust.resize(10, json::object()); + std::vector dust(6); + dust.resize(6, json::object()); // Create Sietch zdust addr again to not use it twice. // Using DataStore singelton, to store the data outside of lambda, bing bada boom :D - for(uint8_t i = 0; i < 10; i++) + for(uint8_t i = 0; i < 6; i++) { zrpc->createNewSietchZaddr( [=] (json reply) { QString zdust = QString::fromStdString(reply.get()[0]); @@ -128,20 +143,74 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) // Set sietch zdust addr to json. // Using DataStore singelton, to store the data into the dusts, bing bada boom :D - for(uint8_t i = 0; i < 10; i++) + for(uint8_t i = 0; i < 6; i++) { dust.at(i)["address"] = DataStore::getSietchDataStore()->getData(QString("Sietch" + QString(i))).toStdString(); } DataStore::getSietchDataStore()->clear(); // clears the datastore - // Dust amt/memo, construct the JSON - for(uint8_t i = 0; i < 8; i++) + const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); + + int sizerandomString = rand() % 250 +125; + const int randomStringLength = sizerandomString; // assuming you want random strings of 12 characters + + QString randomString; + for(int i=0; i(hash),MESSAGE_LEN1); + + ///encrypt zdust memo + std::string encrypt = this->encryptDecrypt(decryptedMemo); + QString randomHashafter1 = QString::fromUtf8( encrypt.data(), encrypt.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + std::string encrypt2 = this->encryptDecrypt(decryptedMemo); + QString randomHashafter2 = QString::fromUtf8( encrypt2.data(), encrypt2.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + std::string encrypt3 = this->encryptDecrypt(decryptedMemo); + QString randomHashafter3 = QString::fromUtf8( encrypt3.data(), encrypt3.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + std::string encrypt4 = this->encryptDecrypt(decryptedMemo); + QString randomHashafter4 = QString::fromUtf8( encrypt4.data(), encrypt4.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + std::string encrypt5 = this->encryptDecrypt(decryptedMemo); + QString randomHashafter5 = QString::fromUtf8( encrypt5.data(), encrypt5.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + std::string encrypt6 = this->encryptDecrypt(decryptedMemo); + QString randomHashafter6 = QString::fromUtf8( encrypt6.data(), encrypt6.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + std::string encrypt7 = this->encryptDecrypt(decryptedMemo); + QString randomHashafter7 = QString::fromUtf8( encrypt7.data(), encrypt7.size() + crypto_secretstream_xchacha20poly1305_ABYTES); + + + for(uint8_t i = 0; i < 6; i++) { - dust.at(i)["amount"] = 0; - dust.at(i)["memo"] = ""; - + dust.at(i)["amount"] = 0; } + + dust.at(0)["memo"] = randomHashafter1.toStdString(); + dust.at(1)["memo"] = randomHashafter2.toStdString(); + dust.at(2)["memo"] = randomHashafter3.toStdString(); + dust.at(3)["memo"] = randomHashafter4.toStdString(); + dust.at(4)["memo"] = randomHashafter5.toStdString(); + dust.at(5)["memo"] = randomHashafter6.toStdString(); + // For each addr/amt/memo, construct the JSON and also build the confirm dialog box for (int i=0; i < tx.toAddrs.size(); i++) @@ -161,8 +230,7 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) dust.at(2), dust.at(3), dust.at(4), - dust.at(5), - dust.at(6) + dust.at(5) }) ; } @@ -971,14 +1039,11 @@ void Controller::refreshTransactions() { QString hashEncryptionKey = passphrase; int length = hashEncryptionKey.length(); - - ////////////////Generate the secretkey for our message encryption char *hashEncryptionKeyraw = NULL; hashEncryptionKeyraw = new char[length+1]; strncpy(hashEncryptionKeyraw, hashEncryptionKey.toLocal8Bit(), length +1); - const QByteArray pubkeyBobArray = QByteArray::fromHex(publickey.toLatin1()); const unsigned char *pubkeyBob = reinterpret_cast(pubkeyBobArray.constData()); @@ -1019,9 +1084,12 @@ void Controller::refreshTransactions() { const QByteArray ba1 = QByteArray::fromHex(headerbytes.toLatin1()); const unsigned char *header = reinterpret_cast(ba1.constData()); - int encryptedMemoSize1 = ba.length(); + QString memodecrypt; + + if (encryptedMemoSize1 > 15) + { //////unsigned char* as message from QString #define MESSAGE2 (const unsigned char *) encryptedMemo @@ -1050,10 +1118,15 @@ void Controller::refreshTransactions() { } std::string decryptedMemo(reinterpret_cast(decrypted),MESSAGE1_LEN); - + + memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); + + }else{ + memodecrypt = ""; + + } /////Now we can convert it to QString - QString memodecrypt = QString::fromUtf8( decryptedMemo.data(), decryptedMemo.size()); //////////////Give us the output of the decrypted message as debug to see if it was successfully diff --git a/src/controller.h b/src/controller.h index f66596f..195827c 100644 --- a/src/controller.h +++ b/src/controller.h @@ -44,6 +44,7 @@ public: int getLag(); void setLag(int lag); int _lag; + std::string encryptDecrypt(std::string); void checkForUpdate(bool silent = true); void refreshZECPrice(); diff --git a/src/firsttimewizard.cpp b/src/firsttimewizard.cpp index ffcfd84..5ef96bb 100644 --- a/src/firsttimewizard.cpp +++ b/src/firsttimewizard.cpp @@ -60,7 +60,6 @@ NewOrRestorePage::NewOrRestorePage(FirstTimeWizard *parent) : QWizardPage(parent form.radioRestoreWallet->setEnabled(true); form.radioNewWallet->setEnabled(true); form.radioNewWallet->setChecked(true); - qDebug()<<"PW :"<setPassword(Password); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index bf5b464..c3be452 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1191,7 +1191,6 @@ void MainWindow::setupBalancesTab() { menu.exec(ui->balancesTable->viewport()->mapToGlobal(pos)); }); - qDebug()<<"PW :"<getPassword(); } void MainWindow::setuphushdTab() { From f8e295775a8e5b4af408a1aa35c5df5b6de63045 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Wed, 10 Jun 2020 01:32:41 -0400 Subject: [PATCH 241/253] Title capitalization of all themes, fixed border for settings.ui, increased width of theme & currency boxes to accomodate longer theme names --- application.qrc | 27 ++++++++++--------- res/css/{blue.css => Blue.css} | 0 res/css/{dark.css => Dark.css} | 0 res/css/{default.css => Default.css} | 0 res/css/{light.css => Light.css} | 0 res/css/{midnight.css => Midnight.css} | 0 src/chatmodel.cpp | 10 +++---- src/connection.cpp | 2 +- src/controller.cpp | 2 +- src/mainwindow.cpp | 10 +++---- src/sendtab.cpp | 2 +- src/settings.cpp | 2 +- src/settings.ui | 36 +++++++++++++++++++------- 13 files changed, 54 insertions(+), 37 deletions(-) rename res/css/{blue.css => Blue.css} (100%) rename res/css/{dark.css => Dark.css} (100%) rename res/css/{default.css => Default.css} (100%) rename res/css/{light.css => Light.css} (100%) rename res/css/{midnight.css => Midnight.css} (100%) diff --git a/application.qrc b/application.qrc index 345aac4..e6c1b2d 100644 --- a/application.qrc +++ b/application.qrc @@ -47,7 +47,6 @@ res/addContactBlack.png res/unknownBlack.png res/unknownWhite.png - res/hushdlogo.gif @@ -59,21 +58,21 @@ res/loaderwhite.gif - res/silentdragonlite_de.qm - res/silentdragonlite_es.qm - res/silentdragonlite_fr.qm - res/silentdragonlite_pt.qm - res/silentdragonlite_it.qm - res/silentdragonlite_hr.qm - res/silentdragonlite_fa.qm - res/silentdragonlite_id.qm + res/silentdragonlite_de.qm + res/silentdragonlite_es.qm + res/silentdragonlite_fr.qm + res/silentdragonlite_pt.qm + res/silentdragonlite_it.qm + res/silentdragonlite_hr.qm + res/silentdragonlite_fa.qm + res/silentdragonlite_id.qm - res/css/blue.css - res/css/dark.css - res/css/default.css - res/css/light.css - res/css/midnight.css + res/css/Blue.css + res/css/Dark.css + res/css/Default.css + res/css/Light.css + res/css/Midnight.css res/images/blue/unchecked.png diff --git a/res/css/blue.css b/res/css/Blue.css similarity index 100% rename from res/css/blue.css rename to res/css/Blue.css diff --git a/res/css/dark.css b/res/css/Dark.css similarity index 100% rename from res/css/dark.css rename to res/css/Dark.css diff --git a/res/css/default.css b/res/css/Default.css similarity index 100% rename from res/css/default.css rename to res/css/Default.css diff --git a/res/css/light.css b/res/css/Light.css similarity index 100% rename from res/css/light.css rename to res/css/Light.css diff --git a/res/css/midnight.css b/res/css/Midnight.css similarity index 100% rename from res/css/midnight.css rename to res/css/Midnight.css diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index c3f5f08..fe4e92b 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -101,7 +101,7 @@ void MainWindow::renderContactRequest(){ QString icon; auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { icon = ":/icons/res/unknownWhite.png"; }else{ icon = ":/icons/res/unknownBlack.png"; @@ -587,7 +587,7 @@ void MainWindow::sendChat() { movie1->setFileName(":/img/res/loaderwhite.gif"); auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { connect(movie, &QMovie::frameChanged, [=]{ ui->sendChatButton->setIcon(movie->currentPixmap()); @@ -616,7 +616,7 @@ void MainWindow::sendChat() { QTimer::singleShot(1000, [=]() { - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { QPixmap send(":/icons/res/send-white.png"); QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); @@ -649,7 +649,7 @@ void MainWindow::sendChat() { movie->stop(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { QPixmap send(":/icons/res/send-white.png"); QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); @@ -881,7 +881,7 @@ void MainWindow::ContactRequest() { QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif"); QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif"); auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { movie2->setScaledSize(QSize(512,512)); connD->topIcon->setMovie(movie2); movie2->start(); diff --git a/src/connection.cpp b/src/connection.cpp index bbc3bce..569ebed 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -23,7 +23,7 @@ ConnectionLoader::ConnectionLoader(MainWindow* main, Controller* rpc) qDebug() << theme << "theme has loaded"; auto size = QSize(512,512); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-startup-dark.gif");; movie2->setScaledSize(size); qDebug() << "Animation dark loaded"; diff --git a/src/controller.cpp b/src/controller.cpp index 6bcd569..7cca1a7 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -2035,7 +2035,7 @@ void Controller::shutdownhushd() auto theme = Settings::getInstance()->get_theme_name(); auto size = QSize(512,512); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-startup-dark.gif");; movie2->setScaledSize(size); qDebug() << "Animation dark loaded"; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index c3be452..6eba199 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -66,7 +66,7 @@ MainWindow::MainWindow(QWidget *parent) : } catch (...) { - theme_name = "dark"; + theme_name = "Dark"; } this->slot_change_theme(theme_name); @@ -1213,10 +1213,10 @@ void MainWindow::setupTransactionsTab() { // Set up context menu on transactions tab auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { ui->listChat->setStyleSheet("background-image: url(:/icons/res/sdlogo.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover"); } - if (theme == "default") {ui->listChat->setStyleSheet("background-image: url(:/icons/res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} + if (theme == "Default") {ui->listChat->setStyleSheet("background-image: url(:/icons/res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} ui->listChat->setResizeMode(QListView::Adjust); ui->listChat->setWordWrap(true); @@ -1316,7 +1316,7 @@ void MainWindow::setupchatTab() { /////////////Setting Icons for Chattab and different themes auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { QPixmap send(":/icons/res/send-white.png"); QIcon sendIcon(send); ui->sendChatButton->setIcon(sendIcon); @@ -1955,7 +1955,7 @@ void MainWindow::slot_change_theme(const QString& theme_name) } catch (...) { - saved_theme_name = "dark"; + saved_theme_name = "Dark"; } QFile qFile(":/css/res/css/" + saved_theme_name +".css"); diff --git a/src/sendtab.cpp b/src/sendtab.cpp index 6f3fc11..7e21261 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -846,7 +846,7 @@ void MainWindow::sendButton() { QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif");; QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif");; auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark" || theme == "midnight") { + if (theme == "Dark" || theme == "Midnight") { movie2->setScaledSize(QSize(512,512)); connD->topIcon->setMovie(movie2); movie2->start(); diff --git a/src/settings.cpp b/src/settings.cpp index dfe1e11..fd47f76 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -230,7 +230,7 @@ void Settings::set_currency_name(QString currency_name) { QString Settings::get_theme_name() { // Load from the QT Settings. - return QSettings().value("options/theme_name", "dark").toString(); + return QSettings().value("options/theme_name", "Dark").toString(); } void Settings::set_theme_name(QString theme_name) { diff --git a/src/settings.ui b/src/settings.ui index ac730fb..57620e5 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -6,10 +6,28 @@ 0 0 - 733 - 539 + 590 + 443 + + + 0 + 0 + + + + + 590 + 443 + + + + + 590 + 443 + + Settings @@ -85,7 +103,7 @@ 80 110 - 80 + 111 25 @@ -97,27 +115,27 @@ - dark + Dark - default + Midnight - blue + Light - light + Blue - midnight + Default @@ -241,7 +259,7 @@ 80 150 - 80 + 111 25 From 8a840d29c806f331aa81acf8de1768e4b55bb104 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Wed, 10 Jun 2020 01:45:27 -0400 Subject: [PATCH 242/253] Fixed encrypt wallet display bug; commented out line. On entering text in 2nd field, caused long sentence to display that was unreadable. --- src/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6eba199..3e9d2a0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -386,7 +386,7 @@ void MainWindow::encryptWallet() { ed.lblPasswordMatch->setText(""); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } else { - ed.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)")); + //ed.lblPasswordMatch->setText(tr("Passphrase don't match or You have entered too few letters (16 minimum)")); ed.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } @@ -445,7 +445,7 @@ void MainWindow::encryptWallet() { address.rename(dir.filePath("addresslabels.datBackup")); QMessageBox::information(this, tr("Wallet Encryption Success"), - QString("Successfully encrypt your wallet"), + QString("Successfully encrypted your wallet"), QMessageBox::Ok ); } From 65379b8c063c7ff6c5e8bc84045859a7bb9ebe41 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Wed, 10 Jun 2020 02:17:08 -0400 Subject: [PATCH 243/253] Updated window titles, fixed addressbook layout issues with Avatar & Nickname, spellings. --- src/addressbook.ui | 49 ++++++- src/connection.ui | 14 +- src/contactrequest.ui | 284 ++++++++++++++++++------------------ src/hushrequest.ui | 2 +- src/mainwindow.cpp | 2 +- src/mobileappconnector.ui | 2 +- src/newwallet.ui | 164 +++++++++++---------- src/recurringdialog.ui | 2 +- src/recurringmultiple.ui | 2 +- src/recurringpayments.ui | 2 +- src/requestContactDialog.ui | 2 +- src/restoreseed.ui | 2 +- 12 files changed, 295 insertions(+), 232 deletions(-) diff --git a/src/addressbook.ui b/src/addressbook.ui index 08b2356..80b3a80 100644 --- a/src/addressbook.ui +++ b/src/addressbook.ui @@ -67,15 +67,28 @@ - <html><head/><body><p align="right">Nickname :</p></body></html> + <html><head/><body><p>Nickname :</p></body></html> - + + + + 0 + 25 + + + + + + 0 + 25 + + 25 @@ -89,7 +102,14 @@ - + + + + 0 + 25 + + + @@ -99,10 +119,23 @@ - + + + + 0 + 25 + + + + + + 0 + 25 + + Add to Address Book @@ -245,12 +278,18 @@ - <html><head/><body><p align="right">Avatar :</p></body></html> + <html><head/><body><p>Avatar :</p></body></html> + + + 0 + 25 + + Create a new HushChat zaddr diff --git a/src/connection.ui b/src/connection.ui index 69c6a7c..8c950bd 100644 --- a/src/connection.ui +++ b/src/connection.ui @@ -10,9 +10,21 @@ 0 0 512 - 513 + 512 + + + 512 + 512 + + + + + 512 + 512 + + SilentDragonLite diff --git a/src/contactrequest.ui b/src/contactrequest.ui index 1b9bd7d..d187eb1 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -29,9 +29,71 @@ - Send a contact request + Send Contact Request + + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -39,6 +101,58 @@ + + + + 6 + + + QLayout::SetMaximumSize + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + + + + 0 + 0 + + + + Create New Address + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -55,6 +169,13 @@ + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + @@ -272,6 +393,26 @@ + + + + + 0 + 0 + + + + 0/512 + + + + + + + Add a memo to your request + + + @@ -310,147 +451,6 @@ - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> - - - - - - - 6 - - - QLayout::SetMaximumSize - - - - - - 0 - 0 - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> - - - - - - - - 0 - 0 - - - - Create New Address - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QLayout::SetMaximumSize - - - - - - 0 - 0 - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Add a memo to your request - - - - - - - - 0 - 0 - - - - 0/512 - - - diff --git a/src/hushrequest.ui b/src/hushrequest.ui index d0b0ca7..f51aebd 100644 --- a/src/hushrequest.ui +++ b/src/hushrequest.ui @@ -11,7 +11,7 @@ - Dialog + Request Payment diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3e9d2a0..441126e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -612,7 +612,7 @@ void MainWindow::removeWalletEncryptionStartUp() { { - QMessageBox::information(this, tr("You have still Plaintextdata on your disk!"), + QMessageBox::information(this, tr("You still have plaintext data on your disk!"), QString("WARNING: Delete it only if you have a backup of your Wallet Seed."), QMessageBox::Ok ); diff --git a/src/mobileappconnector.ui b/src/mobileappconnector.ui index 9412c37..823a497 100644 --- a/src/mobileappconnector.ui +++ b/src/mobileappconnector.ui @@ -11,7 +11,7 @@ - Connect Mobile App + Mobile Connector App diff --git a/src/newwallet.ui b/src/newwallet.ui index ac2a5af..9f1e76c 100644 --- a/src/newwallet.ui +++ b/src/newwallet.ui @@ -11,90 +11,17 @@ - Form + Create New SDL Wallet - - - - - 0 - 0 - - - - - - - - - - Create a new Wallet - - - - - - - Create a new wallet with a randomly generated seed. - - - true - - - - - - - - - - Qt::Horizontal - - - - - - - color: red; - - - Passphrase don't match - - - Qt::AlignCenter - - - - - - - <html><head/><body><p>16 letters minimum</p></body></html> - - - - - - - Encryption Passphrase: - - - - - - - QLineEdit::Password - - - - + Confirm Passphrase: - + QLineEdit::Password @@ -133,6 +60,91 @@ + + + + QLineEdit::Password + + + + + + + + 0 + 0 + + + + + + + + + + Create a new wallet + + + + + + + Create a new wallet with a randomly generated seed. + + + true + + + + + + + + + + Qt::Horizontal + + + + + + + Encryption Passphrase: + + + + + + + + 0 + 0 + + + + color: red; + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + diff --git a/src/recurringdialog.ui b/src/recurringdialog.ui index fbe26e6..6e53279 100644 --- a/src/recurringdialog.ui +++ b/src/recurringdialog.ui @@ -11,7 +11,7 @@ - Dialog + Reccuring Dialog diff --git a/src/recurringmultiple.ui b/src/recurringmultiple.ui index b895ecb..e7a41ca 100644 --- a/src/recurringmultiple.ui +++ b/src/recurringmultiple.ui @@ -11,7 +11,7 @@ - Dialog + Recurring Multiple Payments diff --git a/src/recurringpayments.ui b/src/recurringpayments.ui index 3874370..839fe73 100644 --- a/src/recurringpayments.ui +++ b/src/recurringpayments.ui @@ -11,7 +11,7 @@ - Payments + Reocurring Payments diff --git a/src/requestContactDialog.ui b/src/requestContactDialog.ui index 237f206..76e904a 100644 --- a/src/requestContactDialog.ui +++ b/src/requestContactDialog.ui @@ -23,7 +23,7 @@ - Incoming contact request + Incoming Contact Request diff --git a/src/restoreseed.ui b/src/restoreseed.ui index 9cc2b3f..64bd43f 100644 --- a/src/restoreseed.ui +++ b/src/restoreseed.ui @@ -11,7 +11,7 @@ - Form + Restore Wallet Seed From 83912f6efbcd86416043badd889c498a71ab20ee Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 10 Jun 2020 11:48:25 +0200 Subject: [PATCH 244/253] zdust memos with random size, zdust memo in hex --- src/controller.cpp | 52 ++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 6bcd569..066f055 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -108,6 +108,7 @@ std::string Controller::encryptDecrypt(std::string toEncrypt) { int radomInteger = rand() % 1000000000 +100000; + char key = radomInteger; std::string output = toEncrypt; @@ -150,21 +151,23 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) DataStore::getSietchDataStore()->clear(); // clears the datastore - const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); + const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); - int sizerandomString = rand() % 250 +125; - const int randomStringLength = sizerandomString; // assuming you want random strings of 12 characters + int sizerandomString = rand() % 120 +10; + const int randomStringLength = sizerandomString; - QString randomString; - for(int i=0; i(hash),MESSAGE_LEN1); - - ///encrypt zdust memo - std::string encrypt = this->encryptDecrypt(decryptedMemo); - QString randomHashafter1 = QString::fromUtf8( encrypt.data(), encrypt.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - std::string encrypt2 = this->encryptDecrypt(decryptedMemo); - QString randomHashafter2 = QString::fromUtf8( encrypt2.data(), encrypt2.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - std::string encrypt3 = this->encryptDecrypt(decryptedMemo); - QString randomHashafter3 = QString::fromUtf8( encrypt3.data(), encrypt3.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - std::string encrypt4 = this->encryptDecrypt(decryptedMemo); - QString randomHashafter4 = QString::fromUtf8( encrypt4.data(), encrypt4.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - std::string encrypt5 = this->encryptDecrypt(decryptedMemo); - QString randomHashafter5 = QString::fromUtf8( encrypt5.data(), encrypt5.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - std::string encrypt6 = this->encryptDecrypt(decryptedMemo); - QString randomHashafter6 = QString::fromUtf8( encrypt6.data(), encrypt6.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - std::string encrypt7 = this->encryptDecrypt(decryptedMemo); - QString randomHashafter7 = QString::fromUtf8( encrypt7.data(), encrypt7.size() + crypto_secretstream_xchacha20poly1305_ABYTES); - +std::string encrypt = this->encryptDecrypt(decryptedMemo); +QString randomHashafter1 = QByteArray(reinterpret_cast(encrypt.c_str()),encrypt.size()).toHex(); +dust.at(i)["memo"] = randomHashafter1.toStdString(); + + } for(uint8_t i = 0; i < 6; i++) { dust.at(i)["amount"] = 0; } - dust.at(0)["memo"] = randomHashafter1.toStdString(); - dust.at(1)["memo"] = randomHashafter2.toStdString(); - dust.at(2)["memo"] = randomHashafter3.toStdString(); - dust.at(3)["memo"] = randomHashafter4.toStdString(); - dust.at(4)["memo"] = randomHashafter5.toStdString(); - dust.at(5)["memo"] = randomHashafter6.toStdString(); - // For each addr/amt/memo, construct the JSON and also build the confirm dialog box for (int i=0; i < tx.toAddrs.size(); i++) From 92e20e1c98ce6f4035614e267b4ac130c1aac128 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 10 Jun 2020 17:07:45 +0200 Subject: [PATCH 245/253] rename old addrbook to .bak and create a new one #109 --- src/addressbook.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 11dc0c4..e2f481d 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -398,7 +398,16 @@ void AddressBook::readFromStorage() QList> stuff; in >> stuff; - + //////////////found old addrbook, and rename it to .bak + if (version != "v2") + { + auto filename = QStringLiteral("addresslabels.dat"); + auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + QFile address(dir.filePath(filename)); + + address.rename(dir.filePath("addresslabels.bak")); + + }else{ for (int i=0; i < stuff.size(); i++) { @@ -406,6 +415,7 @@ void AddressBook::readFromStorage() allLabels.push_back(contact); } + } // qDebug() << "Read " << version << " Hush contacts from disk..."; @@ -448,7 +458,7 @@ void AddressBook::writeToStorage() c.push_back(item.getAvatar()); contacts.push_back(c); } - out << QString("v1") << contacts; + out << QString("v2") << contacts; file.close(); } From 94340842a9e486e1b2d657ea070fe48af5211204 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 10 Jun 2020 21:59:25 +0200 Subject: [PATCH 246/253] add funds button #104 --- src/deposithush.ui | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/deposithush.ui diff --git a/src/deposithush.ui b/src/deposithush.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/src/deposithush.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From 2b907a20d46599b678b4d80dcce2b48cb1d8f8d6 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 10 Jun 2020 21:59:32 +0200 Subject: [PATCH 247/253] add funds button #104 --- silentdragon-lite.pro | 2 + src/deposithush.ui | 130 ++++++++++++----- src/mainwindow.cpp | 31 ++++ src/mainwindow.ui | 323 +++++++++++++++++++++--------------------- 4 files changed, 291 insertions(+), 195 deletions(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 90b261b..57144f4 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -121,6 +121,7 @@ HEADERS += \ FORMS += \ src/contactrequest.ui \ + src/deposithush.ui \ src/encryption.ui \ src/hushrequest.ui \ src/mainwindow.ui \ @@ -147,6 +148,7 @@ FORMS += \ src/removeencryption.ui \ src/recurringmultiple.ui \ src/chatbubbleme.ui \ + src/deposithush.ui \ src/chatbubblepartner.ui diff --git a/src/deposithush.ui b/src/deposithush.ui index fb923db..6ac7e71 100644 --- a/src/deposithush.ui +++ b/src/deposithush.ui @@ -1,51 +1,112 @@ - - - - - Dialog - - + + + deposithush + + 0 0 - 400 - 300 + 792 + 650 - - Dialog + + Deposit Hush - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + + 16777215 + 71 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + + + Hush zaddr + + + + + + + Copy Address + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + 0 + 0 + + + + background-color: #fff + + + + + + + - + + + QRCodeLabel + QLabel +
qrcodelabel.h
+
+
buttonBox accepted() - Dialog + deposithush accept() - + 248 254 - + 157 274 @@ -54,14 +115,14 @@ buttonBox rejected() - Dialog + deposithush reject() - + 316 260 - + 286 274 @@ -69,4 +130,3 @@
- diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 441126e..4f278e7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -18,6 +18,7 @@ #include "version.h" #include "connection.h" #include "ui_contactrequest.h" +#include "ui_deposithush.h" #include "ui_requestContactDialog.h" #include "chatmodel.h" #include "requestdialog.h" @@ -1158,6 +1159,36 @@ void MainWindow::setupBalancesTab() { ui->unconfirmedWarning->setVisible(false); ui->lblSyncWarning->setVisible(false); ui->lblSyncWarningReceive->setVisible(false); + QObject::connect(ui->depositHushButton, &QPushButton::clicked, [=](){ + + Ui_deposithush deposithush; + QDialog dialog(this); + deposithush.setupUi(&dialog); + Settings::saveRestore(&dialog); + + QList allAddresses; + + allAddresses = getRPC()->getModel()->getAllZAddresses(); + QString depositzaddr = allAddresses[1]; + deposithush.qrcodeDisplayDeposit->setQrcodeString(depositzaddr); + deposithush.zaddr->setText(depositzaddr); + + QObject::connect(deposithush.CopyAddress, &QPushButton::clicked, [=](){ + + QGuiApplication::clipboard()->setText(depositzaddr); + ui->statusBar->showMessage(tr("Copied to clipboard"), 3 * 1000); + + }); + + + + dialog.exec(); + + + + + }); + // Setup context menu on balances tab ui->balancesTable->setContextMenuPolicy(Qt::CustomContextMenu); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 2fa544c..8471227 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -59,7 +59,7 @@ - 5 + 2 @@ -84,181 +84,184 @@
- + - - - - - - 0 - 0 - - - - Shielded - - - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - Notarized - - - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - 0 - 0 - - - - Transparent - - - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Total - - - - - - - - 75 - true - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - color:red; - - - Your node is still syncing, balances may not be updated. - - - true - - - - - + 0 0 - - color: red; - - Some transactions are not yet confirmed. Balances may change. - - - true + Shielded - - - Qt::Vertical + + + - - - 20 - 40 - + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - +
+ + + + + + + 0 + 0 + + + + Notarized + + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + 0 + 0 + + + + Transparent + + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + Qt::Horizontal + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Total + + + + + + + + 75 + true + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + color:red; + + + Your node is still syncing, balances may not be updated. + + + true + + + + + + + + 0 + 0 + + + + color: red; + + + Some transactions are not yet confirmed. Balances may change. + + + true + + + + + + + Deposit Hush + + + + + + + Qt::Vertical + + + + 20 + 383 + + + +
@@ -1627,7 +1630,7 @@ false - QAbstractItemView::NoDragDrop + QAbstractItemView::DragOnly Qt::IgnoreAction From 8dba87d5b080034d746be3dd190442ab16e7e51d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Wed, 10 Jun 2020 22:04:58 +0200 Subject: [PATCH 248/253] try catch hm --- src/controller.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index b727e2c..7ce4c2d 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -965,7 +965,8 @@ void Controller::refreshTransactions() { memo = QString::fromStdString(o["memo"].get()); if (memo.startsWith("{")) { - + try + { QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); cid = headermemo["cid"].toString(); @@ -974,7 +975,12 @@ void Controller::refreshTransactions() { chatModel->addCid(txid, cid); chatModel->addHeader(txid, headerbytes); - } + } catch(...) + + { + + } + } bool isNotarized; @@ -1191,7 +1197,8 @@ void Controller::refreshTransactions() { if (!it["memo"].is_null()) { if (memo.startsWith("{")) { - + try + { QJsonDocument headermemo = QJsonDocument::fromJson(memo.toUtf8()); cid = headermemo["cid"].toString(); @@ -1208,6 +1215,10 @@ void Controller::refreshTransactions() { main->addPubkey(requestZaddr, publickey); } + } catch(...) + { + + } } if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ From c6f170a97d34a2e87b79975f64b1d336a92a06b8 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:22:18 +0200 Subject: [PATCH 249/253] change version, disable request Hush --- src/mainwindow.cpp | 4 ++-- src/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4f278e7..338c8b2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1531,7 +1531,7 @@ void MainWindow::setupchatTab() { ui->listContactWidget->addAction(requestHushAction); ui->listContactWidget->addAction(subatomicAction); - QObject::connect(requestHushAction, &QAction::triggered, [=]() { + /*QObject::connect(requestHushAction, &QAction::triggered, [=]() { QModelIndex index = ui->listContactWidget->currentIndex(); QString label_contact = index.data(Qt::DisplayRole).toString(); @@ -1543,7 +1543,7 @@ void MainWindow::setupchatTab() { } MainWindow::showRequesthush(); - }); + }); */ QObject::connect(editAction, &QAction::triggered, [=]() { QModelIndex index = ui->listContactWidget->currentIndex(); diff --git a/src/version.h b/src/version.h index 875d8ab..0b92eaa 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define APP_VERSION "1.3-Chat-Alpha" +#define APP_VERSION "1.3.2-Chat-Beta" From cf5f71b67bc6d5d3132f784a9aa28111fe7fb3c8 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 11 Jun 2020 10:38:21 +0200 Subject: [PATCH 250/253] delete double ui --- silentdragon-lite.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index 57144f4..428efdc 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -148,7 +148,6 @@ FORMS += \ src/removeencryption.ui \ src/recurringmultiple.ui \ src/chatbubbleme.ui \ - src/deposithush.ui \ src/chatbubblepartner.ui From 971dd9ee60d7fe1285460ed476cdd29ce6078c28 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 11 Jun 2020 16:39:19 +0200 Subject: [PATCH 251/253] switch to MyHush repo for sdl lib --- lib/Cargo.lock | 6 +++--- lib/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index d1c7722..3c5dbf4 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1177,7 +1177,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)", + "silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)", ] [[package]] @@ -1640,7 +1640,7 @@ dependencies = [ [[package]] name = "silentdragonlitelib" version = "0.1.0" -source = "git+https://github.com/DenioD/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0#d2887d07879a93bdd9b2c8bd12504bb977e82fe0" +source = "git+https://github.com/MyHush/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0#d2887d07879a93bdd9b2c8bd12504bb977e82fe0" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/MyHush/librustzcash.git?rev=1a0204113d487cdaaf183c2967010e5214ff9e37)", @@ -2631,7 +2631,7 @@ dependencies = [ "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"checksum silentdragonlitelib 0.1.0 (git+https://github.com/DenioD/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)" = "" +"checksum silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=d2887d07879a93bdd9b2c8bd12504bb977e82fe0)" = "" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index d46b55f..39a70e9 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -silentdragonlitelib = { git = "https://github.com/DenioD/silentdragonlite-cli", rev = "d2887d07879a93bdd9b2c8bd12504bb977e82fe0" } +silentdragonlitelib = { git = "https://github.com/MyHush/silentdragonlite-cli", rev = "d2887d07879a93bdd9b2c8bd12504bb977e82fe0" } From bd0c5f4bfeb466daca17c9878b1d5eaec899710d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 11 Jun 2020 16:48:10 +0200 Subject: [PATCH 252/253] add arabic, update ts files with new hushchat translations --- application.qrc | 1 + res/silentdragonlite_ar.qm | Bin 0 -> 23614 bytes res/silentdragonlite_ar.ts | 2651 ++++++++++++++++++++++++++++++++++++ res/silentdragonlite_de.qm | Bin 43364 -> 43459 bytes res/silentdragonlite_de.ts | 1498 +++++++++++++++----- res/silentdragonlite_es.ts | 1507 +++++++++++++++----- res/silentdragonlite_fa.ts | 1503 +++++++++++++++----- res/silentdragonlite_fr.ts | 1504 +++++++++++++++----- res/silentdragonlite_hr.ts | 1502 +++++++++++++++----- res/silentdragonlite_it.ts | 1494 ++++++++++++++------ res/silentdragonlite_pt.ts | 1519 ++++++++++++++++----- res/silentdragonlite_sr.ts | 1502 +++++++++++++++----- res/silentdragonlite_tr.ts | 1496 ++++++++++++++------ res/silentdragonlite_zh.ts | 1486 ++++++++++++++------ 14 files changed, 14077 insertions(+), 3586 deletions(-) create mode 100644 res/silentdragonlite_ar.qm create mode 100644 res/silentdragonlite_ar.ts diff --git a/application.qrc b/application.qrc index e6c1b2d..4c5ae9c 100644 --- a/application.qrc +++ b/application.qrc @@ -66,6 +66,7 @@ res/silentdragonlite_hr.qm res/silentdragonlite_fa.qm res/silentdragonlite_id.qm + res/silentdragonlite_ar.qm
res/css/Blue.css diff --git a/res/silentdragonlite_ar.qm b/res/silentdragonlite_ar.qm new file mode 100644 index 0000000000000000000000000000000000000000..cc809ec63da02bc769858fca540d2bd75169c42b GIT binary patch literal 23614 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 literal 0 HcmV?d00001 diff --git a/res/silentdragonlite_ar.ts b/res/silentdragonlite_ar.ts new file mode 100644 index 0000000..1590186 --- /dev/null +++ b/res/silentdragonlite_ar.ts @@ -0,0 +1,2651 @@ + + + + + AddressBookModel + + + Label + + + + + Address + + + + + Avatar + + + + + HushChatAddress + + + + + CID + + + + + BalancesTableModel + + + Address + + + + + Amount + + + + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + + + + + ConnectionDialog + + + SilentDragonLite + + + + + The Dragon Awakens... + + + + + Controller + + + Wallet Password + + + + + Your wallet is encrypted. +Please enter your wallet password + + + + + + Wallet Decryption Failed + + + + + Please enter a valid password + + + + + Failed to unlock wallet + + + + + CreateWalletForm + + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + + Restore wallet from seed + + + + + Restore an existing wallet, using the 24-word seed. + + + + + Create a new wallet + + + + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Create a new wallet with a randomly generated seed. + + + + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + + + + + Add a memo to your request + + + + + Cancel + + + + + Add Contact and Send Request + + + + + MainWindow + + + SilentDragonLite + + + + + Balance + + + + + Summary + + + + + Shielded + + + + + Notarized + + + + + Transparent + + + + + Total + + + + + Your node is still syncing, balances may not be updated. + + + + + Some transactions are not yet confirmed. Balances may change. + + + + + Address Balances + + + + + + Send + + + + + Total notarized funds available: + + + + + Send To + + + + + Recipient + + + + + + + + + Address + + + + + + Address Book + + + + + + + + Amount + + + + + Max Available + + + + + + + + Memo + + + + + Add Recipient + + + + + + Miner Fee + + + + + 0 + + + + + Cancel + + + + + Receive + + + + + Address Type + + + + + z-Addr + + + + + t-Addr + + + + + Next Address + + + + + Information about Hush + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> + + + + + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> + + + + + Next Halving + + + + + Difficulty + + + + + Last Notarized Block + + + + + Total Supply + + + + + Longestchain + + + + + BlockHeight + + + + + Supply zAddr + + + + + Supply tAddr + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> + + + + + Market Cap + + + + + Volume on Exchanges + + + + + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> + + + + + View All Addresses + + + + + Label + + + + + Update Label + + + + + Address balance + + + + + Optional + + + + + + Export Private Key + + + + + Your node is still syncing, balances may not be updated + + + + + Transactions + + + + + + + + + + + + + + + + Loading... + + + + + Version hushlightd + + + + + Vendor + + + + + Deposit Hush + + + + + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + + &File + + + + + &Help + + + + + &Apps + + + + + &Edit + + + + + E&xit + + + + + &About + + + + + &Settings + + + + + Ctrl+P + + + + + &Send DenioD Feedback + + + + + &Hush Discord + + + + + &Hush Website + + + + + Check github.com for &updates + + + + + &Export all private keys + + + + + Address &book + + + + + Ctrl+B + + + + + &Export seed phrase + + + + + + Export transactions + + + + + Pay hush &URI... + + + + + Connect mobile &app + + + + + Ctrl+M + + + + + &Recurring Payments + + + + + Request hush... + + + + + File a bug... + + + + + Encrypt Wallet + + + + + Remove Wallet Encryption + + + + + Rescan + + + + + Passwords don't match + + + + + + Wallet Encryption Failed + + + + + Wallet is not encrypted + + + + + + Copy txid + + + + + + Copy block explorer link + + + + + View tx on block explorer + + + + + Refresh + + + + + Restart + + + + + Please restart Silentdragonlite to have the theme apply + + + + + Currency Change + + + + + Some feedback about SilentDragonlite or Hush... + + + + + This change can take a few seconds. + + + + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + + or SilentDragonLite + + + + + Send DenioD some private and shielded feedback about + + + + + Paste HUSH URI + + + + + Error paying HUSH URI + + + + + URI should be of the form 'hush:<addr>?amt=x&memo=y + + + + + Error + + + + + Error exporting transactions, file was not saved + + + + + This is your wallet seed. Please back it up carefully and safely. + + + + + + Save File + + + + + + Unable to open file + + + + + Error getting private keys + + + + + Error loading private keys: + + + + + These are all the private keys for all the addresses in your wallet + + + + + Private key for + + + + + + Copy address + + + + + + + + Copied to clipboard + + + + + Get private key + + + + + + View on block explorer + + + + + View Payment Request + + + + + View Memo + + + + + Reply to + + + + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + + Created new t-Addr + + + + + Copy Address + + + + + Address has been previously used + + + + + Address is unused + + + + + Cannot support multiple addresses + + + + + Recurring payments doesn't currently support multiple addresses + + + + + Recipient + + + + + Only z-addresses can have memos + + + + + Transaction Error + + + + + + Please wait... + + + + + Computing your transaction + + + + + + Done! + + + + + + + Recipient Address + + + + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + + is Invalid + + + + + + + Amount for address '%1' is invalid! + + + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + + + + MemoDialog + + + + Memo + + + + + Include Reply Address + + + + + MemoEdit + + + Reply to + + + + + MigrationDialog + + + Migration Turnstile + + + + + Migration History + + + + + Migrated Amount + + + + + Unmigrated Amount + + + + + Sprout -> Sapling migration enabled + + + + + If enabled, hushd will slowly migrate your Sprout shielded funds to your Sapling address. + + + + + MobileAppConnector + + + Mobile Connector App + + + + + Scan this QRCode from your silentdragon companion app to connect your phone + + + + + QR Code + + + + + Connection String + + + + + Allow connections over the internet via silentdragon wormhole + + + + + silentdragon Companion App + + + + + Disconnect + + + + + + TextLabel + + + + + Last seen: + + + + + Connection type: + + + + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + + + NewSeedForm + + + Form + + + + + This is your new wallet's seed phrase. PLEASE BACK IT UP SECURELY. + + + + + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it + + + + + NewSeedPage + + + Error creating a wallet + + + + + Failed to save wallet + + + + + Couldn't save the wallet + + + + + PrivKey + + + Private Keys + + + + + QObject + + + Pick + + + + + + + Address or Label Error + + + + + + + Address or Label cannot be empty + + + + + + + Address Format Error + + + + + + + %1 doesn't seem to be a valid hush address. + + + + + Label Error + + + + + The label '%1' already exists. Please remove the existing label. + + + + + + Added Contact + + + + + + successfully added your new contact + + + + + Import Address Book + + + + + Unable to open file + + + + + Address Book Import Done + + + + + Imported %1 new Address book entries + + + + + Copy address + + + + + Copied to clipboard + + + + + Delete label + + + + + Attempting to initialize library with + + + + + Using existing wallet. + + + + + Create/restore wallet. + + + + + + Connection Error + + + + + + + + + Transaction Error + + + + + There was an error sending the transaction. The error was: + + + + + + No Connection + + + + + + + + + Tx + + + + + + + + + failed + + + + + + + + The transaction with id + + + + + + + + failed. The error was + + + + + There was an error connecting to the server. Please check your internet connection. The error was + + + + + Update Available + + + + + A new release v%1 is available! You have v%2. + +Would you like to visit the releases page? + + + + + No updates available + + + + + You already have the latest release v%1 + + + + + + Please wait for SilentDragonLite to exit + + + + + + Waiting for hushd to exit + + + + + No hush price was available to convert from USD + + + + + View on block explorer + + + + + View Error + + + + + Reported Error + + + + + + Are you sure you want to delete the recurring payment? + + + + + All future payments will be cancelled. + + + + + Tx submitted (right click to copy) txid: + + + + + Type + + + + + Address + + + + + Date/Time + + + + + Confirmations + + + + + Amount + + + + + Connected directly + + + + + Connected over the internet via silentdragon wormhole service + + + + + + Node is still syncing. + + + + + + No sapling or transparent addresses with enough balance to spend. + + + + + RecurringDialog + + + Reccuring Dialog + + + + + View + + + + + Delete + + + + + RecurringListViewModel + + + Amount + + + + + Schedule + + + + + Payments Left + + + + + Next Payment + + + + + To + + + + + Every + + + + + None + + + + + RecurringPayments + + + Reocurring Payments + + + + + RecurringPaymentsListViewModel + + + Date + + + + + Status + + + + + Txid + + + + + Not due yet + + + + + Pending + + + + + Skipped + + + + + Paid + + + + + Error + + + + + + Unknown + + + + + RecurringPending + + + Recurring Multiple Payments + + + + + No payments will be processed. You can manually pay them from the Recurring Payments Dialog box + + + + + Schedule + + + + + How should silentdragon proceed? + + + + + Pay All in 1 Tx + + + + + Only the latest pending payment will be processed. All previous pending payments will be skipped + + + + + Pay Latest Only + + + + + Pay None + + + + + All pending payments collected, added up and paid in a single transaction + + + + + Description + + + + + To + + + + + The following recurring payment has multiple payments pending + + + + + RequestDialog + + + Payment Request + + + + + AddressBook + + + + + Request From + + + + + My Address + + + + + Amount in + + + + + z address + + + + + Amount + + + + + The recipient will see this address in the "to" field when they pay your request. + + + + + Amount USD + + + + + Memo + + + + + TextLabel + + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + + + + + Error paying hush URI + + + + + URI should be of the form 'hush:<addr>?amt=x&memo=y + + + + + Pay To + + + + + Pay + + + + + You are paying a payment request. Your address will not be visible to the person requesting this payment. + + + + + Can only request from Sapling addresses + + + + + RestoreSeedForm + + + Restore Wallet Seed + + + + + Please enter your 24-word seed below + + + + + Wallet Seed + + + + + Wallet Birthday + + + + + 0 + + + + + Wallet birthday is the block height at which the wallet had the first transaction. If you don't know this, you can leave it as "0" (It'll take longer to rescan) + + + + + RestoreSeedPage + + + + Failed to restore wallet + + + + + SilentDragonLite needs 24 words to restore wallet + + + + + Failed to parse wallet birthday + + + + + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. + + + + + Couldn't restore the wallet + + + + + Failed to save wallet + + + + + Couldn't save the wallet + + + + + Settings + + + Settings + + + + + Connection + + + + + Lightwallet Server + + + + + Options + + + + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + + Fetch hush prices + + + + + Check github for updates at startup + + + + + Connect to github on startup to check for updates + + + + + Theme + + + + + Connect to the internet to fetch hush prices + + + + + Currency + + + + + AUD + + + + + BTC + + + + + CAD + + + + + CHF + + + + + CNY + + + + + EUR + + + + + GBP + + + + + INR + + + + + RUB + + + + + USD + + + + + ViewAddressesDialog + + + All Addresses + + + + + Export All Keys + + + + + ViewAllAddressesModel + + + Address + + + + + Balance (%1) + + + + + about + + + About + + + + + addressBook + + + Address Book + + + + + Add New Address + + + + + Address (z-Addr or t-Addr) + + + + + <html><head/><body><p>Nickname :</p></body></html> + + + + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + + Add to Address Book + + + + + Import Address Book + + + + + confirm + + + Confirm Transaction + + + + + To + + + + + Recurring Payment + + + + + TextLabel + + + + + You are sending a transaction while your node is still syncing. This may not work. + + + + + createhushConf + + + Configure hush.conf + + + + + Your hush node will be configured for you automatically + + + + + Show Advanced Configuration + + + + + Allow connections to the internet to check for updates, get hush prices etc... + + + + + Use custom datadir + + + + + Choose directory + + + + + Please note that you'll need to already have a Tor service configured on port 9050 + + + + + Connect to the internet for updates and price feeds + + + + + Please choose a directory to store your wallet.dat and blockchain + + + + + Connect over Tor + + + + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + + + + + encryptionDialog + + + Encrypt Your Wallet + + + + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + hushrequest + + + Request Payment + + + + + TextLabel + + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + + + + + Request From + + + + + zaddr + + + + + Amount in + + + + + Amount + + + + + Amount USD + + + + + Memo + + + + + My Address + + + + + The recipient will see this address in the "to" field when they pay your request. + + + + + newRecurringDialog + + + Edit Schedule + + + + + Payment Description + + + + + Schedule + + + + + Next Payment + + + + + Amount + + + + + Memo + + + + + To + + + + + From + + + + + Number of payments + + + + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + + diff --git a/res/silentdragonlite_de.qm b/res/silentdragonlite_de.qm index 1c109628b9f49f9920737f9ce18a3e80c1c15029..3fbb62f016ac59f4c6f031d29971bbce09d46264 100644 GIT binary patch delta 2949 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 AddressBookModel - + Label Adressbuch - + Address Adresse + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel @@ -27,6 +42,42 @@ Betrag + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + + + ConnectionDialog @@ -34,42 +85,46 @@ SilentDragonLite - + SilentDragonLite SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - Starte + Starte Controller - + Wallet Password Wallet Passwort - + Your wallet is encrypted. Please enter your wallet password Ihr Wallet ist verschlüsselt. Bitte geben Sie das Passwort ein - - + + Wallet Decryption Failed Entschlüsslung gescheitert - + Please enter a valid password Bitte geben Sie ein gültiges Passwort ein - + Failed to unlock wallet Konnte das Wallet nicht entsperren @@ -77,31 +132,187 @@ Please enter your wallet password CreateWalletForm - Form - Neues Wallet erstellen + Neues Wallet erstellen - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed Wallet mit dem Seed wiederherstellen - + Restore an existing wallet, using the 24-word seed. Der Seed benötigt 24 Wörter um das Wallet mit dem Seed wiederherzustellen. - - Create a new Wallet - Wallet neu erstellen + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + Wallet neu erstellen + + + Create a new wallet with a randomly generated seed. Neues Wallet mit einem zufälligen Seed erstellen. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + + + + + Add a memo to your request + + + + + Cancel + Abbrechen + + + + Add Contact and Send Request + + + MainWindow @@ -109,52 +320,52 @@ Please enter your wallet password SilentDragonLite - + Balance Guthaben - + Summary Zusammenfassung - + Shielded Verborgen - + Notarized Notarisiert - + Transparent Sichtbar - + Total Gesamt - + Your node is still syncing, balances may not be updated. Synchronisierung noch nicht abgeschlossen. Beträge sind noch nicht aktuell. - + Some transactions are not yet confirmed. Balances may change. Einige Transaktionen sind noch nicht bestätigt. - + Total notarized funds available: Insgesammter notarisierter Betrag: - + Your node is still syncing, balances may not be updated Synchronisierung noch nicht abgeschlossen. Beträge sind noch nicht aktuell @@ -163,13 +374,13 @@ Please enter your wallet password Einige Transaktionen sind noch nicht bestätigt - + Address Balances Guthaben der Adresse - - + + Send Senden @@ -178,104 +389,101 @@ Please enter your wallet password Guthaben der Adresse - + Send To Sende an - + Recipient Empfänger - - - + + + Address Adresse - + Address Book Adressbuch - - + + Amount Betrag - + Max Available Maximal verfügbare Summe - - - + + + Memo Nachricht - + Add Recipient Weiteren Empfänger hinzufügen - Recurring payment - Wiederkehrende Zahlung + Wiederkehrende Zahlung - Every month, starting 12-May-2012, for 6 payments - Jeden Monat, startet am 12. Mai 2019, für 6 Monate + Jeden Monat, startet am 12. Mai 2019, für 6 Monate - Edit Schedule - Zeitplan bearbeiten + Zeitplan bearbeiten - + Miner Fee Gebühr - + 0 - + Cancel Abbrechen - + Receive Empfangen - + Address Type Adressen Format - + z-Addr Verborgene Adresse - + t-Addr Sichtbare Adresse @@ -284,38 +492,38 @@ Please enter your wallet password Neue Adresse - + View All Addresses Alle Adressen ansehen - + Label Bezeichnung - + Update Label Bezeichnung ändern - + Address balance Guthaben der Adresse - + Optional Optional - - + + Export Private Key Private Key exportieren - + Transactions Transaktionen @@ -328,32 +536,32 @@ Please enter your wallet password Blockhöhe - + Version hushlightd Hushdlight Version - + &Send DenioD Feedback Sende DenioD Feedback - + &Export seed phrase Seed exportieren - + Encrypt Wallet Wallet verschlüsseln - + Remove Wallet Encryption Verschlüsslung entfernen - + Rescan Neu Scannen @@ -362,23 +570,23 @@ Please enter your wallet password Dies ist ein Lightwallet, sie können damit nicht Minen! - + SilentDragonLite SilentDragonLite - - - - - - - - - - - - + + + + + + + + + + + + Loading... Lade... @@ -391,230 +599,275 @@ Please enter your wallet password Version hushd light - + Vendor Vendor - + Next Address Nächste Adresse - + + Deposit Hush + + + + Information about Hush Informationen über Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Informationen</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving Nächstes Block Halving - + Difficulty Difficulty - + Last Notarized Block Letzter notarisierter Block - + Total Supply Gesamt Coins im Netzwerk - + Longestchain Längste Chain - + BlockHeight Blockhöhe - + Supply zAddr Verborgene Coins im Netzwerk - + Supply tAddr Transparente Coins im Netzwerk - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Markt Informationen</span></p></body></html> - + Market Cap Marktkapitalisierung - + Volume on Exchanges Volumen auf allen Börsen - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> <html><head/><body><p align="center">Dies ist ein Lightwallet. Sie können damit nicht Minen!!!</p></body></html> + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &File Datei - + &Help Hilfe - + &Apps Smartphone - + &Edit Bearbeiten - + E&xit Beenden - + &About Über - + &Settings Einstellungen - + Ctrl+P Ctrl+P - + &Hush Discord &Hush Discord - + &Hush Website &Hush Website - + Check github.com for &updates Überprüfe Github für Updates - + &Export all private keys Alle private Keys exportieren - + Address &book Adressbuch - + Ctrl+B Ctrl+B - - + + Export transactions Transaktionen exportieren - + Pay hush &URI... Zahlungs Hush &URI... - + Connect mobile &app Smartphone verbinden - + Ctrl+M Ctrl+M - + &Recurring Payments Wiederkehrende Zahlung - + Request hush... Hush anfordern... - + File a bug... Fehler melden... - - + + Copy txid Transaktions ID kopieren - + View tx on block explorer Transaktions ID auf dem Blockexplorer anschauen - + Refresh Aktualisieren - + Restart Neustart - + Please restart Silentdragonlite to have the theme apply Bitte starten sie SilentDragonLite neu @@ -623,7 +876,7 @@ Please enter your wallet password Starte SilentDragonLite neu - + Some feedback about SilentDragonlite or Hush... Etwas Feedback über SilentDragonLite... @@ -632,160 +885,146 @@ Please enter your wallet password Sende DenioD anonym Feedback über - + or SilentDragonLite oder SilentDragonLite - + Send DenioD some private and shielded feedback about Sende DenioD anonym Feedback über - + Paste HUSH URI Hush URI einfügen - + Error paying HUSH URI Fehler bei HUSH URI - + URI should be of the form 'hush:<addr>?amt=x&memo=y Die URI sollte folgendemaßen aussehen 'hush:<addr>?amt=x&memo=y - + Error Fehler - + Error exporting transactions, file was not saved Fehler beim exportieren der Transaktionen. Die Datei wurde nicht gespeichert - + Error getting private keys Fehler beim empfangen der private Keys - + Error loading private keys: Fehler beim laden der private Keys: - + These are all the private keys for all the addresses in your wallet Dies sind alle private Keys für ihr Wallet - + Private key for Private Key für - - + + Save File Datei sichern - Wallet is already encrypted - SilentDragonLite ist bereits verschlüsselt + SilentDragonLite ist bereits verschlüsselt - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - SilentDragonLite ist bereits mit einem Passwort verschlüsselt. Bitte benutzen Sie die Funktion 'Verschlüsselung entfernen'. + SilentDragonLite ist bereits mit einem Passwort verschlüsselt. Bitte benutzen Sie die Funktion 'Verschlüsselung entfernen'. - + Passwords don't match Passwort falsch - Error was: - Der Fehler war: + Der Fehler war: - Wallet Encrypted - SilentDragonLite verschlüsselt + SilentDragonLite verschlüsselt - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - SilentDragonLite wurde erfolgreich verschlüsselt. Sie benötigen Ihr Passwort um Zahlungen zu senden oder Ihre private Keys zu exportieren. + SilentDragonLite wurde erfolgreich verschlüsselt. Sie benötigen Ihr Passwort um Zahlungen zu senden oder Ihre private Keys zu exportieren. - - + + Wallet Encryption Failed Verschlüsslung gescheitert - + Wallet is not encrypted SilentDragonLite ist nicht verschlüsselt - Your wallet is not encrypted with a password. - SilentDragonLite ist nicht mit einem Passwort verschlüsselt. + SilentDragonLite ist nicht mit einem Passwort verschlüsselt. - Wallet Password - SilentDragonLite Passwort + SilentDragonLite Passwort - Please enter your wallet password - Bitte geben sie Ihr Passwort ein + Bitte geben sie Ihr Passwort ein - - - Wallet Decryption Failed - SilentDragonLite konnte nicht entschlüsselt werden + SilentDragonLite konnte nicht entschlüsselt werden - Please enter a password to decrypt your wallet! - Bitte geben Sie das Passwort ein, um SilentDragonLite zu entschlüsseln! + Bitte geben Sie das Passwort ein, um SilentDragonLite zu entschlüsseln! - Wallet Encryption Removed - Verschlüsselung wurde entfernt + Verschlüsselung wurde entfernt - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - SilentDragonLite wurde erfolgreich entschlüsselt. Sie benötigen Ihr Passwort nicht mehr. + SilentDragonLite wurde erfolgreich entschlüsselt. Sie benötigen Ihr Passwort nicht mehr. - - + + Copy block explorer link Blockexplorer Link kopieren - + Currency Change Währungszeichen wechseln - + This change can take a few seconds. Die übernahme der Änderung kann ein paar sekunden dauern. @@ -794,72 +1033,104 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Bitte starten sie SilentDragonLite neu - + This is your wallet seed. Please back it up carefully and safely. Dies ist Ihr SilentDragonLite Seed. Bitte sichern Sie ihn sorgfältig. - - + + Unable to open file Konnte die Datei nicht öffnen - - + + Copy address Adresse kopieren - - - + + + + Copied to clipboard In die Zwischenablage kopiert - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key Private Key erhalten - - + + View on block explorer Auf dem Blockexplorer anschauen - + View Payment Request Zahlungsanforderung ansehen - + View Memo Nachricht ansehen - + Reply to Antworten an - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Neue sichtbare Adresse erstellen - + Copy Address Adresse kopieren - + Address has been previously used Diese Adresse wurde schon einmal benutzt - + Address is unused Adresse ist unbenutzt @@ -884,48 +1155,46 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Nur verborgene Adressen können Nachrichten enthalten - Memos can only be used with z-addresses - Nur verborgene Adressen können Nachrichten enthalten + Nur verborgene Adressen können Nachrichten enthalten - The memo field can only be used with a z-address. - Nur verborgene Adressen können Nachrichten enthalten. + Nur verborgene Adressen können Nachrichten enthalten. - doesn't look like a z-address - + sieht nicht nach einer verborgenen Adresse aus (Zs...) - + + Please wait... Bitte warten... - + Computing your transaction Generiere Ihre Transaktion - + + Done! Fertig! - Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - Nicht genügend Guthaben für die Transaktion verfügbar. + Nicht genügend Guthaben für die Transaktion verfügbar. Sie haben:%1 Sie benötigen:%2 @@ -938,20 +1207,107 @@ Anmerkung: Sie bnötigen 2 Bestätigungen Fehler bei der Transaktion - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address Adresse des Empfängers - + + + is Invalid ist ungültig - + + + Amount for address '%1' is invalid! Betrag für die Adresse '%1' ist nicht gültig! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + Nicht genügend Guthaben für die Transaktion verfügbar. + +Sie haben:%1 +Sie benötigen:%2 + +Anmerkung: Sie bnötigen 2 Bestätigungen {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + MemoDialog @@ -1011,9 +1367,13 @@ Anmerkung: Sie bnötigen 2 Bestätigungen MobileAppConnector - Connect Mobile App - Smartphone verbinden + Smartphone verbinden + + + + Mobile Connector App + @@ -1062,6 +1422,14 @@ Anmerkung: Sie bnötigen 2 Bestätigungen Verbindungstyp: + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1075,7 +1443,7 @@ Anmerkung: Sie bnötigen 2 Bestätigungen Dies ist Ihr SilentDragonLite Seed. Bitte sichern Sie ihn sorgfältig. - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it Der Seed ist die einzige Möglichkeit ihr Guthaben wiederherzustellen. Ohne diesen Seed ist Ihr Guthaben für immer verloren @@ -1083,17 +1451,17 @@ Anmerkung: Sie bnötigen 2 Bestätigungen NewSeedPage - + Error creating a wallet Fehler beim erstellen des Wallets - + Failed to save wallet Konnte wallet.dat nicht speichern - + Couldn't save the wallet Konnte wallet.dat nicht speichern @@ -1109,152 +1477,186 @@ Anmerkung: Sie bnötigen 2 Bestätigungen QObject - + Pick Wählen - + + + Address or Label Error Die Adresse oder die Bezeichnung gab einen Fehler - + + + Address or Label cannot be empty Adresse oder Bezeichnung dürfen nicht leer sein - + + + Address Format Error Adressen Format war falsch - + + + %1 doesn't seem to be a valid hush address. %1 das scheint keine gültige Hush Adresse zu sein. - + Label Error Bezeichnungs Fehler - + The label '%1' already exists. Please remove the existing label. Die Bezeichnung ´'%1' existiert bereits. Bitte verwenden Sie eine andere Bezeichnung. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Importiere das Adressbuch - + Unable to open file Kann die Datei nicht öffnen - + Address Book Import Done Importieren des Adressbuchs beendet - + Imported %1 new Address book entries Habe %1 neue Adressen importiert - + Copy address Kopiere Adresse - + Copied to clipboard In die Zwischenablage kopiert - + Delete label Lösche Beschriftung - + Attempting to initialize library with Versuche die Bibliothek zu starten mit - + Using existing wallet. Benutze existierendes Wallet. - + Create/restore wallet. Wallet neu erstellen oder wiederherstellen. - - + + Connection Error Verbsindungsfehler - - - + + + + + Transaction Error Transaktionsfehler - + There was an error sending the transaction. The error was: Es gab einen Fehler beim senden der Transaktion: - - + + No Connection keine Verbindung - There was an error connecting to hushd. The error was - Es gab einen Fehler zum server zu verbinden + Es gab einen Fehler zum server zu verbinden - + + + - + Tx Transaktion - + + + - + failed gescheitert - - + + + + The transaction with id Die Transaktion mit der ID - - + + + + failed. The error was ist gescheitert - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available Update verfügbar - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1263,22 +1665,24 @@ Would you like to visit the releases page? Möchten Sie die Release Seite besuchen? - + No updates available keine Updates verfügbar - + You already have the latest release v%1 Sie haben bereits die neueste Version v%1 - + + Please wait for SilentDragonLite to exit Bitte warten Sie bis SilentDragonLite beendet ist - + + Waiting for hushd to exit Warten auf beendigung der Serververbindung @@ -1314,7 +1718,7 @@ Möchten Sie die Release Seite besuchen? Alle geplanten zukünftigen Zahlungen werden nicht durchgeführt. - + Tx submitted (right click to copy) txid: Transaktions ID übermittelt (Rechtsklick zum anschauen) : @@ -1369,9 +1773,13 @@ Möchten Sie die Release Seite besuchen? RecurringDialog - Dialog - Wiederkehrende Zahlungen + Wiederkehrende Zahlungen + + + + Reccuring Dialog + @@ -1425,9 +1833,13 @@ Möchten Sie die Release Seite besuchen? RecurringPayments - Payments - Zahlungen + Zahlungen + + + + Reocurring Payments + @@ -1482,9 +1894,13 @@ Möchten Sie die Release Seite besuchen? RecurringPending - Dialog - Wiederkehrende Zahlungen + Wiederkehrende Zahlungen + + + + Recurring Multiple Payments + @@ -1550,57 +1966,57 @@ Möchten Sie die Release Seite besuchen? Zahlungsanfrage - + AddressBook Adressbuch - + Request From Anfrage von - + My Address Meine Adresse - + Amount in Betrag in - + z address verborgende Adresse - + Amount Betrag - + The recipient will see this address in the "to" field when they pay your request. Bei Bezahlung ist deine Adresse in dem "Empfänger" Feld sichtbar. - + Amount USD Betrag USD - + Memo Nachricht - + TextLabel Bezeichnung - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Bezahlung über eine sichere Adresse anfordern. Sende 0.0001 HUSH an die Adresse der Zahlungsanfrage, mit einer HUSH bezahl URI. Die Nachricht wird zur Transaktion hinzugefügt, sobald bezahlt wird. @@ -1638,9 +2054,13 @@ Möchten Sie die Release Seite besuchen? RestoreSeedForm - Form - Wallet wiederherstellen + Wallet wiederherstellen + + + + Restore Wallet Seed + @@ -1671,38 +2091,38 @@ Möchten Sie die Release Seite besuchen? RestoreSeedPage - - + + Failed to restore wallet Konnte das Wallet nicht wiederherstellen - + SilentDragonLite needs 24 words to restore wallet Der Seed benötigt 24 Wörter um das Wallet mit dem Seed wiederherzustellen - + Failed to parse wallet birthday Konnte das Erstellungsdatum nicht bestätigen - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. Das Erstellungsdatum ist die Blockhöhe bei der das Wallet erstellt wurde. Wenn Sie dies nicht mehr wissen tragen sie einfach "0" ein. - + Couldn't restore the wallet Konnte Wallet nicht wiederherstellen - + Failed to save wallet Konnte wallet.dat nicht speichern - + Couldn't save the wallet Konnte wallet.dat nicht speichern @@ -1710,32 +2130,57 @@ Möchten Sie die Release Seite besuchen? Settings - + Settings Einstellungen - + Lightwallet Server Lightwallet Server - + Options Optionen - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Connect to github on startup to check for updates Überprüfe Github für Updates - + Connect to the internet to fetch hush prices Hush Preise abrufen (dies kann Ihre Privatssphäre einschränken) - + Check github for updates at startup Überprüfe Github beim Start auf Updates @@ -1744,17 +2189,16 @@ Möchten Sie die Release Seite besuchen? Hush Preise abrufen - + Theme Design - default - default + default - + Connection Verbindung @@ -1763,77 +2207,74 @@ Möchten Sie die Release Seite besuchen? Server - blue - blue + blue - light - light + light - dark - dark + dark - + Fetch hush prices Hush Preise abrufen - + Currency Währung - + AUD - + BTC - + CAD - + CHF - + CNY - + EUR - + GBP - + INR - + RUB RUB - + USD @@ -1892,27 +2333,116 @@ Möchten Sie die Release Seite besuchen? Adressbuch - + Add New Address Neue Adresse hinzufügen - + Address (z-Addr or t-Addr) Adresse - - Label - Adressbuch + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Adressbuch + + + Add to Address Book Zum Adressbuch hinzufügen - + Import Address Book Adressbuch importieren @@ -2010,32 +2540,148 @@ Möchten Sie die Release Seite besuchen? Überspringt die meisten Checks beim Start + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Adresse kopieren + + encryptionDialog - + Encrypt Your Wallet SilentDragonLite verschlüsseln - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - Passwort: + Passwort: - Confirm Password: - Passwort bestätigen: + Passwort bestätigen: - Passwords don't match - Passwort stimmen nicht überein + Passwort stimmen nicht überein - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - Der Seed ist die einzige Möglichkeit ihr Guthaben wiederherzustellen. Ohne diesen Seed ist Ihr Guthaben für immer verloren. + Der Seed ist die einzige Möglichkeit ihr Guthaben wiederherzustellen. Ohne diesen Seed ist Ihr Guthaben für immer verloren. + + + + hushrequest + + + Request Payment + + + + + TextLabel + Bezeichnung + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Bezahlung über eine sichere Adresse anfordern. Sende 0.0001 HUSH an die Adresse der Zahlungsanfrage, mit einer HUSH bezahl URI. Die Nachricht wird zur Transaktion hinzugefügt, sobald bezahlt wird. + + + + Request From + Anfrage von + + + + zaddr + + + + + Amount in + Betrag in + + + + Amount + Betrag + + + + Amount USD + Betrag USD + + + + Memo + Nachricht + + + + My Address + Meine Adresse + + + + The recipient will see this address in the "to" field when they pay your request. + Bei Bezahlung ist deine Adresse in dem "Empfänger" Feld sichtbar. @@ -2086,4 +2732,178 @@ Möchten Sie die Release Seite besuchen? Anzahl der Zahlungen + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Abbrechen + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + diff --git a/res/silentdragonlite_es.ts b/res/silentdragonlite_es.ts index 84db05c..b2dc770 100644 --- a/res/silentdragonlite_es.ts +++ b/res/silentdragonlite_es.ts @@ -4,69 +4,124 @@ AddressBookModel - + Label Etiqueta - + Address Dirección + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Dirección - + Amount Cantidad + + ChatBubbleMe + + + Form + Formulario + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + Formulario + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog - + SilentDragonLite DragónSilenciosoLigero - + + The Dragon Awakens... + + + Starting Up - Iniciando + Iniciando Controller - + Wallet Password Contraseña de billetera - + Your wallet is encrypted. Please enter your wallet password Su billetera está encriptada. Ingrese la contraseña de su billetera - - + + Wallet Decryption Failed Error de descifrado de billetera - + Please enter a valid password Ingrese una contraseña válida - + Failed to unlock wallet Error al desbloquear la billetera @@ -74,741 +129,957 @@ Ingrese la contraseña de su billetera CreateWalletForm - Form - Formulario + Formulario - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed Restaurar billetera desde semilla - + Restore an existing wallet, using the 24-word seed. Restaurar una billetera existente, usando la semilla de 24 palabras. - - Create a new Wallet - Crear una nueva billetera + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + Crear una nueva billetera + + + Create a new wallet with a randomly generated seed. Crear una nueva billetera con una semilla generada aleatoriamente. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + Cancelar + + + + Add Contact and Send Request + + + MainWindow - + Balance Saldo - + Summary Resumen - + Shielded Blindado - + Notarized Notarizado - + Transparent Transparente - + Total Total - + Your node is still syncing, balances may not be updated. Su nodo todavía se está sincronizando, los saldos pueden no actualizarse. - + Some transactions are not yet confirmed. Balances may change. Algunas transacciones aún no están confirmadas. Los saldos pueden cambiar. - + Total notarized funds available: Total de fondos notariales disponibles: - + Next Address Siguiente dirección - + Your node is still syncing, balances may not be updated Su nodo todavía se está sincronizando, los saldos pueden no actualizarse - + Address Balances Saldos de direcciones - + SilentDragonLite DragónSilenciosoLigero - - + + Send Enviar - + Send To Enviar a - + Recipient Destinatario - - - + + + Address Dirección - + Address Book Libreta de direcciones - - + + Amount Cantidad - + Max Available Máx. disponible - - - + + + Memo Nota - + Add Recipient Agregar destinatario - Recurring payment - Pago recurrente + Pago recurrente - Every month, starting 12-May-2012, for 6 payments - Todos los meses, a partir del 12 de mayo de 2012, para 6 pagos + Todos los meses, a partir del 12 de mayo de 2012, para 6 pagos - Edit Schedule - Editar horario + Editar horario - + Miner Fee Tarifa de minero - + 0 0 - + Cancel Cancelar - + Receive Recibir - + Address Type Tipo de dirección - + z-Addr z-Direc - + t-Addr t-Direcc - + Information about Hush Información sobre Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> <html><cabeza/><cuerpo><palign="centro"><estilo Span=" peso de fuente: 600;"> Información de la cadena de bloques de Hush</span></p></cuerpo></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> <html><cabeza/><cuerpo><palign="centro">El|</p></cuerpo></html> - + Difficulty Dificultad - + Last Notarized Block Último bloque notario - + Total Supply Suministro Total - + Longestchain Cadena más larga - + View All Addresses Ver todas las direcciones - + Label Etiqueta - + Update Label Actualizar etiqueta - + Address balance Saldo de dirección - + Optional Opcional - - + + Export Private Key Exportar clave privada - + Transactions Transacciones - + Version hushlightd Versión hushlightd - + BlockHeight AlturaDelBloque - + Supply zAddr Suministro zDirecc - + Supply tAddr Suministro tDirecc - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> <html><head/><body><p align="center"><span style=" font-weight:600;">Información de mercado de Hush</span></p></body></html> - + Market Cap Capitalización de mercado - + Volume on Exchanges Volumen en intercambios - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> <html><cabeza/><cuerpo><palign="centro">Esta es una Billetera Light,¡no puedes minar con ella!</p></cuerpo></html> - + &Send DenioD Feedback Enviar comentarios de DenioD - + &Export seed phrase Exportar frase semilla - + Encrypt Wallet Encriptar billetera - + Remove Wallet Encryption Eliminar encriptado de billetera - + Rescan Volver a escanear - - - - - - - - - - - - + + + + + + + + + + + + Loading... Cargando... - + + Deposit Hush + + + + Next Halving Siguiente reducción a la mitad - + Vendor Proveedor + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &File Archivo - + &Help Ayuda - + &Apps Aplicaciones - + &Edit Editar - + E&xit E&xit - + &About Sobre - + &Settings Configuraciones - + Ctrl+P Ctrl+P - + &Hush Discord Discord de Hush - + &Hush Website Pagina web de Hush - + Check github.com for &updates Compruebe github.com para & actualizaciones - + &Export all private keys Exportar todas las claves privadas - + Address &book Libro - + Ctrl+B Ctrl+B - - + + Export transactions Transacciones de exportación - + Pay hush &URI... Paga con Hush &URI... - + Connect mobile &app Conectar móvil &Aplicación - + Ctrl+M Ctrl+M - + &Recurring Payments &Pagos recurrentes - + Request hush... Solicitar Hush… - + File a bug... Archivar un error... - - + + Copy txid Copiar txid - + View tx on block explorer Ver en el explorador de bloques - + Refresh Actualizar - + Restart Reiniciar - + Please restart Silentdragonlite to have the theme apply Reinicie Dragón silencioso ligero para que se aplique el tema - + This change can take a few seconds. Este cambio puede tardar unos segundos. - + Some feedback about SilentDragonlite or Hush... Algunos comentarios sobre Dragón silencioso ligero o Hush ... - + or SilentDragonLite o Dragón silencioso ligero - + Send DenioD some private and shielded feedback about Enviar DenioD algunos comentarios privados y protegidos sobre - + Paste HUSH URI Pegar URI HUSH - + Error paying HUSH URI Error al pagar HUSH URI - + URI should be of the form 'hush:<addr>?amt=x&memo=y URI debe tener la forma 'Hush:<Direct>?amt=x&nota=y - + Error Error - + Error exporting transactions, file was not saved Error al exportar transacciones, el archivo no se guardó - + Error getting private keys Error al obtener claves privadas - + Error loading private keys: Error al cargar claves privadas: - + These are all the private keys for all the addresses in your wallet Estas son todas las claves privadas para todas las direcciones en su billetera - + Private key for Clave privada para - - + + Save File Guardar archivo - Wallet is already encrypted - La billetera ya está encriptada + La billetera ya está encriptada - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - Su billetera ya está encriptada con una contraseña. + Su billetera ya está encriptada con una contraseña. Por favor use 'Eliminar la encriptacion de la billetera 'si desea eliminar el encriptado de billetera. - + Passwords don't match Contraseñas don't partido - Error was: - El error fue: + El error fue: - Wallet Encrypted - Billetera Encriptada + Billetera Encriptada - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - ¡Su billetera fue encriptada con éxito! La contraseña será necesaria para enviar fondos o exportar claves privadas. + ¡Su billetera fue encriptada con éxito! La contraseña será necesaria para enviar fondos o exportar claves privadas. - - + + Wallet Encryption Failed Encriptacion - + Wallet is not encrypted Error en el encriptado de billetera - Your wallet is not encrypted with a password. - Billetera no está encriptada + Billetera no está encriptada - Wallet Password - Contraseña de billetera + Contraseña de billetera - Please enter your wallet password - Por favor ingrese la contraseña de su billetera + Por favor ingrese la contraseña de su billetera - - - Wallet Decryption Failed - Error de descifrado de billetera + Error de descifrado de billetera - Please enter a password to decrypt your wallet! - ¡Ingrese una contraseña para descifrar su billetera! + ¡Ingrese una contraseña para descifrar su billetera! - Wallet Encryption Removed - Encriptacion de billetera eliminado + Encriptacion de billetera eliminado - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - ¡Su billetera fue descifrada con éxito! Ya no necesitará una contraseña para enviar fondos o exportar claves privadas. + ¡Su billetera fue descifrada con éxito! Ya no necesitará una contraseña para enviar fondos o exportar claves privadas. - - + + Copy block explorer link Copiar enlace del explorador de bloques - + Currency Change Cambio de moneda - + This is your wallet seed. Please back it up carefully and safely. Esta es la semilla de tu billetera. Haga una copia de seguridad con cuidado y seguridad. - - + + Unable to open file No se puede abrir el archivo - - + + Copy address Copiar dirección - - - + + + + Copied to clipboard Copiado al portapapeles - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key Obtener clave privada - - + + View on block explorer Ver en el explorador de bloques - + View Payment Request Ver solicitud de pago - + View Memo Ver Nota - + Reply to Responder a - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Creado nuevo t-Direcc - + Copy Address Copiar dirección - + Address has been previously used La dirección se ha utilizado previamente - + Address is unused La dirección no se utiliza @@ -833,46 +1104,44 @@ Por favor use 'Eliminar la encriptacion de la billetera 'si desea elim Solo las direcciones z pueden tener notas - Memos can only be used with z-addresses - Las notas solo se pueden usar con direcciones z + Las notas solo se pueden usar con direcciones z - The memo field can only be used with a z-address. - El campo nota solo se puede usar con una dirección z. + El campo nota solo se puede usar con una dirección z. - doesn't look like a z-address - no't parece una dirección z + no't parece una dirección z - + + Please wait... Por favor espera... - + Computing your transaction Calculando su transacción - + + Done! Listo! - Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - No hay suficientes fondos disponibles para enviar esta transacción + No hay suficientes fondos disponibles para enviar esta transacción Tener:% 1 Necesidad:% 2 @@ -884,20 +1153,106 @@ Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarseError de transacción - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address Dirección del destinatario - + + + is Invalid es inválido - + + + Amount for address '%1' is invalid! Cantidad para dirección '%1' es inválido! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + No hay suficientes fondos disponibles para enviar esta transacción +Tener:% 1 +Necesidad:% 2 + +Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarse {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + MemoDialog @@ -957,9 +1312,13 @@ Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarse MobileAppConnector - Connect Mobile App - Conectar aplicación móvil + Conectar aplicación móvil + + + + Mobile Connector App + @@ -1008,6 +1367,14 @@ Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarseTipo de conexión: + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1021,7 +1388,7 @@ Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarseEsta es su nueva billetera 's frase de semilla. POR FAVOR HAGA UNA COPIA DE SEGURIDAD. - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it La frase semilla es la única forma de restaurar la billetera. Si olvida la frase semilla, NO HAY FORMA DE RESTAURAR SU BILLETERA Y LOS FONDOS en ella @@ -1029,17 +1396,17 @@ Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarse NewSeedPage - + Error creating a wallet Error al crear una billetera - + Failed to save wallet Error al guardar la billetera - + Couldn't save the wallet Podría 't guardar la billetera @@ -1055,152 +1422,186 @@ Nota: Los fondos necesitan 5 confirmaciones antes de que puedan gastarse QObject - + Pick Elegir - + + + Address or Label Error Dirección o error de etiqueta - + + + Address or Label cannot be empty La dirección o etiqueta no puede estar vacía - + + + Address Format Error Error de formato de dirección - + + + %1 doesn't seem to be a valid hush address. >% 1 no' parece ser una dirección de Hush válida. - + Label Error Error de etiqueta - + The label '%1' already exists. Please remove the existing label. La etiqueta '%1' ya existe. Elimine la etiqueta existente. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Importar libreta de direcciones - + Unable to open file No se puede abrir el archivo - + Address Book Import Done Importación de libreta de direcciones realizada - + Imported %1 new Address book entries Importado% 1 nuevas entradas de la libreta de direcciones - + Copy address Copiar dirección - + Copied to clipboard Copiado al portapapeles - + Delete label Eliminar etiqueta - + Attempting to initialize library with Intentando inicializar la biblioteca con - + Using existing wallet. Utilizando la billetera existente. - + Create/restore wallet. Crear/restaurar billetera. - - + + Connection Error Error de conexión - - - + + + + + Transaction Error Error de transacción - + There was an error sending the transaction. The error was: Hubo un error al enviar la transacción. El error fue: - - + + No Connection Sin conexión - There was an error connecting to hushd. The error was - Hubo un error al conectarse a hushd. El error fue + Hubo un error al conectarse a hushd. El error fue - + + + - + Tx Tx - + + + - + failed falló - - + + + + The transaction with id La transacción con id - - + + + + failed. The error was falló. El error fue - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available Actualización disponible - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1209,22 +1610,24 @@ Would you like to visit the releases page? ¿Te gustaría visitar la página de lanzamientos? - + No updates available No hay actualizaciones disponibles - + You already have the latest release v%1 Ya tienes la última versión v% 1 - + + Please wait for SilentDragonLite to exit Espere a que DragónSilenciosoLigero salga - + + Waiting for hushd to exit Esperando a que hushd salga @@ -1260,7 +1663,7 @@ Would you like to visit the releases page? Todos los pagos futuros serán cancelados. - + Tx submitted (right click to copy) txid: Tx enviado (clic derecho para copiar) txid: @@ -1315,9 +1718,13 @@ Would you like to visit the releases page? RecurringDialog - Dialog - Diálogo + Diálogo + + + + Reccuring Dialog + @@ -1371,9 +1778,13 @@ Would you like to visit the releases page? RecurringPayments - Payments - Pagos + Pagos + + + + Reocurring Payments + @@ -1428,9 +1839,13 @@ Would you like to visit the releases page? RecurringPending - Dialog - Diálogo + Diálogo + + + + Recurring Multiple Payments + @@ -1496,57 +1911,57 @@ Would you like to visit the releases page? Solicitud de pago - + AddressBook Libreta de direcciones - + Request From Solicitud de - + My Address Mi dirección - + Amount in Cantidad en - + z address dirección z - + Amount Cantidad - + The recipient will see this address in the "to" field when they pay your request. El destinatario verá esta dirección en el " a " campo cuando pagan su solicitud. - + Amount USD Cantidad USD - + Memo Nota - + TextLabel Etiqueta de texto - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Solicitar pago de una dirección de Sapling. Usted ' Enviaré una transacción de silencio 0.0001 a la dirección con un URI de pago de hush. La nota se incluirá en la transacción cuando la dirección le pague. @@ -1584,9 +1999,13 @@ Would you like to visit the releases page? RestoreSeedForm - Form - Formulario + Formulario + + + + Restore Wallet Seed + @@ -1617,38 +2036,38 @@ Would you like to visit the releases page? RestoreSeedPage - - + + Failed to restore wallet Error al restaurar la billetera - + SilentDragonLite needs 24 words to restore wallet Dragón silencioso ligero necesita 24 palabras para restaurar la billetera - + Failed to parse wallet birthday Error al analizar el cumpleaños de la billetera - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. Podría ' No entiendo el cumpleaños de la billetera. Esto debe ser una altura de bloque desde donde volver a escanear la billetera. Puedes dejarlo como ' 0 ' si no lo haces ' No sé lo que debería ser. - + Couldn't restore the wallet Podría 't restaurar la billetera - + Failed to save wallet Error al guardar la billetera - + Couldn't save the wallet Podría 't guardar la billetera @@ -1656,122 +2075,131 @@ Would you like to visit the releases page? Settings - + Settings Configuración - + Lightwallet Server Billetera Servidor Light - + Options Opciones - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Connect to github on startup to check for updates Conéctese a github en el inicio para buscar actualizaciones - + Connect to the internet to fetch hush prices Conéctese a internet para obtener precios de Hush - + Check github for updates at startup Verifique github para actualizaciones al inicio - + Theme Tema - default - Predeterminado + Predeterminado - + Connection Conexión - - blue - - - - - light - - - - - dark - - - - + Fetch hush prices Ir a buscar precios de Hush - + Currency Moneda - + AUD AUD - + BTC BTC - + CAD CAD - + CHF CHF - + CNY CNY - + EUR EUR - + GBP GBP - + INR INR - + RUB RUB - + USD USD @@ -1818,27 +2246,116 @@ Would you like to visit the releases page? Libreta de direcciones - + Add New Address Agregar nueva dirección - + Address (z-Addr or t-Addr) Dirección (z-Direcc o t-Direcc) - - Label - Etiqueta + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Etiqueta + + + Add to Address Book Agregar a la libreta de direcciones - + Import Address Book Importar libreta de direcciones @@ -1924,32 +2441,148 @@ Would you like to visit the releases page? Conectar a través de Tor + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Copiar dirección + + encryptionDialog - + Encrypt Your Wallet Encriptar su billetera - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - Encriptar Contraseña: + Encriptar Contraseña: - Confirm Password: - Confirmar contraseña: + Confirmar contraseña: - Passwords don't match - Contraseñas don't no coincide + Contraseñas don't no coincide - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - ADVERTENCIA: Si olvida su contraseña, la única forma de recuperar la billetera es desde la frase inicial. + ADVERTENCIA: Si olvida su contraseña, la única forma de recuperar la billetera es desde la frase inicial. + + + + hushrequest + + + Request Payment + + + + + TextLabel + Etiqueta de texto + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Solicitar pago de una dirección de Sapling. Usted ' Enviaré una transacción de silencio 0.0001 a la dirección con un URI de pago de hush. La nota se incluirá en la transacción cuando la dirección le pague. + + + + Request From + Solicitud de + + + + zaddr + + + + + Amount in + Cantidad en + + + + Amount + Cantidad + + + + Amount USD + Cantidad USD + + + + Memo + Nota + + + + My Address + Mi dirección + + + + The recipient will see this address in the "to" field when they pay your request. + El destinatario verá esta dirección en el " a " campo cuando pagan su solicitud. @@ -2000,4 +2633,178 @@ Would you like to visit the releases page? Número de pagos + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Cancelar + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + diff --git a/res/silentdragonlite_fa.ts b/res/silentdragonlite_fa.ts index d586e8b..23398ab 100644 --- a/res/silentdragonlite_fa.ts +++ b/res/silentdragonlite_fa.ts @@ -4,68 +4,123 @@ AddressBookModel - + Label برچسب - + Address آدرس + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address آدرس - + Amount مقدار + + ChatBubbleMe + + + Form + ساخت/بازیابی کیف پول + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + ساخت/بازیابی کیف پول + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog - + SilentDragonLite سایلنت دراگون سبک - + + The Dragon Awakens... + + + Starting Up - درحال راه‌اندازی + درحال راه‌اندازی Controller - + Wallet Password رمزعبور کیف پول - + Your wallet is encrypted. Please enter your wallet password کیف پول شما رمزنگاری شده است. لطفا رمزعبور کیف پول خود را وارد کنید - - + + Wallet Decryption Failed رمزگشایی کیف پول ناموفق بود - + Please enter a valid password لطفاً رمزعبور صحیحی وارد کنید - + Failed to unlock wallet باز کردن کیف پول ناموفق بود @@ -73,284 +128,442 @@ Please enter your wallet password CreateWalletForm - Form - ساخت/بازیابی کیف پول + ساخت/بازیابی کیف پول - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed بازیابی کیف پول با عبارت بازیابی - + Restore an existing wallet, using the 24-word seed. بازیابی کیف پول موجود با عبارت بازیابی 24 کلمه ای - - Create a new Wallet - ساخت کیف پول جدید + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + ساخت کیف پول جدید + + + Create a new wallet with a randomly generated seed. ساخت کیف پول جدید با عبارت بازیابی تصادفی + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + انصراف + + + + Add Contact and Send Request + + + MainWindow - + SilentDragonLite سایلنت دراگون سبک - + Balance اعتبار - + Summary خلاصه - + Shielded حفاظت شده - + Notarized محضری - + Transparent عمومی - + Total جمع کل - + Your node is still syncing, balances may not be updated. نود شما در حال همگام سازی است، اعتبارات ممکن است بروز نباشند - + Some transactions are not yet confirmed. Balances may change. برخی تراکنش ها تاکنون تأیید نشده اند. اعتبارات ممکن است تغییر کنند - + + Deposit Hush + + + + Address Balances اعتبارات آدرس ها - - + + Send ارسال - + Total notarized funds available: کل اعتبارات محضری دردسترس - + Send To ارسال به - + Recipient دریافت کننده - - - + + + Address آدرس - + Address Book دفترچه آدرس - - + + Amount مقدار - + Max Available حداکثر دردسترس - - - + + + Memo یادداشت - + Add Recipient اضافه کردن دریافت کننده - Recurring payment - تکرار پرداخت + تکرار پرداخت - Every month, starting 12-May-2012, for 6 payments - 12-May-20برای 6 پرداخت، هر ماه شروع می‌شود از 12 + 12-May-20برای 6 پرداخت، هر ماه شروع می‌شود از 12 - Edit Schedule - ویرایش برنامه زمانی + ویرایش برنامه زمانی - + Miner Fee کارمزد استخراج کننده - + 0 0 - + Cancel انصراف - + Receive دریافت - + Address Type نوع آدرس - + z-Addr آدرس حفاظت شده - + t-Addr آدرس عمومی - + Next Address آدرس بعدی - + Information about Hush Hush اطلاعات مربوط به - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> Hush اطلاعات زنجیره بلوک - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving نصف شدن پاداش بلوک بعدی - + Difficulty سختی - + Last Notarized Block آخرین بلوک محضری - + Total Supply کل عرضه - + Longestchain بلندترین زنجیره - + BlockHeight ارتفاع بلوک - + Supply zAddr تعداد سکه های حفاظت شده - + Supply tAddr تعداد سکه های عمومی - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> <html><head/><body><p align="center"><span style=" font-weight:600;">Hush اطلاعات </span></p></body></html> - + Market Cap حجم معاملات در بازار - + Volume on Exchanges حجم معاملات در صرافی ها - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> <html><head/><body><p align="center">این کیف پول سبک است. شما نمی توانید با آن استخراج کنید</p></body></html> @@ -359,43 +572,43 @@ Please enter your wallet password آدرس جدید - + View All Addresses مشاهده تمام آدرس ها - + Label برچسب - + Update Label بروزرسانی برچسب - + Address balance اعتبار آدرس - + Optional اختیاری - - + + Export Private Key صدور کلید خصوصی - + Your node is still syncing, balances may not be updated نود شما درحال همگام سازی است، اعتبارات ممکن است بروز نباشند - + Transactions تراکنش ها @@ -408,18 +621,18 @@ Please enter your wallet password این یک کیف پول سبک است و شما نمی توانید با آن استخراج کنید - - - - - - - - - - - - + + + + + + + + + + + + Loading... ...درحال بارگذاری @@ -428,12 +641,12 @@ Please enter your wallet password ارتفاع بلوک - + Version hushlightd Hushنسخه کیف پول سبک - + Vendor فروشنده @@ -443,251 +656,277 @@ Please enter your wallet password + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &File پرونده - + &Help امداد - + &Apps برنامه ها - + &Edit ویرایش - + E&xit خروج - + &About درباره - + &Settings تنظیمات - + Ctrl+P Ctrl+P - + &Send DenioD Feedback DenioDارسال بازخورد به - + &Hush Discord Hushدیسکورد - + &Hush Website Hushوبسایت - + Check github.com for &updates بررسی گیت هاب ما برای بروزرسانی - + &Export all private keys صدور تمام کلید های خصوصی - + Address &book دفترچه آدرس - + Ctrl+B Ctrl+B - + &Export seed phrase صدور عبارت بازیابی - - + + Export transactions صدور تراکنش‌ها - + Pay hush &URI... URI پرداخت هاش با - + Connect mobile &app اتصال برنامه تلفن همراه - + Ctrl+M Ctrl+M - + &Recurring Payments تکرار پرداخت ها - + Request hush... Hushدرخواست - + File a bug... گزارش اشکال - + Encrypt Wallet رمزنگاری کیف پول - + Remove Wallet Encryption حذف رمزنگاری کیف پول - + Rescan بررسی دوباره - Wallet is already encrypted - کیف پول در حال حاضر رمزنگاری شده است + کیف پول در حال حاضر رمزنگاری شده است - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - کیف پول شما درحال حاضر توسط رمزعبور، رمزنگاری شده است + کیف پول شما درحال حاضر توسط رمزعبور، رمزنگاری شده است لطفا از حذف رمزنگاری کیف پول استفاده کنید اگر می خواهید رمزنگاری کیف پولتان را حذف کنید. - + Passwords don't match رمزعبور همخوانی ندارد - Error was: - خطا: + خطا: - Wallet Encrypted - کیف پول رمزنگاری شده است + کیف پول رمزنگاری شده است - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - کیف پول شما با موفقیت رمزنگاری شد! این رمز عبور برای ارسال اعتبار و صدور کلید های خصوصی ضروری است + کیف پول شما با موفقیت رمزنگاری شد! این رمز عبور برای ارسال اعتبار و صدور کلید های خصوصی ضروری است - - + + Wallet Encryption Failed رمزنگاری کیف پول ناموفق بود - + Wallet is not encrypted کیف پول، رمزنگاری نشده است - Your wallet is not encrypted with a password. - کیف پول شما با رمزعبور، رمزنگاری نشده است + کیف پول شما با رمزعبور، رمزنگاری نشده است - Wallet Password - رمزعبور کیف پول + رمزعبور کیف پول - Please enter your wallet password - لطفاً رمزعبور کیف پول خود را وارد کنید + لطفاً رمزعبور کیف پول خود را وارد کنید - - - Wallet Decryption Failed - رمزگشایی کیف پول ناموفق بود + رمزگشایی کیف پول ناموفق بود - Please enter a password to decrypt your wallet! - لطفاً رمزعبور خود را وارد کنید تا کیف پول شما رمزگشایی شود + لطفاً رمزعبور خود را وارد کنید تا کیف پول شما رمزگشایی شود - Wallet Encryption Removed - رمزنگاری کیف پول حذف شد + رمزنگاری کیف پول حذف شد - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - کیف پول شما با موفقیت رمزگشایی شد! شما دیگر برای ارسال اعتبار و صدور کلید های خصوصی به رمز عبور نیازی ندارید + کیف پول شما با موفقیت رمزگشایی شد! شما دیگر برای ارسال اعتبار و صدور کلید های خصوصی به رمز عبور نیازی ندارید - - + + Copy txid کپی شناسه تراکنش - - + + Copy block explorer link کپی لینک وبسایت مشاهده تراکنش - + View tx on block explorer مشاهده تراکنش در وبسایت - + Refresh تازه سازی - + Restart اجرای مجدد - + Please restart Silentdragonlite to have the theme apply لطفا برای اعمال پوسته، سایلنت دراگون سبک خود را مجدداً اجرا کنید - + Currency Change تغییر واحد پول @@ -696,7 +935,7 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet لطفا برای اعمال واحد پول جدید، سایلنت دراگون سبک خود را مجدداً اجرا کنید - + Some feedback about SilentDragonlite or Hush... Hushبرخی بازخوردها درباره سایلنت دراگون سبک یا @@ -705,138 +944,170 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet بفرستید Duke تعدادی بازخورد به صورت خصوصی و حفاظت شده برای - + This change can take a few seconds. - + or SilentDragonLite یا سایلنت دراگون سبک - + Send DenioD some private and shielded feedback about بفرستید DenioD تعدادی بازخورد به صورت خصوصی و حفاظت شده به - + Paste HUSH URI Hush URI چسبانیدن - + Error paying HUSH URI HUSH URI خطا در پرداخت - + URI should be of the form 'hush:<addr>?amt=x&memo=y یو-آر-آی باید از این قالب باشد'hush:<addr>?amt=x&memo=y - + Error خطا - + Error exporting transactions, file was not saved خطا در صدور تراکنش ها، پرونده ذخیره نشد - + This is your wallet seed. Please back it up carefully and safely. این، عبارت بازیابی کیف پول شما است. لطفا با دقت و اطمینان از آن نسخه پشتیبان تهیه کنید - - + + Save File ذخیره پرونده - - + + Unable to open file خطا در بازکردن پرونده - + Error getting private keys خطا در دریافت کلید های خصوصی - + Error loading private keys: خطا در بارگذاری کلید های خصوصی - + These are all the private keys for all the addresses in your wallet این ها تمام کلید های خصوصی برای تمام آدرس های کیف پول های شما است - + Private key for کلید خصوصی برای - - + + Copy address کپی آدرس - - - + + + + Copied to clipboard در کلیپ بورد کپی شد - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key دریافت کلید خصوصی - - + + View on block explorer مشاهده در وبسایت - + View Payment Request مشاهده درخواست پرداخت - + View Memo مشاهده یادداشت - + Reply to پاسخ به - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr آدرس عمومی جدید، ساخته شد - + Copy Address کپی آدرس - + Address has been previously used آدرس، قبلا هم استفاده شده بود - + Address is unused آدرس استفاده نشده @@ -861,21 +1132,18 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet فقط آدرس های حفاظت شده می توانند یادداشت داشته باشند - Memos can only be used with z-addresses - یادداشت ها تنها می توانند توسط آدرس های حفاظت شده، مورد استفاده قرار گیرند + یادداشت ها تنها می توانند توسط آدرس های حفاظت شده، مورد استفاده قرار گیرند - The memo field can only be used with a z-address. - یادداشت ها تنها می توانند توسط آدرس های حفاظت شده، مورد استفاده قرار گیرند + یادداشت ها تنها می توانند توسط آدرس های حفاظت شده، مورد استفاده قرار گیرند - doesn't look like a z-address - به نظر نمی رسد این یک آدرس حفاظت شده باشد + به نظر نمی رسد این یک آدرس حفاظت شده باشد @@ -883,44 +1151,133 @@ doesn't look like a z-address خطای تراکنش - + + Please wait... ...لطفا منتظر بمانید - + Computing your transaction درحال محاسبه تراکنش شما - + + Done! !انجام شد - + + + Recipient Address آدرس دریافت کننده - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + is Invalid صحیح نیست - + + + Amount for address '%1' is invalid! صحیح نمی باشد '%1' این مقدار برای آدرس - + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + اعتبار برای ارسال این تراکنش کافی نیست + + %1 :دارای + %2 :نیازمند + + توجه: اعتبارات قبل از اینکه بتوانند خرج شوند، نیاز به 5 تاییدیه دارند + {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + + Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - اعتبار برای ارسال این تراکنش کافی نیست + اعتبار برای ارسال این تراکنش کافی نیست %1 :دارای %2 :نیازمند @@ -987,9 +1344,13 @@ Note: Funds need 5 confirmations before they can be spent MobileAppConnector - Connect Mobile App - اتصال به برنامه تلفن همراه + اتصال به برنامه تلفن همراه + + + + Mobile Connector App + @@ -1038,6 +1399,14 @@ Note: Funds need 5 confirmations before they can be spent نوع اتصال + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1051,7 +1420,7 @@ Note: Funds need 5 confirmations before they can be spent این عبارت بازیابی کیف پول جدید شما است. لطفا با اطمینان از آن پشتیبانی بگیرید - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it این عبارت بازیابی، تنها راه بازگرداندن کیف پولتان است. اگر این عبارت بازیابی را فراموش کنید، دیگر هیچ راهی برای بازگرداندن کیف پول و اعتبارات درون آن وجود ندارد @@ -1059,17 +1428,17 @@ Note: Funds need 5 confirmations before they can be spent NewSeedPage - + Error creating a wallet خطا در ساختن کیف پول جدید - + Failed to save wallet ذخیره کیف پول ناموفق بود - + Couldn't save the wallet ذخیره کیف پول مقدور نبود @@ -1085,174 +1454,210 @@ Note: Funds need 5 confirmations before they can be spent QObject - + Pick انتخاب - + + + Address or Label Error خطای آدرس یا برچسب - + + + Address or Label cannot be empty آدرس یا برچسب، نمی تواند خالی باشد - + + + Address Format Error خطای قالب آدرس - + + + %1 doesn't seem to be a valid hush address. آدرس هاش صحیحی باشد '%1' به نظر نمی رسد - + Label Error خطای برچسب - + The label '%1' already exists. Please remove the existing label. موجود بوده است. لطفا برچسب موجود را حذف کنید '%1' ِبرچسب - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book وارد کردن دفترچه آدرس - + Unable to open file قادر به بازکردن پرونده نیست - + Address Book Import Done وارد کردن دفترچه آدرس انجام شد - + Imported %1 new Address book entries به دفترچه آدرس، 1% آدرس جدید اضافه شد - + Copy address کپی آدرس - + Copied to clipboard در کلیپ بورد کپی شد - + Delete label حذف برچسب - + Attempting to initialize library with درحال تلاش برای راه‌اندازی کتابخانه با: - + Using existing wallet. استفاده از کیف پول موجود - + Create/restore wallet. ساخت/بازیابی کیف پول - - + + Connection Error خطا در برقراری اتصال - - - + + + + + Transaction Error خطا در تراکنش - + There was an error sending the transaction. The error was: خطایی در ارسال تراکنش رخ داد: - - + + No Connection متصل نیست - There was an error connecting to hushd. The error was - خطایی در اتصال به سرویس هاشد رخ داد: + خطایی در اتصال به سرویس هاشد رخ داد: - + + + - + Tx تراکنش - + + + - + failed ناموفق بود - - + + + + The transaction with id تراکنش با شناسه - - + + + + failed. The error was ناموفق بود - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available بروزرسانی دردسترس است - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? آیا مایل به بازدید از صفحه انتشار نسخه ها هستید؟ - + No updates available هیچ بروزرسانی ای دردسترس نیست - + You already have the latest release v%1 هستید v%1 شما هم‌اکنون دارای آخرین نسخه - + + Please wait for SilentDragonLite to exit لطفا تا خروج سایلنت دراگون سبک، منتظر بمانید - + + Waiting for hushd to exit لطفا تا خروج سرویس هاشد، منتظر بمانید @@ -1288,7 +1693,7 @@ Would you like to visit the releases page? تمام پرداخت های آینده، لغو می‌شوند - + Tx submitted (right click to copy) txid: تراکنش ارسال شد. برای کپی شناسه تراکنش راست کلیک کنید @@ -1343,9 +1748,13 @@ Would you like to visit the releases page? RecurringDialog - Dialog - گفتگو + گفتگو + + + + Reccuring Dialog + @@ -1399,9 +1808,13 @@ Would you like to visit the releases page? RecurringPayments - Payments - پرداخت ها + پرداخت ها + + + + Reocurring Payments + @@ -1456,9 +1869,13 @@ Would you like to visit the releases page? RecurringPending - Dialog - گفتگو + گفتگو + + + + Recurring Multiple Payments + @@ -1524,57 +1941,57 @@ Would you like to visit the releases page? درخواست پرداخت - + AddressBook دفترچه آدرس - + Request From درخواست از - + My Address آدرس من - + Amount in مقدار - + z address آدرس حفاظت شده - + Amount مقدار - + The recipient will see this address in the "to" field when they pay your request. در هنگام پرداخت درخواست شما خواهد دید "به"دریافت کننده، این آدرس را در قسمت - + Amount USD USD مقدار - + Memo یادداشت - + TextLabel برچسب متن - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. درخواست پرداخت از یک آدرس سپلینگ. شما 0.0001 هاش به آن آدرس با یو-آر-آی پرداخت هاش ارسال خواهید کرد @@ -1612,9 +2029,13 @@ Would you like to visit the releases page? RestoreSeedForm - Form - ساخت/بازیابی کیف پول + ساخت/بازیابی کیف پول + + + + Restore Wallet Seed + @@ -1645,38 +2066,38 @@ Would you like to visit the releases page? RestoreSeedPage - - + + Failed to restore wallet بازیابی کیف پول ناموفق بود - + SilentDragonLite needs 24 words to restore wallet سایلنت دراگون سبک برای بازیابی کیف پول، به 24 کلمه نیاز دارد - + Failed to parse wallet birthday تجزیه روز تولد کیف پول ناموفق بود - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. نمی توان این روز تولد کیف پول را فهمید. این باید ارتفاع بلوکی باشد که از آنجا شروع به بررسی شود. اگر نمی دانید، می توانید آن را 0 قرار دهید - + Couldn't restore the wallet نتوانست کیف پول را بازیابی کند - + Failed to save wallet ذخیره کیف پول ناموفق بود - + Couldn't save the wallet نتوانست کیف پول را ذخیره کند @@ -1684,122 +2105,143 @@ Would you like to visit the releases page? Settings - + Settings تنظیمات - + Connection اتصال - + Lightwallet Server سرور کیف پول سبک - + Options گزینه ها - default - پیش فرض + پیش فرض - blue - آبی + آبی - light - روشن + روشن - dark - تاریک + تاریک - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Fetch hush prices Hush جمع آوری نرخ های - + Check github for updates at startup بررسی گیت هاب برای بروزرسانی ها در هنگام راه‌اندازی - + Connect to github on startup to check for updates اتصال به گیت هاب در هنگام راه‌اندازی، برای بررسی بروزرسانی ها - + Theme پوسته - + Connect to the internet to fetch hush prices Hushاتصال به اینترنت برای جمع‌آوری نرخ های - + Currency واحد پول - + AUD AUD - + BTC BTC - + CAD CAD - + CHF CHF - + CNY CNY - + EUR EUR - + GBP GBP - + INR INR - + RUB RUB - + USD USD @@ -1846,27 +2288,116 @@ Would you like to visit the releases page? دفترچه آدرس - + Add New Address اضافه کردن آدرس جدید - + Address (z-Addr or t-Addr) آدرس عمومی/حفاظت شده - - Label - برچسب + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + برچسب + + + Add to Address Book اضافه به دفترچه آدرس - + Import Address Book وارد کردن دفترچه آدرس @@ -1963,32 +2494,148 @@ Would you like to visit the releases page? + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + کپی آدرس + + encryptionDialog - + Encrypt Your Wallet رمزنگاری کیف پول شما - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - رمزعبور رمزنگاری: + رمزعبور رمزنگاری: - Confirm Password: - تایید رمز عبور + تایید رمز عبور - Passwords don't match - رمزعبور همخوانی ندارد + رمزعبور همخوانی ندارد - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - هشدار: اگر شما رمزعبورتان را فراموش کنید، تنها راه بازیابی کیف پول، استفاده از عبارت بازیابی است + هشدار: اگر شما رمزعبورتان را فراموش کنید، تنها راه بازیابی کیف پول، استفاده از عبارت بازیابی است + + + + hushrequest + + + Request Payment + + + + + TextLabel + برچسب متن + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + درخواست پرداخت از یک آدرس سپلینگ. شما 0.0001 هاش به آن آدرس با یو-آر-آی پرداخت هاش ارسال خواهید کرد + + + + Request From + درخواست از + + + + zaddr + + + + + Amount in + مقدار + + + + Amount + مقدار + + + + Amount USD + USD مقدار + + + + Memo + یادداشت + + + + My Address + آدرس من + + + + The recipient will see this address in the "to" field when they pay your request. + در هنگام پرداخت درخواست شما خواهد دید "به"دریافت کننده، این آدرس را در قسمت @@ -2039,4 +2686,178 @@ Would you like to visit the releases page? تعداد پرداخت ها + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + انصراف + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + diff --git a/res/silentdragonlite_fr.ts b/res/silentdragonlite_fr.ts index b874a16..8bc8d92 100644 --- a/res/silentdragonlite_fr.ts +++ b/res/silentdragonlite_fr.ts @@ -4,29 +4,80 @@ AddressBookModel - + Label Nom - + Address Adresse + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Adresse - + Amount Montant + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog @@ -34,43 +85,47 @@ silentdragon - + SilentDragonLite SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - Démarrage + Démarrage Controller - + Wallet Password Mot de passe du wallet - + Your wallet is encrypted. Please enter your wallet password Votre portefeuille est crypté. Veuillez entrer le mot de passe du wallet - - + + Wallet Decryption Failed Échec du déchiffrement du portefeuille - + Please enter a valid password Veuillez entrer un mot de passe valide - + Failed to unlock wallet Impossible de déverrouiller le wallet @@ -78,31 +133,187 @@ Veuillez entrer le mot de passe du wallet CreateWalletForm - Form - Création / Restauration d'un wallet + Création / Restauration d'un wallet - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed Restaurer le wallet de la phrase clé (graine) - + Restore an existing wallet, using the 24-word seed. Restaurez un wallet existant à l'aide de la phrase clé de 24 mots. - - Create a new Wallet - Créer un nouveau wallet + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + Créer un nouveau wallet + + + Create a new wallet with a randomly generated seed. Créer un nouveau wallet avec une graine générée aléatoirement. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + Annuler + + + + Add Contact and Send Request + + + MainWindow @@ -110,57 +321,57 @@ Veuillez entrer le mot de passe du wallet silentdragon - + Balance Solde - + Summary Résumé - + Shielded Privé - + Notarized Notarizé - + Transparent Transparant - + Total Total - + Your node is still syncing, balances may not be updated. Votre nœud est toujours en cours de synchronisation, les soldes peuvent ne pas être mis à jour. - + Some transactions are not yet confirmed. Balances may change. Certaines transactions ne sont pas encore confirmées. Les soldes peuvent changer. - + Total notarized funds available: Total des fonds notariés disponibles: - + Next Address - + Your node is still syncing, balances may not be updated Votre nœud est toujours en cours de synchronisation, les soldes peuvent ne pas être mis à jour @@ -169,13 +380,13 @@ Veuillez entrer le mot de passe du wallet Certaines transactions ne sont pas encore confirmées - + Address Balances Solde des adresses - - + + Send Envoyer @@ -188,226 +399,268 @@ Veuillez entrer le mot de passe du wallet Solde de l'adresse - + Send To Envoyer à - + Recipient Destinataire - - - + + + Address Adresse - + Address Book Carnet d'adresses - - + + Amount Montant - + Max Available Maximum disponible - - - + + + Memo Mémo - + Add Recipient Ajouter un destinataire - Recurring payment - Paiement récurrent + Paiement récurrent - Every month, starting 12-May-2012, for 6 payments - Chaque mois, à partir du 12 mai 2012, pour 6 paiements + Chaque mois, à partir du 12 mai 2012, pour 6 paiements - Edit Schedule - Modifier la programmation + Modifier la programmation - + Miner Fee I replaced this with "transaction fee" which sounds much better in French.. I hope it's correct too.. Frais de transaction - + 0 0 - + Cancel Annuler - + Receive Recevoir - + Address Type Type d'adresse - + Version hushlightd - + &Send DenioD Feedback &amp;Envoyer des commentaires à DenioD - + &Export seed phrase &amp;Exporter la phrase clé (graine) - + Encrypt Wallet Chiffrer le portefeuille - + Remove Wallet Encryption Supprimer le chiffrement de portefeuille - + Rescan Re-scanner - + &Hush Discord &amp;Discord Hush - + SilentDragonLite SilentDragonLite - + + Deposit Hush + + + + Information about Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving - + Difficulty - + Last Notarized Block - + Total Supply - + Longestchain - + BlockHeight Hauteur du block - + Supply zAddr - + Supply tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> - + Market Cap - + Volume on Exchanges - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> Ceci est un Lightwallet, vous ne pouvez pas miner avec cette application ! - + + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &Hush Website &Site Internet Hush @@ -416,7 +669,7 @@ Veuillez entrer le mot de passe du wallet Adresse-z(Sapling) - + t-Addr Adresse-t @@ -429,28 +682,28 @@ Veuillez entrer le mot de passe du wallet Nouvelle Adresse - + Label Etiquette - + Update Label Mettre à jour l'étiquette - + Address balance Solde de l'adresse - + Optional Optionnel - - + + Export Private Key Exporter la clef privée @@ -459,17 +712,17 @@ Veuillez entrer le mot de passe du wallet Adresse utilisée - + z-Addr z-Add - + View All Addresses Voir toutes les adresses - + Transactions Transactions @@ -482,18 +735,18 @@ Veuillez entrer le mot de passe du wallet Vous ne minez pas à présent - - - - - - - - - - - - + + + + + + + + + + + + Loading... Chargement... @@ -506,7 +759,7 @@ Veuillez entrer le mot de passe du wallet Taux de solution du réseau - + Vendor Connections @@ -515,42 +768,42 @@ Veuillez entrer le mot de passe du wallet | - + &File &Fichier - + &Help &Aide - + &Apps &Applications - + &Edit &Edition - + E&xit Q&uiter - + &About &À propos - + &Settings &Préférences - + Ctrl+P Ctrl+P @@ -559,7 +812,7 @@ Veuillez entrer le mot de passe du wallet &Faire un don - + Check github.com for &updates Vérifier &github.com pour des mises à jour @@ -576,7 +829,7 @@ Veuillez entrer le mot de passe du wallet &Importer une clef privée - + &Export all private keys &Exporter toutes les clefs privées @@ -589,12 +842,12 @@ Veuillez entrer le mot de passe du wallet Ctrl+A, Ctrl+Z - + Address &book Carnet &d'adresse - + Ctrl+B Ctrl+B @@ -603,38 +856,38 @@ Veuillez entrer le mot de passe du wallet &Sauvegarder "wallet.dat" - - + + Export transactions Exporter les transactions - + Pay hush &URI... Payer une &URI Hush... - + Connect mobile &app Connexion à l'&application Mobile - + Ctrl+M Ctrl+M - + &Recurring Payments &Paiements récurrents - + Request hush... Demande de Hush... - + File a bug... Déclarer un bug ... @@ -691,12 +944,12 @@ Veuillez entrer le mot de passe du wallet Rescan de l'import de la clef privée achevé - + View tx on block explorer Voir la tx sur l'explorateur de blocs - + Refresh Rafraîchir @@ -705,7 +958,7 @@ Veuillez entrer le mot de passe du wallet Erreur lors du payement du URI hush - + URI should be of the form 'hush:<addr>?amt=x&memo=y Le format URI doit être comme suit: 'hush:<addr>?amt=x&memo=y @@ -730,12 +983,12 @@ Veuillez entrer le mot de passe du wallet Les clef seront importées dans votre noeud hushd connecté - + Error Erreur - + Error exporting transactions, file was not saved Erreur lors de l'exportation des transactions. Le fichier n'a pas été sauvegardé @@ -768,150 +1021,158 @@ Veuillez entrer le mot de passe du wallet Vous devez le sauvegarder manuellement. - + These are all the private keys for all the addresses in your wallet Ce sont toutes les clés privées pour toutes les adresses de votre portefeuille - + Private key for Clef privée pour - - + + Save File Sauvegarder le fichier - Wallet is already encrypted - Votre wallet est maintenant crypté + Votre wallet est maintenant crypté - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - Votre portefeuille est déjà crypté avec un mot de passe. + Votre portefeuille est déjà crypté avec un mot de passe. Veuillez utiliser "Supprimer le chiffrement du wallet" si vous souhaitez supprimer le chiffrement du portefeuille. - + Passwords don't match Les mots de passe ne correspondent pas - Error was: - L'erreur est la suivante : + L'erreur est la suivante : - Wallet Encrypted - wallet crypté + wallet crypté - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - Votre portefeuille a été crypté avec succès! Le mot de passe sera nécessaire pour envoyer des fonds ou exporter des clés privées. + Votre portefeuille a été crypté avec succès! Le mot de passe sera nécessaire pour envoyer des fonds ou exporter des clés privées. - - + + Wallet Encryption Failed Échec du chiffrement du wallet - + Wallet is not encrypted Votre wallet n'est pas crypté - Your wallet is not encrypted with a password. - Votre wallet n'est pas crypté avec un mot de passe. + Votre wallet n'est pas crypté avec un mot de passe. - Wallet Password - Mot de passe du wallet + Mot de passe du wallet - Please enter your wallet password - Veuillez entrer votre mot de passe portefeuille + Veuillez entrer votre mot de passe portefeuille - - - Wallet Decryption Failed - Échec du déchiffrement du wallet + Échec du déchiffrement du wallet - Please enter a password to decrypt your wallet! - Veuillez entrer un mot de passe pour décrypter votre wallet! + Veuillez entrer un mot de passe pour décrypter votre wallet! - Wallet Encryption Removed - Cryptage du wallet supprimé + Cryptage du wallet supprimé - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - Votre portefeuille a été déchiffré avec succès! Vous n'aurez plus besoin d'un mot de passe pour envoyer des fonds ou exporter des clés privées. + Votre portefeuille a été déchiffré avec succès! Vous n'aurez plus besoin d'un mot de passe pour envoyer des fonds ou exporter des clés privées. - - + + Copy block explorer link - + Currency Change Changement de la devise - + This is your wallet seed. Please back it up carefully and safely. Ceci est la graine de wallet. Veuillez le sauvegarder avec soin et en toute sécurité. - - + + Unable to open file mpossible d'ouvrir le fichier - + Error getting private keys Erreur lors de l'obtention des clés privées - + Error loading private keys: Erreur lors du chargement des clés privées: - - + + Copy address Copier l'adresse - - - + + + + Copied to clipboard Copié dans le presse-papier - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key Obtenir la clef privée @@ -920,8 +1181,8 @@ Veuillez utiliser "Supprimer le chiffrement du wallet" si vous souhait Rendre privé le solde vers Sapling - - + + View on block explorer Voir dans l'explorateur de block @@ -930,83 +1191,93 @@ Veuillez utiliser "Supprimer le chiffrement du wallet" si vous souhait Migrer vers Sapling - - + + Copy txid Copier l'ID de transaction - + Restart Redémarrer - + Please restart Silentdragonlite to have the theme apply Veuillez redémarrer SilentDragonLite pour aplliqué le thème. - + This change can take a few seconds. - + Some feedback about SilentDragonlite or Hush... Quelques commentaires sur SilentDragonlite ou Hush ... - + or SilentDragonLite ou SilentDragonLite - + Send DenioD some private and shielded feedback about Envoyez à DenioD des commentaires privés et protégés sur - + Paste HUSH URI Coller l'URI Hush - + Error paying HUSH URI Erreur lors du paiement de l'URI Hush - + View Payment Request Afficher la demande de paiement - + View Memo Voir le mémo - + Reply to Répondre à - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Nouvelle Adresse-t créée - + Copy Address Copier l'adresse - + Address has been previously used L'adresse a été utilisée précédemment - + Address is unused L'adresse est inutilisée @@ -1021,48 +1292,46 @@ Veuillez utiliser "Supprimer le chiffrement du wallet" si vous souhait Seules les Adresses-z peuvent avoir un mémo - Memos can only be used with z-addresses - Les mémos peuvent seulement être utilisés avec des Adresses-z + Les mémos peuvent seulement être utilisés avec des Adresses-z - The memo field can only be used with a z-address. - Le champs mémo ne peut uniquement être utilisé avec une adresse-z. + Le champs mémo ne peut uniquement être utilisé avec une adresse-z. - doesn't look like a z-address - + Cette adresse ne semble pas être de type adresse-z - + + Please wait... Veuillez patienter... - + Computing your transaction Calcul de votre transaction - + + Done! Terminé! - Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - Vous n'avez pas assez de fonds disponibles pour envoyer cette transaction + Vous n'avez pas assez de fonds disponibles pour envoyer cette transaction Ont:%1 Besoin:%2 @@ -1105,20 +1374,107 @@ Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépens L'adresse de l'émetteur est invalide - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address Adresse du destinataire - + + + is Invalid est invalide - + + + Amount for address '%1' is invalid! Le montant pour l'adresse '%1' est invalide! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + Vous n'avez pas assez de fonds disponibles pour envoyer cette transaction + +Ont:%1 +Besoin:%2 + +Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépensés {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + Amount '%1' is invalid! Le montant '%1' est invalide. @@ -1182,9 +1538,8 @@ Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépens MobileAppConnector - Connect Mobile App - Connexion à l'application Mobile + Connexion à l'application Mobile @@ -1206,6 +1561,11 @@ Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépens Scan this QRCode from your silentdragon companion app to connect your phone Scannez ce code QR à partir de votre application mobile SilentDragon pour connecter votre téléphone + + + Mobile Connector App + + silentdragon Companion App @@ -1233,6 +1593,14 @@ Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépens Type de connection : + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1246,7 +1614,7 @@ Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépens Ceci est la phrase clé de votre nouveau wallet. VEUILLEZ LE GARDER EN TOUTE SECURITE. - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it La phrase clé (graine) est le seul moyen de restaurer le wallet. Si vous oubliez la phrase clé, IL N'Y A AUCUN MOYEN DE RESTAURER VOTRE WALLET ET LES FONDS @@ -1254,17 +1622,17 @@ Remarque: Les fonds nécessitent 5 confirmations avant de pouvoir être dépens NewSeedPage - + Error creating a wallet Erreur lors de la création du wallet - + Failed to save wallet Échec lors de la sauvvegarde du wallet - + Couldn't save the wallet Impossible d'enregister le wallet @@ -1388,33 +1756,40 @@ Not starting embedded hushd because --no-embedded was passed hushd n'a aucune connexion à un pair - There was an error connecting to hushd. The error was - Une erreur est survenue lors de la connection à hushd. L'erreur est + Une erreur est survenue lors de la connection à hushd. L'erreur est - - + + + + The transaction with id La transaction avec ID - - + + + + failed. The error was a échoué. L'erreur était - + + + - + failed a échoué - + + + - + Tx Tx @@ -1423,12 +1798,17 @@ Not starting embedded hushd because --no-embedded was passed tx en cours de calcul. Ceci peut prendre quelques minutes. - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available MàJ disponible - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1437,17 +1817,18 @@ Would you like to visit the releases page? Voulez-vous visiter la page des nouvelles versions ? - + No updates available Pas de MàJ disponible - + You already have the latest release v%1 Vous utilisez déjà la dernière version v%1 - + + Please wait for SilentDragonLite to exit Merci d'attendre la fermeture de SilentDragonLite @@ -1456,7 +1837,8 @@ Voulez-vous visiter la page des nouvelles versions ? Veuillez patienter. Fermeture de silentdragon en cours - + + Waiting for hushd to exit Attente de la fermeture de hushd @@ -1493,61 +1875,69 @@ Veuillez configurer l'hôte/port et utilisateur/mot de passe dans le menu E Votre hushd est en cours de démarrage. Veuillez patienter. - + Attempting to initialize library with Tentative d’initialisation de la bibliothèque avec - + Using existing wallet. Utiliser le wallet existant. - + Create/restore wallet. Créer / restaurer un wallet. - - + + Connection Error Erreur de connection - - - + + + + + Transaction Error Erreur de transaction - + There was an error sending the transaction. The error was: Une erreur est survenue en envoyant la transaction. L'erreur est: - - + + No Connection Pas de connection - + Pick Choisir - + + + Address or Label Error Erreur dans l'adresse ou le libellé - + + + Address or Label cannot be empty L'adresse ou le libellé ne peuvent pas être vide - + + + Address Format Error Erreur de format d'adresse @@ -1556,57 +1946,71 @@ Veuillez configurer l'hôte/port et utilisateur/mot de passe dans le menu E ne semble pas être une adresse hush valide. - + + + %1 doesn't seem to be a valid hush address. %1 ne semble pas être une adresse Hush valide. - + Label Error Erreur sur le libellé - + The label '%1' already exists. Please remove the existing label. Le libellé '%1' existe déjà. Veuillez supprimer l'étiquette existante. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Importer le carnet d'adresses - + Unable to open file Impossible d'ouvrir le fichier - + Address Book Import Done Import du carnet d'adresses terminé - + Imported %1 new Address book entries %1 nouvelle(s) entrée(s) importée(s) dans le carnet d'adresses - + Copy address Copier l'adresse - + Copied to clipboard Copiée dans le presse papier - + Delete label Effacer l'étiquette - + Tx submitted (right click to copy) txid: Tx soumise. (clic droit pour copier) txid: @@ -1706,9 +2110,13 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi RecurringDialog - Dialog - Dialogue + Dialogue + + + + Reccuring Dialog + @@ -1762,9 +2170,13 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi RecurringPayments - Payments - Paiements + Paiements + + + + Reocurring Payments + @@ -1819,9 +2231,13 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi RecurringPending - Dialog - Paiements récurrents + Paiements récurrents + + + + Recurring Multiple Payments + @@ -1887,57 +2303,57 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Demande de paiement - + AddressBook Carnet d'adresses - + Request From Demande de - + My Address Mon adresse - + Amount in Montant en - + z address z address - + Amount Montant - + The recipient will see this address in the "to" field when they pay your request. Le destinataire verra cette adresse dans le champ "à" lorsqu'il paiera votre demande. - + Amount USD Montant en USD - + Memo Mémo - + TextLabel TextLabel - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Demander le paiement à une adresse de type Sapling. Vous enverrez une transaction de 0.0001 Hush à l'adresse avec un URI de paiement Hush. Le mémo sera inclus dans la transaction lorsque l'adresse vous payera. @@ -1975,9 +2391,13 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi RestoreSeedForm - Form - Graine + Graine + + + + Restore Wallet Seed + @@ -2008,38 +2428,38 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi RestoreSeedPage - - + + Failed to restore wallet Échec de la restoration du wallet - + SilentDragonLite needs 24 words to restore wallet SilentDragonLite a besoin de 24 mots pour restaurer son wallet - + Failed to parse wallet birthday Impossible d'analyser l'anniversaire du wallet - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. L'anniversaire du wallet n'est pas reconnue. Cela devrait être une hauteur de bloc à partir de laquelle numériser à nouveau le portefeuille. Vous pouvez laisser «0» si vous ne savez pas ce que cela devrait être. - + Couldn't restore the wallet Impossible de restaurer le wallet - + Failed to save wallet Échec de la sauvegarde du wallet - + Couldn't save the wallet Impossible d'enregister le wallet @@ -2047,7 +2467,7 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Settings - + Settings Paramétres @@ -2072,12 +2492,37 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Mot de passe RPC - + Options Options - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Check github for updates at startup Rechercher les mises à jour sur GitHub au démarrage @@ -2094,107 +2539,103 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Se connecter via Tor - + Connect to github on startup to check for updates Connexion à GitHub au démarragede l'application pour rechercher les mises à jour - + Connect to the internet to fetch hush prices Connexion à Internet pour obtenir des prix de Hush - + Theme Thème - + Lightwallet Server Serveur Lightwallet - default - Standard + Standard - + Connection Connexion - blue - Bleu + Bleu - light - Light + Light - dark - Dark + Dark - + Fetch hush prices Récupérer les prix de Hush - + Currency Devise - + AUD AUD - + BTC BTC - + CAD CAD - + CHF CHF - + CNY CNY - + EUR EUR - + GBP GBP - + INR INR - + RUB RUB - + USD USD @@ -2327,27 +2768,116 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Carnet d'adresses - + Add New Address Ajouter une nouvelle adresse - + Address (z-Addr or t-Addr) Adresse (Adresse-z ou Adresse-t) - - Label - Etiquette + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Etiquette + + + Add to Address Book Ajouter au carnet d'adresse - + Import Address Book Importer de carnet d'adresses @@ -2445,32 +2975,148 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Veuillez noter que vous devez déjà avoir un service Tor configuré sur le port 9050 + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Copier l'adresse + + encryptionDialog - + Encrypt Your Wallet Cryptez votre wallet - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - Mot de passe du cryptage: + Mot de passe du cryptage: - Confirm Password: - Confirmez le mot de passe: + Confirmez le mot de passe: - Passwords don't match - Les mots de passe ne correspondent pas + Les mots de passe ne correspondent pas - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - AVERTISSEMENT: Si vous oubliez votre mot de passe, le seul moyen de récupérer le portefeuille consiste à utiliser la phrase clé. + AVERTISSEMENT: Si vous oubliez votre mot de passe, le seul moyen de récupérer le portefeuille consiste à utiliser la phrase clé. + + + + hushrequest + + + Request Payment + + + + + TextLabel + TextLabel + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Demander le paiement à une adresse de type Sapling. Vous enverrez une transaction de 0.0001 Hush à l'adresse avec un URI de paiement Hush. Le mémo sera inclus dans la transaction lorsque l'adresse vous payera. + + + + Request From + Demande de + + + + zaddr + + + + + Amount in + Montant en + + + + Amount + Montant + + + + Amount USD + Montant en USD + + + + Memo + Mémo + + + + My Address + Mon adresse + + + + The recipient will see this address in the "to" field when they pay your request. + Le destinataire verra cette adresse dans le champ "à" lorsqu'il paiera votre demande. @@ -2521,6 +3167,180 @@ Vous avez soit des fonds non confirmés soit le solde est trop petit pour une mi Mémo + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Annuler + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + zboard diff --git a/res/silentdragonlite_hr.ts b/res/silentdragonlite_hr.ts index 2113af1..430ec6f 100644 --- a/res/silentdragonlite_hr.ts +++ b/res/silentdragonlite_hr.ts @@ -4,69 +4,124 @@ AddressBookModel - + Label Oznaka - + Address Adresa + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Adresa - + Amount Količina + + ChatBubbleMe + + + Form + Od + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + Od + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog - + SilentDragonLite SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - Početak + Početak Controller - + Wallet Password Lozinka novčanika - + Your wallet is encrypted. Please enter your wallet password Vaš novčanik je šifriran. Molimo unesite vašu lozinku - - + + Wallet Decryption Failed Dešifriranje novčanika neuspjelo - + Please enter a valid password Molimo unesite valjanu lozinku - + Failed to unlock wallet Neuspjeh prilikom otključavanja novčanika @@ -74,284 +129,442 @@ Molimo unesite vašu lozinku CreateWalletForm - Form - Od + Od - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed Vraćanje novčanika u početno stanje iz seed riječi - + Restore an existing wallet, using the 24-word seed. Vratite postojeći novčanik u početno stanje koristeći seed od 24 riječi. - - Create a new Wallet - Napravite novi novčanik + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + Napravite novi novčanik + + + Create a new wallet with a randomly generated seed. Napravite novi novčanik sa nasumice odabranim seed riječima. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + Odustani + + + + Add Contact and Send Request + + + MainWindow - + SilentDragonLite SilentDragonLite - + Balance Saldo - + Summary Sažetak - + Shielded Zaštićeno - + Notarized Potvrđeno - + Transparent Transparentno - + Total Ukupno - + Your node is still syncing, balances may not be updated. Vaš čvor se još uvijek sinkronizira, saldo neće biti ažuriran. - + Some transactions are not yet confirmed. Balances may change. Neke transakcije još nisu potvrđene. Saldo se može promijeniti. - + + Deposit Hush + + + + Address Balances Saldo adrese - - + + Send Šalji - + Total notarized funds available: Ukopna dostupna potvrđena sredstva: - + Send To Pošalji - + Recipient Primatelj - - - + + + Address Adresa - + Address Book Adresar - - + + Amount Količina - + Max Available Max dostupno - - - + + + Memo Poruka (memo) - + Add Recipient Dodaj primatelja - Recurring payment - Ponavljajuće plaćanje + Ponavljajuće plaćanje - Every month, starting 12-May-2012, for 6 payments - Svaki mjesec s početkom 12-Svibnja-2012, u 6 rata + Svaki mjesec s početkom 12-Svibnja-2012, u 6 rata - Edit Schedule - Uredi raspored + Uredi raspored - + Miner Fee Naknada za rudarenje - + 0 0 - + Cancel Odustani - + Receive Primiti - + Address Type Vrsta adrese - + z-Addr z-Adr - + t-Addr t-adr - + Next Address - + Information about Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving - + Difficulty - + Last Notarized Block - + Total Supply - + Longestchain - + BlockHeight - + Supply zAddr - + Supply tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> - + Market Cap - + Volume on Exchanges - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> @@ -360,43 +573,43 @@ Molimo unesite vašu lozinku Nova adresa - + View All Addresses Pogledaj sve adrese - + Label Oznaka - + Update Label Ažuriraj oznaku - + Address balance Saldo na adresi - + Optional Opcionalno - - + + Export Private Key Izvoz privatnog ključa - + Your node is still syncing, balances may not be updated Vaš čvor se još uvijek sinkronizira, saldo neće biti ažuriran - + Transactions Transakcije @@ -409,18 +622,18 @@ Molimo unesite vašu lozinku Ovo je LaganiNovčanik, s njim ne možete rudariti! - - - - - - - - - - - - + + + + + + + + + + + + Loading... Učitavanje... @@ -429,12 +642,12 @@ Molimo unesite vašu lozinku visinaBloka - + Version hushlightd Verzija hushlightd - + Vendor Prodavač @@ -444,251 +657,277 @@ Molimo unesite vašu lozinku + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &File &Datoteka - + &Help &Pomoć - + &Apps &Apps - + &Edit &Uredi - + E&xit &Izlaz - + &About &O - + &Settings &Postavke - + Ctrl+P Ctrl+P - + &Send DenioD Feedback &Pošalji DenioD povratne informacije - + &Hush Discord &Hush Discord - + &Hush Website &Hush Web stranica - + Check github.com for &updates Provjeri na github.com &dopune - + &Export all private keys &Izvoz svih privatnih ključeva - + Address &book Adresna &knjiga - + Ctrl+B Ctrl+B - + &Export seed phrase &Izvoz seed fraze - - + + Export transactions Izvoz transakcija - + Pay hush &URI... Plati hush &URI... - + Connect mobile &app Spoji mobilnu &app - + Ctrl+M Ctrl+M - + &Recurring Payments &Ponavljajuća plaćanja - + Request hush... Zatraži hush... - + File a bug... Prijavi grešku... - + Encrypt Wallet Šifriraj novčanik - + Remove Wallet Encryption Uklonite šifriranje novčanika - + Rescan Rescan - Wallet is already encrypted - Novčanik je već šifriran + Novčanik je već šifriran - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - Vaš novčanik je već šifriran lozinkom. + Vaš novčanik je već šifriran lozinkom. Molimo koristite 'Uklonite šifriranje novčanika' ako želite ukloniti šifriranje novčanika. - + Passwords don't match Lozinke se ne podudaraju - Error was: - Greška je : + Greška je : - Wallet Encrypted - Novčanik šifriran + Novčanik šifriran - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - Vaš novčanik je uspješno šifriran! Lozinka će vam trebati za slanje sredstava ili za izvoz privatnih ključeva. + Vaš novčanik je uspješno šifriran! Lozinka će vam trebati za slanje sredstava ili za izvoz privatnih ključeva. - - + + Wallet Encryption Failed Šifriranje novčanika neuspjelo - + Wallet is not encrypted Novčanik nije šifriran - Your wallet is not encrypted with a password. - Vaš novčanik nije šifriran sa lozinkom. + Vaš novčanik nije šifriran sa lozinkom. - Wallet Password - Lozinka novčanika + Lozinka novčanika - Please enter your wallet password - Molimo unesite lozinku novčanika + Molimo unesite lozinku novčanika - - - Wallet Decryption Failed - Dešifriranje novčanika neuspjelo + Dešifriranje novčanika neuspjelo - Please enter a password to decrypt your wallet! - Molimo unesite lozinku za dešifriranje novčanika! + Molimo unesite lozinku za dešifriranje novčanika! - Wallet Encryption Removed - Šifriranje novčanika uklonjeno + Šifriranje novčanika uklonjeno - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - Vaš novčanik je uspješno dešifriran! Lozinka vam više neće trebati za slanje sredstava ili za izvoz privatnih ključeva. + Vaš novčanik je uspješno dešifriran! Lozinka vam više neće trebati za slanje sredstava ili za izvoz privatnih ključeva. - - + + Copy txid Kopitajte txid - - + + Copy block explorer link - + View tx on block explorer Pogledaj tx na blok pregledniku - + Refresh Osvježi - + Restart Ponovno pokreni - + Please restart Silentdragonlite to have the theme apply Molimo ponovno pokrenite SilentDragonLite ako želite primjeniti temu - + Currency Change Razmjena valuta @@ -697,12 +936,12 @@ Molimo koristite 'Uklonite šifriranje novčanika' ako želite uklonit Molimo ponovno pokrenite SilentDragonLite ako želite primjeniti novu valutu - + This change can take a few seconds. - + Some feedback about SilentDragonlite or Hush... Neke povratne informaciej o SilentDragonLite ili Hush... @@ -711,133 +950,165 @@ Molimo koristite 'Uklonite šifriranje novčanika' ako želite uklonit Pošaljite Duke neku privatnu i zaštićenu povratnu informaciju - + or SilentDragonLite ili SilentDragonLite - + Send DenioD some private and shielded feedback about - + Paste HUSH URI Zalijepi HUSH URI - + Error paying HUSH URI Greška u plaćanju HUSH URI - + URI should be of the form 'hush:<addr>?amt=x&memo=y URI treba biti formata 'hush:<addr>?amt=x&memo=y - + Error Greška - + Error exporting transactions, file was not saved Greška prilikom izvoza transakcija, datoteka nije spremljena - + This is your wallet seed. Please back it up carefully and safely. Ovo je vaš seed novčanika. Molimo izradite sigurnosnu kopiju. - - + + Save File Spremi datoteku - - + + Unable to open file Nije moguće otvoriti datoteku - + Error getting private keys Greška u dohvaćanju privatnih ključeva - + Error loading private keys: Greška prilikom učitavanja privatnog ključa: - + These are all the private keys for all the addresses in your wallet Ovo su svi privatni ključevi svih adresa u vašem novčaniku - + Private key for Privatni ključ za - - + + Copy address Kopirajte adresu - - - + + + + Copied to clipboard Kopirano u mađuspremnik - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key Dobavi privatni ključ - - + + View on block explorer Pogledaj na blok pregledniku - + View Payment Request Pogledajte zahtjev o plaćanju - + View Memo Pogledajte poruku (memo) - + Reply to Odgovorite - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Napravljena je nova transparentna adresa - + Copy Address Kopirajte adresu - + Address has been previously used Adresa je već korištena - + Address is unused Adresa nije korištena @@ -862,22 +1133,19 @@ Molimo koristite 'Uklonite šifriranje novčanika' ako želite uklonit Samo z-adrese mogu imati poruke - Memos can only be used with z-addresses - Poruke se mogu koristiti samo sa z-adresama + Poruke se mogu koristiti samo sa z-adresama - The memo field can only be used with a z-address. - Prostor za poruku se može koristiti samo sa z-adresom. + Prostor za poruku se može koristiti samo sa z-adresom. - doesn't look like a z-address - + ne izgleda kao z-adresa @@ -886,44 +1154,132 @@ ne izgleda kao z-adresa Greška u transakciji - + + Please wait... Molimo pričekajte... - + Computing your transaction Računamo vašu transakciju - + + Done! Gotovo! - + + + Recipient Address Adresa primatelja - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + is Invalid je neispravna - + + + Amount for address '%1' is invalid! Količina za adresu '%1' je nevaljala! - + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + Nema dovoljno dostupnih sredstava za slanje transakcije + +Imate: %1 +Trebate: %2 + +Opaska: Za trošenje sredstava potrebno je 5 konfirmacija {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + + Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - Nema dovoljno dostupnih sredstava za slanje transakcije + Nema dovoljno dostupnih sredstava za slanje transakcije Imate: %1 Trebate: %2 @@ -989,9 +1345,13 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija MobileAppConnector - Connect Mobile App - Spojite mobilnu applikaciju + Spojite mobilnu applikaciju + + + + Mobile Connector App + @@ -1040,6 +1400,14 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija Vrsta veze: + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1053,7 +1421,7 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija Ovo je vaša nova seed fraza novčanika. MOLIMO SIGURNO JU SPREMITE. - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it Jedino je pomoću seed fraze moguće ponovno obnoviti novčanik. Ako zaboravite seed frazu, NE POSTOJI NAČIN DA PONOVNO OBNOVITE NOVČANIK I SREDSTVA unutra @@ -1061,17 +1429,17 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija NewSeedPage - + Error creating a wallet Greška u kreiranju novčanika - + Failed to save wallet Neuspjelo spremanje novčanika - + Couldn't save the wallet Ne mogu spremiti novčanik @@ -1087,152 +1455,186 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija QObject - + Pick Odaberite - + + + Address or Label Error Greška u adresi ili oznaci - + + + Address or Label cannot be empty Adresa ili oznaka ne može biti prazno - + + + Address Format Error Greška u formatu adrese - + + + %1 doesn't seem to be a valid hush address. %1 čini se da nije valjana hush adresa. - + Label Error Greška oznake - + The label '%1' already exists. Please remove the existing label. Oznaka %1 već postoji.Molimo uklonite postojeću adresu. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Uvezite adresar - + Unable to open file Nije moguće otvoriti datoteku - + Address Book Import Done Završen unos adresara - + Imported %1 new Address book entries Uvezeno %1 novih adresa - + Copy address Kopirajte adresu - + Copied to clipboard Kopirano u mađuspremnik - + Delete label Izbrišite oznaku - + Attempting to initialize library with Poušavam pokrenuti zbirku sa - + Using existing wallet. Koristim postojeći novčanik. - + Create/restore wallet. Napravi/obnovi novčanik. - - + + Connection Error Greška sa vezom - - - + + + + + Transaction Error Greška u transakciji - + There was an error sending the transaction. The error was: Pojavila se greška prilikom slanja transakcije. Greška je: - - + + No Connection Nema veze - There was an error connecting to hushd. The error was - Pojavila se greška prilikom spajanja na hushd. Greška je + Pojavila se greška prilikom spajanja na hushd. Greška je - + + + - + Tx Tx - + + + - + failed neuspjelo - - + + + + The transaction with id Transakcija sa ID - - + + + + failed. The error was nesupjela. Greška je - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available Dostupno ažuriranje - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1241,22 +1643,24 @@ Would you like to visit the releases page? Želite li posjetiti stranicu sa izadnjima? - + No updates available Nema dostupnih ažuriranja - + You already have the latest release v%1 Već imate najnovije izdanje v%1 - + + Please wait for SilentDragonLite to exit Molimo pričekajte da se SilentDragonLite zatvori - + + Waiting for hushd to exit Čekam da hushd završi @@ -1292,7 +1696,7 @@ Would you like to visit the releases page? Sva buduća plaćanja će biti otkazana. - + Tx submitted (right click to copy) txid: Tx poslan (desni klik za kopiranje) txid: @@ -1347,9 +1751,13 @@ Would you like to visit the releases page? RecurringDialog - Dialog - Dialog + Dialog + + + + Reccuring Dialog + @@ -1403,9 +1811,13 @@ Would you like to visit the releases page? RecurringPayments - Payments - Plaćanja + Plaćanja + + + + Reocurring Payments + @@ -1460,9 +1872,13 @@ Would you like to visit the releases page? RecurringPending - Dialog - Dialog + Dialog + + + + Recurring Multiple Payments + @@ -1528,57 +1944,57 @@ Would you like to visit the releases page? Zahtjev o plaćanju - + AddressBook Adresar - + Request From Zatraži od - + My Address Moja adresa - + Amount in Količina u - + z address z adresa - + Amount Količina - + The recipient will see this address in the "to" field when they pay your request. Primatelj će prilikom plaćanja vidjeti ovu adresu u "za" polju. - + Amount USD Količina USD - + Memo Poruka (memo) - + TextLabel TekstOznaka - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Zatraži plaćanje iz sapling adrese. Poslat ćete 0.0001 husha transakciju na adresu sa hush URI nalogom. Poruka (memo) će biti uključena u transakciji kada vas adresa plati. @@ -1616,9 +2032,13 @@ Would you like to visit the releases page? RestoreSeedForm - Form - Od + Od + + + + Restore Wallet Seed + @@ -1649,38 +2069,38 @@ Would you like to visit the releases page? RestoreSeedPage - - + + Failed to restore wallet Neuspjelo obnavljanje novčanika - + SilentDragonLite needs 24 words to restore wallet SilentDragonLite treba 24 riječi za obnovu novčanika - + Failed to parse wallet birthday Neuspjelo očitanje rođendana novčanika - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. Nisam u mogućnosti razumijeti rođendan novčanika. To bi trebala bi biti visina bloka od koje počinje rescan novčanika. Ako ne znate koja je, možete ostaviti '0'. - + Couldn't restore the wallet Nemoguće obnoviti novčanik - + Failed to save wallet Neuspjeh spremanja novčanika - + Couldn't save the wallet Nemoguće spremiti novčanik @@ -1688,122 +2108,143 @@ Would you like to visit the releases page? Settings - + Settings Postavke - + Connection Veza - + Lightwallet Server Server LaganiNovčanik - + Options Opcije - default - početno + početno - blue - plavo + plavo - light - svijetlo + svijetlo - dark - tamno + tamno - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Fetch hush prices Dohvati hush cijene - + Check github for updates at startup Prilikom pokretanja provjetite ažuriranja na githubu - + Connect to github on startup to check for updates Prilikom pokretanja provjetite ažuriranja na githubu - + Theme Teme - + Connect to the internet to fetch hush prices Spoji se na Internet i dohvati hush cijene - + Currency Valuta - + AUD AUD - + BTC BTC - + CAD CAD - + CHF CHF - + CNY CNY - + EUR EUR - + GBP GBP - + INR INR - + RUB - + USD USD @@ -1850,27 +2291,116 @@ Would you like to visit the releases page? Adresar - + Add New Address Dodaj novu adresu - + Address (z-Addr or t-Addr) Adresa (z-adresa ili t-adresa) - - Label - Oznaka + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Oznaka + + + Add to Address Book Dodaj u adresar - + Import Address Book Uvezite adresar @@ -1964,32 +2494,148 @@ Would you like to visit the releases page? <html><head/><body><p>Preskače najskuplje provjere tokom početnog preuzimanja bloka. <a href="https://docs.silentdragon.co/using-silentdragon/#fastsync"><span style=" text-decoration: underline; color:#0000ff;">Saznaj više</span></a></p></body></html> + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Kopirajte adresu + + encryptionDialog - + Encrypt Your Wallet Šifrirajte vaš novčanik - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - Lozinka šifriranja: + Lozinka šifriranja: - Confirm Password: - Potvrdite lozinku: + Potvrdite lozinku: - Passwords don't match - Lozinke se ne podudaraju + Lozinke se ne podudaraju - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - UPOZORENJE: Ako zaboravite lozinku, jedini način da obnovite novčanik je iz seed fraze. + UPOZORENJE: Ako zaboravite lozinku, jedini način da obnovite novčanik je iz seed fraze. + + + + hushrequest + + + Request Payment + + + + + TextLabel + TekstOznaka + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Zatraži plaćanje iz sapling adrese. Poslat ćete 0.0001 husha transakciju na adresu sa hush URI nalogom. Poruka (memo) će biti uključena u transakciji kada vas adresa plati. + + + + Request From + Zatraži od + + + + zaddr + + + + + Amount in + Količina u + + + + Amount + Količina + + + + Amount USD + Količina USD + + + + Memo + Poruka (memo) + + + + My Address + Moja adresa + + + + The recipient will see this address in the "to" field when they pay your request. + Primatelj će prilikom plaćanja vidjeti ovu adresu u "za" polju. @@ -2041,4 +2687,178 @@ Would you like to visit the releases page? Broj uplata + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Odustani + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + diff --git a/res/silentdragonlite_it.ts b/res/silentdragonlite_it.ts index aa22b26..a3dd69e 100644 --- a/res/silentdragonlite_it.ts +++ b/res/silentdragonlite_it.ts @@ -4,29 +4,80 @@ AddressBookModel - + Label Etichetta - + Address Indirizzo + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Indirizzo - + Amount Saldo + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog @@ -34,42 +85,46 @@ silentdragon - + SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - Avvio in corso + Avvio in corso Controller - + Wallet Password - + Your wallet is encrypted. Please enter your wallet password - - + + Wallet Decryption Failed - + Please enter a valid password - + Failed to unlock wallet @@ -78,30 +133,178 @@ Please enter your wallet password CreateWalletForm - Form + Create New SDL Wallet - + + Confirm Passphrase: + + + + Restore wallet from seed - + Restore an existing wallet, using the 24-word seed. - - Create a new Wallet + + Create a new wallet - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new wallet with a randomly generated seed. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + Annulla + + + + Add Contact and Send Request + + + MainWindow @@ -109,59 +312,59 @@ Please enter your wallet password silentdragon - + Balance check Saldo - + Summary Riepilogo - + Shielded meglio tenerla in EN Shielded - + Notarized - + Transparent Trasparente - + Total Totale - + Your node is still syncing, balances may not be updated. - + Some transactions are not yet confirmed. Balances may change. - + Total notarized funds available: - + Next Address - + Your node is still syncing, balances may not be updated @@ -170,13 +373,13 @@ Please enter your wallet password Rilevate transazioni non ancora confermate - + Address Balances Saldo degli indirizzi - - + + Send Invia @@ -190,33 +393,33 @@ Please enter your wallet password Saldo Indirizzo - + Send To Inviare a - + Recipient Destinatario - - - + + + Address Indirizzo - + Address Book Rubrica - - + + Amount @@ -224,192 +427,222 @@ Please enter your wallet password Importo - + Max Available Invia tutto - - - + + + Memo Memo - + Add Recipient Aggiungi alla rubrica - - Recurring payment - - - - - Every month, starting 12-May-2012, for 6 payments - - - - - Edit Schedule - - - - + Miner Fee Commissioni di rete - + 0 0 - + Cancel Annulla - + Receive Ricevi - + Address Type Tipo Indirizzo - + Version hushlightd - + &Send DenioD Feedback - + &Export seed phrase - + Encrypt Wallet - + Remove Wallet Encryption - + Rescan - + &Hush Discord - + SilentDragonLite - + + Deposit Hush + + + + Information about Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving - + Difficulty - + Last Notarized Block - + Total Supply - + Longestchain - + BlockHeight - + Supply zAddr - + Supply tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> - + Market Cap - + Volume on Exchanges - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> - + + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &Hush Website @@ -418,7 +651,7 @@ Please enter your wallet password z-Addr(Sapling) - + t-Addr t-Addr (Trasparente) @@ -427,7 +660,7 @@ Please enter your wallet password z-Addr(Legacy Sprout) - + z-Addr @@ -436,38 +669,38 @@ Please enter your wallet password Crea Indirizzo - + View All Addresses - + Label Etichetta - + Update Label Aggiorna etichetta - + Address balance - + Optional Opzionale - - + + Export Private Key Esporta la chiave privata - + Transactions Transazioni @@ -480,18 +713,18 @@ Please enter your wallet password Al momento non stai minando - - - - - - - - - - - - + + + + + + + + + + + + Loading... Caricamento... @@ -506,7 +739,7 @@ Please enter your wallet password Potenza di calcolo Network - + Vendor Connessioni attive @@ -515,42 +748,42 @@ Please enter your wallet password | - + &File &File - + &Help &Aiuto - + &Apps &Apps - + &Edit &Modifica - + E&xit &Esci - + &About &About - + &Settings &Impostazioni - + Ctrl+P Ctrl+P @@ -559,7 +792,7 @@ Please enter your wallet password &Dona - + Check github.com for &updates Controllo nuovi &aggiornamenti @@ -576,7 +809,7 @@ Please enter your wallet password &Importa chiave privata - + &Export all private keys &Esporta tutte le chiavi private @@ -589,13 +822,13 @@ Please enter your wallet password Ctrl+A, Ctrl+Z - + Address &book check Rubrica &Contatti - + Ctrl+B Ctrl+B @@ -604,38 +837,38 @@ Please enter your wallet password &Backup wallet.dat - - + + Export transactions - + Pay hush &URI... - + Connect mobile &app - + Ctrl+M - + &Recurring Payments - + Request hush... - + File a bug... @@ -672,17 +905,38 @@ Please enter your wallet password L'importazione delle chiavi private è stata completata - + URI should be of the form 'hush:<addr>?amt=x&memo=y - + View tx on block explorer - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Refresh @@ -696,12 +950,12 @@ Please enter your wallet password Le chiavi saranno importate nel tuo nodo hushd - + Error - + Error exporting transactions, file was not saved @@ -734,148 +988,85 @@ Please enter your wallet password Devi eseguire il backup manualmente. - + These are all the private keys for all the addresses in your wallet Queste sono le chiavi private per tutti gli indirizzi nel tuo portafoglio - + Private key for Chiave privata per - - + + Save File Salva File - - Wallet is already encrypted - - - - - Your wallet is already encrypted with a password. -Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - - - - + Passwords don't match - - Error was: - - - - - - Wallet Encrypted - - - - - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - - - - - + + Wallet Encryption Failed - + Wallet is not encrypted - - Your wallet is not encrypted with a password. - - - - - Wallet Password - - - - - Please enter your wallet password - - - - - - - Wallet Decryption Failed - - - - - Please enter a password to decrypt your wallet! - - - - - Wallet Encryption Removed - - - - - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - - - - - + + Copy block explorer link - + Currency Change - + This is your wallet seed. Please back it up carefully and safely. - - + + Unable to open file Impossibile aprire il file - + Error getting private keys - + Error loading private keys: - - + + Copy address Copia indirizzo - - - + + + + Copied to clipboard Copiato negli appunti - + Get private key Ottieni una chiave privata @@ -884,8 +1075,8 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Trasferisci il saldo su un indirizzo shielded Sapling - - + + View on block explorer Guarda sul block-explorer @@ -894,83 +1085,93 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Migra a Sapling - - + + Copy txid Copia txid - + Restart - + Please restart Silentdragonlite to have the theme apply - + This change can take a few seconds. - + Some feedback about SilentDragonlite or Hush... - + or SilentDragonLite - + Send DenioD some private and shielded feedback about - + Paste HUSH URI - + Error paying HUSH URI - + View Payment Request - + View Memo Visualizza memo - + Reply to - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Crea nuovo t-Addr - + Copy Address - + Address has been previously used - + Address is unused @@ -995,47 +1196,36 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Solo gli indirizzi shielded (z-address) possono avere le memo - Memos can only be used with z-addresses - Le memos possono essere utilizzate solo con z-addresses (Shielded) + Le memos possono essere utilizzate solo con z-addresses (Shielded) - The memo field can only be used with a z-address. - Il campo memo può essere utilizzato solo con z-address (Shielded) + Il campo memo può essere utilizzato solo con z-address (Shielded) - doesn't look like a z-address - Non sembra uno z-address (Shielded) + Non sembra uno z-address (Shielded) - + + Please wait... - + Computing your transaction - + + Done! - - - Not enough available funds to send this transaction - -Have: %1 -Need: %2 - -Note: Funds need 5 confirmations before they can be spent - - Change from Controllare se opportuno inserire Mittente @@ -1052,20 +1242,100 @@ Note: Funds need 5 confirmations before they can be spent L'indirizzo selezionato non è valido - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address Indirizzo Destinatario - + + + is Invalid non valido - + + + Amount for address '%1' is invalid! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + MemoDialog @@ -1124,11 +1394,6 @@ Note: Funds need 5 confirmations before they can be spent MobileAppConnector - - - Connect Mobile App - - QR Code @@ -1149,6 +1414,11 @@ Note: Funds need 5 confirmations before they can be spent Scan this QRCode from your silentdragon companion app to connect your phone + + + Mobile Connector App + + silentdragon Companion App @@ -1176,6 +1446,14 @@ Note: Funds need 5 confirmations before they can be spent + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1189,7 +1467,7 @@ Note: Funds need 5 confirmations before they can be spent - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it @@ -1197,17 +1475,17 @@ Note: Funds need 5 confirmations before they can be spent NewSeedPage - + Error creating a wallet - + Failed to save wallet - + Couldn't save the wallet @@ -1327,33 +1605,40 @@ Non è stato avviato hushd integrato perché è stato passato il comando --no-em Connesso a hushd - There was an error connecting to hushd. The error was - Si è verificato un errore durante la connessione a hushd. L'errore era + Si è verificato un errore durante la connessione a hushd. L'errore era - - + + + + The transaction with id La transazione con id - - + + + + failed. The error was fallito. l'errore era - + + + - + failed fallito - + + + - + Tx Tx @@ -1362,29 +1647,35 @@ Non è stato avviato hushd integrato perché è stato passato il comando --no-em computazione Tx. Questo può richiedere diversi minuti. - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? - + No updates available - + You already have the latest release v%1 - + + Please wait for SilentDragonLite to exit @@ -1394,7 +1685,8 @@ Would you like to visit the releases page? Si prega di attendere che silentdragon finisca la procedura di uscita - + + Waiting for hushd to exit vedi appunto precedente Attendere l'uscita di hushd @@ -1431,61 +1723,69 @@ Impostare host/porta e utente/password nel menu Modifica-> Impostazioni.Il tuo hushd si sta avviando. Attendere prego. - + Attempting to initialize library with - + Using existing wallet. - + Create/restore wallet. - - + + Connection Error Errore di Connessione - - - + + + + + Transaction Error Errore di transazione - + There was an error sending the transaction. The error was: Si è verificato un errore durante l'invio della transazione. L'errore era: - - + + No Connection Nessuna connessione - + Pick - + + + Address or Label Error - + + + Address or Label cannot be empty - + + + Address Format Error Errore nel formato dell'indirizzo @@ -1494,57 +1794,71 @@ Impostare host/porta e utente/password nel menu Modifica-> Impostazioni. Non sembra un indirizzo hush Valido. - + + + %1 doesn't seem to be a valid hush address. - + Label Error - + The label '%1' already exists. Please remove the existing label. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book - + Unable to open file Impossibile aprire il file - + Address Book Import Done - + Imported %1 new Address book entries - + Copy address Copia indirizzo - + Copied to clipboard Copiato negli appunti - + Delete label elimina l'etichetta - + Tx submitted (right click to copy) txid: Tx inviato (clic destro per copiare) txid: @@ -1645,7 +1959,7 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat RecurringDialog - Dialog + Reccuring Dialog @@ -1701,7 +2015,7 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat RecurringPayments - Payments + Reocurring Payments @@ -1758,7 +2072,7 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat RecurringPending - Dialog + Recurring Multiple Payments @@ -1825,57 +2139,57 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat - + AddressBook - + Request From - + My Address - + Amount in - + z address - + Amount - + The recipient will see this address in the "to" field when they pay your request. - + Amount USD - + Memo Memo - + TextLabel - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. @@ -1914,7 +2228,7 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat RestoreSeedForm - Form + Restore Wallet Seed @@ -1946,38 +2260,38 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat RestoreSeedPage - - + + Failed to restore wallet - + SilentDragonLite needs 24 words to restore wallet - + Failed to parse wallet birthday - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. - + Couldn't restore the wallet - + Failed to save wallet - + Couldn't save the wallet @@ -1985,7 +2299,7 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat Settings - + Settings Impostazioni @@ -2010,12 +2324,37 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat RPC Password - + Options Opzioni - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Check github for updates at startup @@ -2024,107 +2363,87 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat Le transazioni Shielded vengono salvate localmente e visualizzate nella scheda delle transazioni. Se deselezioni questa opzione, le transazioni Shielded non verranno visualizzate nella scheda delle transazioni. - + Connect to github on startup to check for updates - + Connect to the internet to fetch hush prices - + Theme - + Lightwallet Server - - default - - - - + Connection - - blue - - - - - light - - - - - dark - - - - + Fetch hush prices - + Currency - + AUD - + BTC - + CAD - + CHF - + CNY - + EUR - + GBP - + INR - + RUB - + USD @@ -2259,27 +2578,116 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat Rubrica - + Add New Address Aggiungi Nuovo Indirizzo - + Address (z-Addr or t-Addr) Indirizzo (z-Addr or t-Addr) - - Label - Etichetta + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Etichetta + + + Add to Address Book Aggiungi a Rubrica - + Import Address Book @@ -2373,31 +2781,131 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + + + encryptionDialog - + Encrypt Your Wallet - - Encryption Password: + + Encryption Passphrase: - - Confirm Password: + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> - - Passwords don't match + + Confirm Passphrase: - - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + hushrequest + + + Request Payment + + + + + TextLabel + + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + + + + + Request From + + + + + zaddr + + + + + Amount in + + + + + Amount + + + + + Amount USD + + + + + Memo + Memo + + + + My Address + + + + + The recipient will see this address in the "to" field when they pay your request. @@ -2449,6 +2957,180 @@ Avete fondi non confermati o il saldo è troppo basso per una migrazione automat Memo + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Annulla + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + zboard diff --git a/res/silentdragonlite_pt.ts b/res/silentdragonlite_pt.ts index 0394c5c..515b835 100644 --- a/res/silentdragonlite_pt.ts +++ b/res/silentdragonlite_pt.ts @@ -4,29 +4,80 @@ AddressBookModel - + Label Etiqueta - + Address Endereço + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Endereço - + Amount Quantia + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog @@ -34,43 +85,47 @@ silentdragon - + SilentDragonLite SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - A iniciar + A iniciar Controller - + Wallet Password Palavra passe da carteira - + Your wallet is encrypted. Please enter your wallet password A sua carteira está encriptada. Por favor digite a palavra passe. - - + + Wallet Decryption Failed Falhou a decriptação da carteira - + Please enter a valid password Por favor digite uma palavra passe válida - + Failed to unlock wallet Falha ao desbloquear a carteira @@ -78,31 +133,187 @@ Please enter your wallet password CreateWalletForm - Form - Formato + Formato - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed Recuperar a carteira a partir da semente - + Restore an existing wallet, using the 24-word seed. Recuperar uma carteira existente, a partir da semente de 24 palavras. - - Create a new Wallet - Criar uma nova carteira + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + Criar uma nova carteira + + + Create a new wallet with a randomly generated seed. A sua carteira não está encriptada com uma palavra passe. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + Cancelar + + + + Add Contact and Send Request + + + MainWindow @@ -110,32 +321,32 @@ Please enter your wallet password silentdragon - + Balance Saldo - + Summary Sumário - + Shielded Blindado - + Notarized Reconhecido - + Transparent Transparente - + Total Total @@ -144,13 +355,13 @@ Please enter your wallet password Algumas transações ainda não estão confirmadas - + Address Balances Balanço dos Endereços - - + + Send Enviar @@ -163,220 +374,267 @@ Please enter your wallet password Saldo do Endereço - + Send To Enviar para - + Recipient Destinatário - - - + + + Address Endereço - + Address Book Agenda - - + + Amount Quantidade - + Max Available Máximo disponível - - - + + + Memo Memo - + Add Recipient Adicionar destinatário - Recurring payment - Pagamento recorrente + Pagamento recorrente - Every month, starting 12-May-2012, for 6 payments - Todos os meses, desde 12-Maio-2012, em 6 pagamentos + Todos os meses, desde 12-Maio-2012, em 6 pagamentos - Edit Schedule - Editar agendamento + Editar agendamento - + Miner Fee Taxa de mineração - + 0 0 - + Cancel Cancelar - + Receive Receber - + Address Type Tipo de Endereço - + Version hushlightd Versão de hushlightd - + &Send DenioD Feedback Enviar avaliação para DenioD - + &Export seed phrase Exportar frase semente - + Encrypt Wallet Encriptar carteira - + Remove Wallet Encryption Remover encriptação da carteira - + Rescan Redigitalizar - + &Hush Discord Discord da Hush - + + Deposit Hush + + + + Information about Hush Informação sobre a Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> <html><head/><body><p align="center"><span style=" font-weight:600;">Informação da Blockchain da Hush</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> <html><head/><body><p align="center">|</p></body></html> - + Next Halving Próximo Halving - + Difficulty Dificuldade - + Last Notarized Block Último bloco reconhecido - + Total Supply Provisão total - + Longestchain Cadeia mais comprida - + BlockHeight Altura dos blocos - + Supply zAddr Forneça zAddr - + Supply tAddr Forneça tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> <html><head/><body><p align="center"><span style=" font-weight:600;">Informação do mercado da Hush</span></p></body></html> - + Market Cap Capital de mercado - + Volume on Exchanges Volume nas bolsas - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> <html><head/><body><p align="center">Esta é uma carteira light, não consegue minerar!</p></body></html> - + + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + + E&xit + + + + &Hush Website Site da Hush @@ -385,7 +643,7 @@ Please enter your wallet password z-Addr(Jovem) - + t-Addr t-Addr @@ -398,73 +656,73 @@ Please enter your wallet password Novo Endereço - + Label Etiqueta - + Update Label Atualizar - + Address balance Balanço do endereço - + Optional Opcional - - + + Export Private Key Exportar Chave Privada - + z-Addr z-Addr - + SilentDragonLite SilentDragonLite - + Your node is still syncing, balances may not be updated. O seu nó ainda está em sincronia, os balanços apresentados podem não estar correctos. - + Some transactions are not yet confirmed. Balances may change. Algumas transacções ainda estão por confirmar. Os balanços podem mudar. - + Total notarized funds available: Total de fundos verificados disponíveis: - + Next Address Próximo Endereço - + Your node is still syncing, balances may not be updated O seu nó ainda está em sincronia, os balanços podem não estar correctos - + View All Addresses Ver Todos os Endereços - + Transactions Transações @@ -477,18 +735,18 @@ Please enter your wallet password Isto é uma carteira light, não consegue minerar! Não está a minar - - - - - - - - - - - - + + + + + + + + + + + + Loading... A carregar... @@ -501,7 +759,7 @@ Please enter your wallet password Taxa de soluções da rede - + Vendor Fornecedor @@ -510,42 +768,41 @@ Please enter your wallet password | - + &File &Ficheiro - + &Help &Ajuda - + &Apps &Aplicações - + &Edit &Editar - &Exit - Sair + Sair - + &About &Sobre - + &Settings &Opções - + Ctrl+P Ctrl+P @@ -554,7 +811,7 @@ Please enter your wallet password &Doar - + Check github.com for &updates &Verificar github.com por actualizações @@ -571,7 +828,7 @@ Please enter your wallet password &Importar chave privada - + &Export all private keys &Exportar todas as chaves privadas @@ -584,12 +841,12 @@ Please enter your wallet password Ctrl+A, Ctrl+Z - + Address &book &Livro de Endereços - + Ctrl+B Ctrl+B @@ -598,38 +855,38 @@ Please enter your wallet password &Guardar wallet.dat - - + + Export transactions Exportar transacções - + Pay hush &URI... Pagar através de &URI hush... - + Connect mobile &app Conectar &aplicação móvel - + Ctrl+M Ctrl+M - + &Recurring Payments &Pagamentos recorrentes - + Request hush... Pedir hush... - + File a bug... Denunciar um bug... @@ -666,17 +923,38 @@ Please enter your wallet password Re-escan de chave privada completo - + URI should be of the form 'hush:<addr>?amt=x&memo=y O URI deve ter a forma 'hush:<addr>?amt=x&memo=y - + View tx on block explorer Ver tx no explorador de blocos - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Refresh Actualizar @@ -689,12 +967,12 @@ Please enter your wallet password As chaves serão importadas em seu nó hushd conectado - + Error Erro - + Error exporting transactions, file was not saved Erro a exportar transacções, ficheiro não guardado @@ -727,150 +1005,137 @@ Please enter your wallet password Você precisar salvá-lo manualmente. - + These are all the private keys for all the addresses in your wallet YOUR_TRANSLATION_HERE - + Private key for Chave privada para - - + + Save File Salvar Arquivo - Wallet is already encrypted - A carteira já se encontra encriptada + A carteira já se encontra encriptada - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - A carteira já se encontra encriptada com uma palavra passe. + A carteira já se encontra encriptada com uma palavra passe. Por favor usa 'Desencriptar carteira' se quiser remover a encriptação da carteira. - + Passwords don't match As palavras passes não correspondem - Error was: - Erro era: + Erro era: - Wallet Encrypted - Cartera encriptada + Cartera encriptada - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - A tua carteira foi encriptada com sucesso! A palavra passe vai ser precisa para enviar fundos ou exportar as chaves privadas. + A tua carteira foi encriptada com sucesso! A palavra passe vai ser precisa para enviar fundos ou exportar as chaves privadas. - - + + Wallet Encryption Failed Falhou a desencriptação da carteira - + Wallet is not encrypted A carteira não está encriptada - Your wallet is not encrypted with a password. - A sua carteira não está encriptada com uma palavra passe. + A sua carteira não está encriptada com uma palavra passe. - Wallet Password - Palavra passe da carteira + Palavra passe da carteira - Please enter your wallet password - Por favor digite a palavra passe da carteira + Por favor digite a palavra passe da carteira - - - Wallet Decryption Failed - Falhou a desencriptação da carteira + Falhou a desencriptação da carteira - Please enter a password to decrypt your wallet! - Por favor digite a palavra passe para desencriptar a carteira! + Por favor digite a palavra passe para desencriptar a carteira! - Wallet Encryption Removed - Encriptação da carteira removida + Encriptação da carteira removida - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - A carteira foi desencriptada com sucesso! Não será mais necessário a palavra passe para enviar fundos ou + A carteira foi desencriptada com sucesso! Não será mais necessário a palavra passe para enviar fundos ou exportar as chaves privadas - - + + Copy block explorer link Copiar link do explorador de blocos - + Currency Change Mudar de moeda - + This is your wallet seed. Please back it up carefully and safely. Esta é a semente da sua carteira. Por favor, guarde-a em segurança. - - + + Unable to open file Não foi possível abrir o arquivo - + Error getting private keys Erro ao obter as chaves privadas - + Error loading private keys: Erro ao carregar as chaves privadas: - - + + Copy address Copiar endereço - - - + + + + Copied to clipboard Copiado - + Get private key Obter chave privada @@ -879,8 +1144,8 @@ Por favor usa 'Desencriptar carteira' se quiser remover a encriptaçã Proteger saldo para Sapling - - + + View on block explorer Ver no explorador de blocos @@ -889,83 +1154,93 @@ Por favor usa 'Desencriptar carteira' se quiser remover a encriptaçã Migrar para Sapling - - + + Copy txid Copiar txid - + Restart Reiniciar - + Please restart Silentdragonlite to have the theme apply Por favor reinicie a SilentDragonLite para aplicar o tema - + This change can take a few seconds. As alterações podem demorar alguns segundos. - + Some feedback about SilentDragonlite or Hush... Alguma sugestão acerca da SilentDragonlite ou Hush... - + or SilentDragonLite ou SilentDragonLite - + Send DenioD some private and shielded feedback about Enviar ao DenioD alguma sugestão privada e protegida acerca - + Paste HUSH URI Colar URI HUSH - + Error paying HUSH URI Erro ao pagar HUSH URI - + View Payment Request Ver o requerimento de pagamento - + View Memo Ver Memo - + Reply to Responder para - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Criar novo t-Addr - + Copy Address Copiar Endereço - + Address has been previously used Endereço foi usado anteriormente - + Address is unused Endereço inutilizado @@ -990,48 +1265,46 @@ Por favor usa 'Desencriptar carteira' se quiser remover a encriptaçã Apenas z-Addresses podem conter recados - Memos can only be used with z-addresses - Memos só podem ser anexados com z-Addresses + Memos só podem ser anexados com z-Addresses - The memo field can only be used with a z-address. - O campo memo só pode ser usado com z-Addresses. + O campo memo só pode ser usado com z-Addresses. - doesn't look like a z-address - + não se parece com um z-Address - + + Please wait... Por favor, aguarde... - + Computing your transaction A calcular a sua transacção - + + Done! Feito! - Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - Fundos disponíveis insuficientes para enviar esta transacção + Fundos disponíveis insuficientes para enviar esta transacção Tem: %1 Precisa: %2 @@ -1052,20 +1325,107 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos Endereço de partida inválido - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address Endereço destinatário - + + + is Invalid é Inválido - + + + Amount for address '%1' is invalid! Quantia para o endereço '%1' é inválido! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + Fundos disponíveis insuficientes para enviar esta transacção + +Tem: %1 +Precisa: %2 + +Nota: Os fundos precisam de 5 confirmações para serem gastos {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + MemoDialog @@ -1125,9 +1485,8 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos MobileAppConnector - Connect Mobile App - Conectar aplicação móvel + Conectar aplicação móvel @@ -1135,9 +1494,8 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos Código QR - Conection String - String de Conexão + String de Conexão @@ -1149,6 +1507,16 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos Scan this QRCode from your silentdragon companion app to connect your phone Digitalizar este QRCode na sua aplicação Silentdragon Companion para conectar o seu dispositivo móvel + + + Mobile Connector App + + + + + Connection String + + silentdragon Companion App @@ -1176,6 +1544,14 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos Tipo de Conexão + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1189,7 +1565,7 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos Esta é a semente da tua carteira. POR FAVOR GUARDA-A. - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it A frase semente é a ÚNICA maneira de recuperar a carteira. Se a perderes, NÃO HÁ QUALQUER MANEIRA DE A RECUPERARES JUNTAMENTE COM OS TEUS FUNDOS @@ -1197,17 +1573,17 @@ Nota: Os fundos precisam de 5 confirmações para serem gastos NewSeedPage - + Error creating a wallet Erro ao criar carteira - + Failed to save wallet Falha ao guardar carteira - + Couldn't save the wallet Não foi possível guardar a carteira @@ -1326,33 +1702,40 @@ Não iniciando hushd embebido porque nenhum foi passado como parâmetroConectado ao hushd - There was an error connecting to hushd. The error was - Ocorreu um erro conectando ao hushd. O erro foi + Ocorreu um erro conectando ao hushd. O erro foi - - + + + + The transaction with id A transação com id - - + + + + failed. The error was falhou. O erro foi - + + + - + failed falhou - + + + - + Tx Tx @@ -1361,29 +1744,35 @@ Não iniciando hushd embebido porque nenhum foi passado como parâmetro gerando transação. Isso pode levar alguns minutos. - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available Actualização disponível - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? Uma nova versão v%1 estã disponível! Tu tens v%2. - + No updates available Não há actualizações disponíveis - + You already have the latest release v%1 Você já tem a última release v%1 - + + Please wait for SilentDragonLite to exit Por favor aguarde pela SilentDragonLite terminar @@ -1392,7 +1781,8 @@ Would you like to visit the releases page? Por favor aguarde pela SilentDragonLite terminar - + + Waiting for hushd to exit Por favor aguarde pela hushd terminar @@ -1429,61 +1819,69 @@ Por favor, coloque o host/porta e usuário/senha no menu Editar>Preferências Seu hushd está iniciando. Por favor aguarde. - + Attempting to initialize library with A tentar iniciar a biblioteca com - + Using existing wallet. A usar a carteira existente. - + Create/restore wallet. Criar/recuperar carteira. - - + + Connection Error Erro na Conexão - - - + + + + + Transaction Error Erro na transacção - + There was an error sending the transaction. The error was: Ocorreu um erro enviando a transacção. O erro foi: - - + + No Connection Sem Conexão - + Pick Escolha - + + + Address or Label Error Erro de Endereço ou Label - + + + Address or Label cannot be empty Endereço ou Label não podem estar vazios - + + + Address Format Error Erro no Formato do Endereço @@ -1492,57 +1890,71 @@ Por favor, coloque o host/porta e usuário/senha no menu Editar>Preferências não parece um endereço válido de hush. - + + + %1 doesn't seem to be a valid hush address. não parece um endereço válido de hush. - + Label Error Erro de Label - + The label '%1' already exists. Please remove the existing label. A label '%1' já existe. Por favor remove a label existente. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Importar Livro de Endereços - + Unable to open file Não foi possível abrir o arquivo - + Address Book Import Done - + Imported %1 new Address book entries - + Copy address Copiar endereço - + Copied to clipboard Copiado - + Delete label Apagar - + Tx submitted (right click to copy) txid: Tx enviada (botão-direito para copiar) txid: @@ -1642,9 +2054,13 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç RecurringDialog - Dialog - Diálogo + Diálogo + + + + Reccuring Dialog + @@ -1698,9 +2114,13 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç RecurringPayments - Payments - Pagamentos + Pagamentos + + + + Reocurring Payments + @@ -1755,9 +2175,13 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç RecurringPending - Dialog - Diálogo + Diálogo + + + + Recurring Multiple Payments + @@ -1823,57 +2247,57 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç Pedir pagamento - + AddressBook Livro de endereços - + Request From Pedir desde - + My Address O meu endereço - + Amount in Quantia em - + z address Endereço z - + Amount Quantidade - + The recipient will see this address in the "to" field when they pay your request. O destinatários irá ver este endereço no campo "para" quando pagarem o teu pedido. - + Amount USD Quantia em USD - + Memo Memo - + TextLabel Label de texto - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Pedir pagamento de um endereço Sapling. Irá enviar 0.0001 hush para o endereço com o pagamento hush URI. O memo irá ser incluído na transacção quando o endereço te pagar. @@ -1912,9 +2336,13 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç RestoreSeedForm - Form - Formato + Formato + + + + Restore Wallet Seed + @@ -1945,38 +2373,38 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç RestoreSeedPage - - + + Failed to restore wallet Falha a recuperar carteira - + SilentDragonLite needs 24 words to restore wallet SilentDragonLite precisa de 24 palavras para recuperar a carteira - + Failed to parse wallet birthday Falha ao analisar aniversário da carteira - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. Não foi possível perceber o aniversário da carteira. Isto deve ser uma altura de bloco donde se verifica a carteira. Pode deixá-la como '0' se não souber o que pôr. - + Couldn't restore the wallet Não foi possível recuperar a carteira - + Failed to save wallet Falha ao guardar carteira - + Couldn't save the wallet Não foi possível guardar a carteira @@ -1984,7 +2412,7 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç Settings - + Settings Opções @@ -2009,12 +2437,37 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç RPC-Senha - + Options Opções - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Check github for updates at startup Verificar github por actualizações no início @@ -2023,107 +2476,103 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç Transações blindadas são salvas localmente e exibidas na aba de transações. Se desmarcado, transações blindadas não aparecerão na aba de transações. - + Connect to github on startup to check for updates Conectar ao github no arranque para verificar actualizações - + Connect to the internet to fetch hush prices Ligar á internet para vêr os preços da hush - + Theme Tema - + Lightwallet Server Servidor da Lightwallet - default - padrão + padrão - + Connection Conexão - blue - azul + azul - light - claro + claro - dark - escuro + escuro - + Fetch hush prices Verificar preços da hush - + Currency moeda - + AUD AUD - + BTC BTC - + CAD CAD - + CHF CHF - + CNY CNY - + EUR EUR - + GBP GBP - + INR INR - + RUB RUB - + USD USD @@ -2256,27 +2705,116 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç Livro de Endereços - + Add New Address Adicionar Novo Endereço - + Address (z-Addr or t-Addr) Endereço (z-Addr ou t-Addr) - - Label - Etiqueta + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Etiqueta + + + Add to Address Book Adicionar a Agenda - + Import Address Book Importar livro de endereços @@ -2370,35 +2908,152 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç Por favor note que vai ser preciso ter o serviço Tor configurado na porta 9050 + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Copiar Endereço + + encryptionDialog - + Encrypt Your Wallet Encripte a Sua Carteira - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - Palavra Passe de Encriptação + Palavra Passe de Encriptação - Confirm Password: - Confirmar Palavra Passe + Confirmar Palavra Passe - Passwords don't match - Palavra Passes não correspondem + Palavra Passes não correspondem - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - AVISO: Se se esquecer da sua palavra passe, a única maneira de recuperar a sua carteira é com a frase- + AVISO: Se se esquecer da sua palavra passe, a única maneira de recuperar a sua carteira é com a frase- semente. + + hushrequest + + + Request Payment + + + + + TextLabel + + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Pedir pagamento de um endereço Sapling. Irá enviar 0.0001 hush para o endereço com o pagamento hush URI. O memo irá + ser incluído na transacção quando o endereço te pagar. + + + + Request From + Pedir desde + + + + zaddr + + + + + Amount in + Quantia em + + + + Amount + + + + + Amount USD + Quantia em USD + + + + Memo + + + + + My Address + O meu endereço + + + + The recipient will see this address in the "to" field when they pay your request. + O destinatários irá ver este endereço no campo "para" quando pagarem o teu pedido. + + newRecurringDialog @@ -2447,6 +3102,180 @@ Você possui fundos não confirmados ou o saldo é muito baixo para uma migraç Memo + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Cancelar + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + zboard diff --git a/res/silentdragonlite_sr.ts b/res/silentdragonlite_sr.ts index c965670..df26e36 100644 --- a/res/silentdragonlite_sr.ts +++ b/res/silentdragonlite_sr.ts @@ -4,69 +4,124 @@ AddressBookModel - + Label Oznaka - + Address Adresa + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Adresa - + Amount Količina + + ChatBubbleMe + + + Form + Od + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + Od + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog - + SilentDragonLite SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - Početak + Početak Controller - + Wallet Password Lozinka novčanika - + Your wallet is encrypted. Please enter your wallet password Vaš novčanik je šifrovan. Molimo unesite vašu lozinku - - + + Wallet Decryption Failed Dešifriranje novčanika neuspelo - + Please enter a valid password Molimo unesite valjanu lozinku - + Failed to unlock wallet Neuspeh prilikom otključavanja novčanika @@ -74,284 +129,442 @@ Molimo unesite vašu lozinku CreateWalletForm - Form - Od + Od - + + Create New SDL Wallet + + + + + Confirm Passphrase: + + + + Restore wallet from seed Vraćanje novčanika u početno stanje iz seed reči - + Restore an existing wallet, using the 24-word seed. Vratite postojeći novčanik u početno stanje koristeći seed od 24 reči. - - Create a new Wallet - Napravite novi novčanik + + Create a new wallet + - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new Wallet + Napravite novi novčanik + + + Create a new wallet with a randomly generated seed. Napravite novi novčanik sa nasumično odabranim seed rečima. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + Odustani + + + + Add Contact and Send Request + + + MainWindow - + SilentDragonLite SilentDragonLite - + Balance Saldo - + Summary Rezime - + Shielded Zaštićeno - + Notarized Potvrđeno - + Transparent Transparentno - + Total Ukupno - + Your node is still syncing, balances may not be updated. Vaš čvor se još uvijek sinhronizuje, saldo neće biti ažuriran. - + Some transactions are not yet confirmed. Balances may change. Neke transakcije još nisu potvrđene. Saldo se može promeniti. - + + Deposit Hush + + + + Address Balances Saldo adrese - - + + Send Šalji - + Total notarized funds available: Ukupna dostupna potvrđena sredstva: - + Send To Pošalji - + Recipient Primalac - - - + + + Address Adresa - + Address Book Adresar - - + + Amount Količina - + Max Available Max dostupno - - - + + + Memo Poruka (memo) - + Add Recipient Dodaj primaoca - Recurring payment - Ponavljajuće plaćanje + Ponavljajuće plaćanje - Every month, starting 12-May-2012, for 6 payments - Svaki mesec s početkom 12-Maja-2012, u 6 rata + Svaki mesec s početkom 12-Maja-2012, u 6 rata - Edit Schedule - Uredi raspored + Uredi raspored - + Miner Fee Naknada za rudarenje - + 0 0 - + Cancel Odustani - + Receive Primiti - + Address Type Vrsta adrese - + z-Addr z-Adr - + t-Addr t-Adr - + Next Address - + Information about Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving - + Difficulty - + Last Notarized Block - + Total Supply - + Longestchain - + BlockHeight - + Supply zAddr - + Supply tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> - + Market Cap - + Volume on Exchanges - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> @@ -360,43 +573,43 @@ Molimo unesite vašu lozinku Nova adresa - + View All Addresses Pogledaj sve adrese - + Label Oznaka - + Update Label Ažuriraj oznaku - + Address balance Saldo na adresi - + Optional Opciono - - + + Export Private Key Izvoz privatnog ključa - + Your node is still syncing, balances may not be updated Vaš čvor se još uvijek sinhronizuje, saldo neće biti ažuriran - + Transactions Transakcije @@ -409,18 +622,18 @@ Molimo unesite vašu lozinku Ovo je LaganiNovčanik, s njim ne možete rudariti! - - - - - - - - - - - - + + + + + + + + + + + + Loading... Učitavanje... @@ -429,12 +642,12 @@ Molimo unesite vašu lozinku visinaBloka - + Version hushlightd Verzija hushlightd - + Vendor Prodavač @@ -444,251 +657,277 @@ Molimo unesite vašu lozinku + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &File &Datoteka - + &Help &Pomoć - + &Apps &Apps - + &Edit &Uredi - + E&xit &Izlaz - + &About &O - + &Settings &Podešavanja - + Ctrl+P Ctrl+P - + &Send DenioD Feedback &Pošalji DenioD povratne informacije - + &Hush Discord &Hush Discord - + &Hush Website &Hush Web stranica - + Check github.com for &updates Proveri na github.com &dopune - + &Export all private keys &Izvoz svih privatnih ključeva - + Address &book Adresna &knjiga - + Ctrl+B Ctrl+B - + &Export seed phrase &Izvoz seed fraze - - + + Export transactions Izvoz transakcija - + Pay hush &URI... Plati hush &URI... - + Connect mobile &app Spoji mobilnu &app - + Ctrl+M Ctrl+M - + &Recurring Payments &Ponavljajuća plaćanja - + Request hush... Zatraži hush... - + File a bug... Prijavi grešku... - + Encrypt Wallet Šifriraj novčanik - + Remove Wallet Encryption Uklonite šifrovanje novčanika - + Rescan Rescan - Wallet is already encrypted - Novčanik je već šifrovan + Novčanik je već šifrovan - Your wallet is already encrypted with a password. Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - Vaš novčanik je već šifrovan lozinkom. + Vaš novčanik je već šifrovan lozinkom. Molimo koristite 'Uklonite šifrovanje novčanika' ako želite ukloniti šifrovanje novčanika. - + Passwords don't match Lozinke se ne podudaraju - Error was: - Greška je : + Greška je : - Wallet Encrypted - Novčanik šifrovan + Novčanik šifrovan - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - Vaš novčanik je uspješno šifrovan! Lozinka će vam trebati za slanje sredstava ili za izvoz privatnih ključeva. + Vaš novčanik je uspješno šifrovan! Lozinka će vam trebati za slanje sredstava ili za izvoz privatnih ključeva. - - + + Wallet Encryption Failed Šifrovanje novčanika neuspelo - + Wallet is not encrypted Novčanik nije šifrovan - Your wallet is not encrypted with a password. - Vaš novčanik nije šifrovan sa lozinkom. + Vaš novčanik nije šifrovan sa lozinkom. - Wallet Password - Lozinka novčanika + Lozinka novčanika - Please enter your wallet password - Molimo unesite lozinku novčanika + Molimo unesite lozinku novčanika - - - Wallet Decryption Failed - Dešifrovanje novčanika neuspelo + Dešifrovanje novčanika neuspelo - Please enter a password to decrypt your wallet! - Molimo unesite lozinku za dešifrovanje novčanika! + Molimo unesite lozinku za dešifrovanje novčanika! - Wallet Encryption Removed - Šifrovanje novčanika uklonjeno + Šifrovanje novčanika uklonjeno - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - Vaš novčanik je uspešno dešifrovan! Lozinka vam više neće trebati za slanje sredstava ili za izvoz privatnih ključeva. + Vaš novčanik je uspešno dešifrovan! Lozinka vam više neće trebati za slanje sredstava ili za izvoz privatnih ključeva. - - + + Copy txid Kopitajte txid - - + + Copy block explorer link - + View tx on block explorer Pogledaj tx na blok pregledaču - + Refresh Osveži - + Restart Ponovo pokreni - + Please restart Silentdragonlite to have the theme apply Molimo ponovo pokrenite SilentDragonLite ako želite primeniti temu - + Currency Change Razmena valuta @@ -697,12 +936,12 @@ Molimo koristite 'Uklonite šifrovanje novčanika' ako želite uklonit Molimo ponovo pokrenite SilentDragonLite ako želite primeniti novu valutu - + This change can take a few seconds. - + Some feedback about SilentDragonlite or Hush... Neke povratne informacije o SilentDragonLite ili Hush... @@ -711,133 +950,165 @@ Molimo koristite 'Uklonite šifrovanje novčanika' ako želite uklonit Pošaljite Duke neku privatnu i zaštićenu povratnu informaciju - + or SilentDragonLite ili SilentDragonLite - + Send DenioD some private and shielded feedback about - + Paste HUSH URI Zalepi HUSH URI - + Error paying HUSH URI Greška u plaćanju HUSH URI - + URI should be of the form 'hush:<addr>?amt=x&memo=y URI treba biti formata 'hush:<addr>?amt=x&memo=y - + Error Greška - + Error exporting transactions, file was not saved Greška prilikom izvoza transakcija, datoteka nije spremljena - + This is your wallet seed. Please back it up carefully and safely. Ovo je vaš seed novčanika. Molimo izradite rezervnu kopiju. - - + + Save File Spremi datoteku - - + + Unable to open file Nije moguće otvoriti datoteku - + Error getting private keys Greška u dohvaćanju privatnih ključeva - + Error loading private keys: Greška prilikom učitavanja privatnog ključa: - + These are all the private keys for all the addresses in your wallet Ovo su svi privatni ključevi svih adresa u vašem novčaniku - + Private key for Privatni ključ za - - + + Copy address Kopirajte adresu - - - + + + + Copied to clipboard Kopirano u mađuspremnik - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key Dobavi privatni ključ - - + + View on block explorer Pogledaj na blok pregledaču - + View Payment Request Pogledajte zahtjev o plaćanju - + View Memo Pogledajte poruku (memo) - + Reply to Odgovorite - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Napravljena je nova transparentna adresa - + Copy Address Kopirajte adresu - + Address has been previously used Adresa je već korištena - + Address is unused Adresa nije korištena @@ -862,22 +1133,19 @@ Molimo koristite 'Uklonite šifrovanje novčanika' ako želite uklonit Samo z-adrese mogu imati poruke - Memos can only be used with z-addresses - Poruke se mogu koristiti samo sa z-adresama + Poruke se mogu koristiti samo sa z-adresama - The memo field can only be used with a z-address. - Prostor za poruku se može koristiti samo sa z-adresom. + Prostor za poruku se može koristiti samo sa z-adresom. - doesn't look like a z-address - + ne izgleda kao z-adresa @@ -886,44 +1154,132 @@ ne izgleda kao z-adresa Greška u transakciji - + + Please wait... Molimo pričekajte... - + Computing your transaction Računamo vašu transakciju - + + Done! Gotovo! - + + + Recipient Address Adresa primatelja - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + is Invalid je neispravna - + + + Amount for address '%1' is invalid! Količina za adresu '%1' je nevaljala! - + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + Nema dovoljno dostupnih sredstava za slanje transakcije + +Imate: %1 +Trebate: %2 + +Opaska: Za trošenje sredstava potrebno je 5 konfirmacija {1 +?} {2 +?} {1 ?} + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + + Not enough available funds to send this transaction Have: %1 Need: %2 Note: Funds need 5 confirmations before they can be spent - Nema dovoljno dostupnih sredstava za slanje transakcije + Nema dovoljno dostupnih sredstava za slanje transakcije Imate: %1 Trebate: %2 @@ -989,9 +1345,13 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija MobileAppConnector - Connect Mobile App - Spojite mobilnu applikaciju + Spojite mobilnu applikaciju + + + + Mobile Connector App + @@ -1040,6 +1400,14 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija Vrsta veze: + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1053,7 +1421,7 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija Ovo je vaša nova seed fraza novčanika. MOLIMO SIGURNO JU SPREMITE. - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it Jedino je pomoću seed fraze moguće ponovo obnoviti novčanik. Ako zaboravite seed frazu, NE POSTOJI NAČIN DA PONOVO OBNOVITE NOVČANIK I SREDSTVA unutra @@ -1061,17 +1429,17 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija NewSeedPage - + Error creating a wallet Greška u kreiranju novčanika - + Failed to save wallet Neuspelo spremanje novčanika - + Couldn't save the wallet Ne mogu spremiti novčanik @@ -1087,152 +1455,186 @@ Opaska: Za trošenje sredstava potrebno je 5 konfirmacija QObject - + Pick Odaberite - + + + Address or Label Error Greška u adresi ili oznaci - + + + Address or Label cannot be empty Adresa ili oznaka ne može biti prazno - + + + Address Format Error Greška u formatu adrese - + + + %1 doesn't seem to be a valid hush address. %1 čini se da nije valjana hush adresa. - + Label Error Greška oznake - + The label '%1' already exists. Please remove the existing label. Oznaka %1 već postoji.Molimo uklonite postojeću adresu. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Uvezite adresar - + Unable to open file Nije moguće otvoriti datoteku - + Address Book Import Done Završen unos adresara - + Imported %1 new Address book entries Uvezeno %1 novih adresa - + Copy address Kopirajte adresu - + Copied to clipboard Kopirano u mađuspremnik - + Delete label Izbrišite oznaku - + Attempting to initialize library with Poušavam pokrenuti zbirku sa - + Using existing wallet. Koristim postojeći novčanik. - + Create/restore wallet. Napravi/obnovi novčanik. - - + + Connection Error Greška sa vezom - - - + + + + + Transaction Error Greška u transakciji - + There was an error sending the transaction. The error was: Pojavila se greška prilikom slanja transakcije. Greška je: - - + + No Connection Nema veze - There was an error connecting to hushd. The error was - Pojavila se greška prilikom spajanja na hushd. Greška je + Pojavila se greška prilikom spajanja na hushd. Greška je - + + + - + Tx Tx - + + + - + failed neuspelo - - + + + + The transaction with id Transakcija sa ID - - + + + + failed. The error was nesupela. Greška je - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available Dostupno ažuriranje - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1241,22 +1643,24 @@ Would you like to visit the releases page? Želite li posetiti stranicu sa izadnjima? - + No updates available Nema dostupnih ažuriranja - + You already have the latest release v%1 Već imate najnovije izdanje v%1 - + + Please wait for SilentDragonLite to exit Molimo pričekajte da se SilentDragonLite zatvori - + + Waiting for hushd to exit Čekam da hushd završi @@ -1292,7 +1696,7 @@ Would you like to visit the releases page? Sva buduća plaćanja će biti otkazana. - + Tx submitted (right click to copy) txid: Tx poslan (desni klik za kopiranje) txid: @@ -1347,9 +1751,13 @@ Would you like to visit the releases page? RecurringDialog - Dialog - Dialog + Dialog + + + + Reccuring Dialog + @@ -1403,9 +1811,13 @@ Would you like to visit the releases page? RecurringPayments - Payments - Plaćanja + Plaćanja + + + + Reocurring Payments + @@ -1460,9 +1872,13 @@ Would you like to visit the releases page? RecurringPending - Dialog - Dialog + Dialog + + + + Recurring Multiple Payments + @@ -1528,57 +1944,57 @@ Would you like to visit the releases page? Zahtev o plaćanju - + AddressBook Adresar - + Request From Zatraži od - + My Address Moja adresa - + Amount in Količina u - + z address z adresa - + Amount Količina - + The recipient will see this address in the "to" field when they pay your request. Primalac će prilikom plaćanja videti ovu adresu u "za" polju. - + Amount USD Količina USD - + Memo Poruka (memo) - + TextLabel TekstOznaka - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Zatraži plaćanje iz sapling adrese. Poslat ćete 0.0001 husha transakciju na adresu sa hush URI nalogom. Poruka (memo) će biti uključena u transakciji kada vas adresa plati. @@ -1616,9 +2032,13 @@ Would you like to visit the releases page? RestoreSeedForm - Form - Od + Od + + + + Restore Wallet Seed + @@ -1649,38 +2069,38 @@ Would you like to visit the releases page? RestoreSeedPage - - + + Failed to restore wallet Neuspelo obnavljanje novčanika - + SilentDragonLite needs 24 words to restore wallet SilentDragonLite treba 24 reči za obnovu novčanika - + Failed to parse wallet birthday Neuspelo očitanje rođendana novčanika - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. Nisam u mogućnosti razumeti rođendan novčanika. To bi trebala bi biti visina bloka od koje počinje rescan novčanika. Ako ne znate koja je, možete ostaviti '0'. - + Couldn't restore the wallet Nemoguće obnoviti novčanik - + Failed to save wallet Neuspeh spremanja novčanika - + Couldn't save the wallet Nemoguće spremiti novčanik @@ -1688,122 +2108,143 @@ Would you like to visit the releases page? Settings - + Settings Postavke - + Connection Veza - + Lightwallet Server Server LaganiNovčanik - + Options Opcije - default - početno + početno - blue - plavo + plavo - light - svetlo + svetlo - dark - tamno + tamno - + + Dark + + + + + Midnight + + + + + Light + + + + + Blue + + + + + Default + + + + Fetch hush prices Zatraži hush cene - + Check github for updates at startup Prilikom pokretanja proverite ažuriranja na githubu - + Connect to github on startup to check for updates Prilikom pokretanja proverite ažuriranja na githubu - + Theme Teme - + Connect to the internet to fetch hush prices Spoji se na Internet i dohvati hush cene - + Currency Valuta - + AUD AUD - + BTC BTC - + CAD CAD - + CHF CHF - + CNY CNY - + EUR EUR - + GBP GBP - + INR INR - + RUB - + USD USD @@ -1850,27 +2291,116 @@ Would you like to visit the releases page? Adresar - + Add New Address Dodaj novu adresu - + Address (z-Addr or t-Addr) Adresa (z-adresa ili t-adresa) - - Label - Oznaka + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Oznaka + + + Add to Address Book Dodaj u adresar - + Import Address Book Uvezite adresar @@ -1964,32 +2494,148 @@ Would you like to visit the releases page? <html><head/><body><p>Preskače najskuplje provere tokom početnog preuzimanja bloka. <a href="https://docs.silentdragon.co/using-silentdragon/#fastsync"><span style=" text-decoration: underline; color:#0000ff;">Saznaj više</span></a></p></body></html> + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Kopirajte adresu + + encryptionDialog - + Encrypt Your Wallet Šifrujte vaš novčanik - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + Encryption Password: - Lozinka šifrovanja: + Lozinka šifrovanja: - Confirm Password: - Potvrdite lozinku: + Potvrdite lozinku: - Passwords don't match - Lozinke se ne podudaraju + Lozinke se ne podudaraju - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. - UPOZORENJE: Ako zaboravite lozinku, jedini način da obnovite novčanik je iz seed fraze. + UPOZORENJE: Ako zaboravite lozinku, jedini način da obnovite novčanik je iz seed fraze. + + + + hushrequest + + + Request Payment + + + + + TextLabel + TekstOznaka + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Zatraži plaćanje iz sapling adrese. Poslat ćete 0.0001 husha transakciju na adresu sa hush URI nalogom. Poruka (memo) će biti uključena u transakciji kada vas adresa plati. + + + + Request From + Zatraži od + + + + zaddr + + + + + Amount in + Količina u + + + + Amount + Količina + + + + Amount USD + Količina USD + + + + Memo + Poruka (memo) + + + + My Address + Moja adresa + + + + The recipient will see this address in the "to" field when they pay your request. + Primalac će prilikom plaćanja videti ovu adresu u "za" polju. @@ -2041,4 +2687,178 @@ Would you like to visit the releases page? Broj uplata + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + Odustani + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + diff --git a/res/silentdragonlite_tr.ts b/res/silentdragonlite_tr.ts index b9c2ebf..ef5c01a 100644 --- a/res/silentdragonlite_tr.ts +++ b/res/silentdragonlite_tr.ts @@ -4,29 +4,80 @@ AddressBookModel - + Label Etiket - + Address Adres + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address Adres - + Amount Miktar + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog @@ -38,42 +89,46 @@ silentdragon - + SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - Başlatılıyor + Başlatılıyor Controller - + Wallet Password - + Your wallet is encrypted. Please enter your wallet password - - + + Wallet Decryption Failed - + Please enter a valid password - + Failed to unlock wallet @@ -82,30 +137,178 @@ Please enter your wallet password CreateWalletForm - Form + Create New SDL Wallet - + + Confirm Passphrase: + + + + Restore wallet from seed - + Restore an existing wallet, using the 24-word seed. - - Create a new Wallet + + Create a new wallet - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new wallet with a randomly generated seed. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + İptal + + + + Add Contact and Send Request + + + MainWindow @@ -113,27 +316,27 @@ Please enter your wallet password silentdragon - + Balance Bakiye - + Summary Özet - + Shielded Korumalı - + Transparent Transparan - + Total Toplam @@ -142,13 +345,13 @@ Please enter your wallet password Bazı işlemler henüz onaylanmadı - + Address Balances Adres Bakiyeleri - - + + Send Gönder @@ -161,145 +364,185 @@ Please enter your wallet password Adres Bakiyesi - + Send To Alıcıya Gönder - + Recipient Alıcı - - - + + + Address Adres - + Address Book Adres Defteri - - + + Amount Miktar - + Max Available Maks. Kullanılabilir - - - + + + Memo Memo - + Add Recipient Alıcı Ekle - + Miner Fee Madenci Ücreti - + 0 0 - + Cancel İptal - + Receive Al - + Address Type Adres Tipi - + Next Address - + Information about Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving - + Difficulty - + Last Notarized Block - + Total Supply - + Longestchain - + + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &Hush Discord - + &Hush Website @@ -308,7 +551,7 @@ Please enter your wallet password z-Adres(Sapling) - + t-Addr t-Adres @@ -321,52 +564,54 @@ Please enter your wallet password silentdragon - + Your node is still syncing, balances may not be updated Düğümünüz hala senkronize oluyor, bakiyeler güncellenmeyebilir - Recurring payment - Düzenli ödeme + Düzenli ödeme - + SilentDragonLite - + Notarized - + Your node is still syncing, balances may not be updated. - + Some transactions are not yet confirmed. Balances may change. - + + Deposit Hush + + + + Total notarized funds available: - Every month, starting 12-May-2012, for 6 payments - Her ay, 12-May-2012'den itibaren, 6 ödeme için + Her ay, 12-May-2012'den itibaren, 6 ödeme için - Edit Schedule - Programı Düzenle + Programı Düzenle - + z-Addr z-Adres @@ -375,98 +620,98 @@ Please enter your wallet password Yeni Adres - + View All Addresses Tüm Adresleri Görüntüle - + Label Etiket - + Update Label Etiketi Güncelle - + Address balance Adres bakiyesi - + Optional İsteğe bağlı - - + + Export Private Key Özel Anahtarı Dışarı Aktar - + Transactions İşlemler - + Version hushlightd - + BlockHeight - + Supply zAddr - + Supply tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> - + Market Cap - + Volume on Exchanges - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> - + &Send DenioD Feedback - + Encrypt Wallet - + Remove Wallet Encryption - + Rescan Yeniden tara @@ -479,18 +724,18 @@ Please enter your wallet password Şu anda madencilik yapmıyorsunuz - - - - - - - - - - - - + + + + + + + + + + + + Loading... Yükleniyor... @@ -503,7 +748,7 @@ Please enter your wallet password Ağ çözüm oranı - + Vendor Bağlantılar @@ -512,42 +757,42 @@ Please enter your wallet password | - + &File Dosya - + &Help Yardım - + &Apps Uygulamalar - + &Edit Düzenle - + E&xit Çıkış - + &About Hakkında - + &Settings Ayarlar - + Ctrl+P Ctrl+P @@ -556,7 +801,7 @@ Please enter your wallet password Bağış Yap - + Check github.com for &updates Güncellemeler için github.com adresini kontrol edin @@ -573,48 +818,48 @@ Please enter your wallet password Özel anahtarı içeri aktar - + &Export all private keys Tüm özel anahtarları dışarı aktar - + &Export seed phrase - - + + Export transactions İşlemleri dışa aktar - + Pay hush &URI... hush URI öde... - + Connect mobile &app Mobil uygulamayı bağla - + Ctrl+M Ctrl+M - + &Recurring Payments Düzenli Ödemeler - + Request hush... hush iste... - + File a bug... Hata bildir... @@ -631,12 +876,12 @@ Please enter your wallet password Ctrl+A, Ctrl+Z - + Address &book Adres defteri - + Ctrl+B Ctrl+B @@ -686,12 +931,12 @@ Please enter your wallet password hushd henüz hazır değil. Lütfen arayüzün yüklenmesini bekleyin - + View tx on block explorer İşlemi blok gezgininde görüntüle - + Refresh Yenile @@ -756,7 +1001,7 @@ Please enter your wallet password hush URI ödeme hatası - + URI should be of the form 'hush:<addr>?amt=x&memo=y URI bu şekilde olmalıdır: 'hush:<addr>?amt=x&memo=y @@ -770,12 +1015,12 @@ Please enter your wallet password YOUR_TRANSLATION_HERE - + Error Hata - + Error exporting transactions, file was not saved İşlemler dışa aktarılırken hata oluştu, dosya kaydedilmedi @@ -812,154 +1057,91 @@ Please enter your wallet password Bu birkaç dakika sürebilir. Yükleniyor... - + These are all the private keys for all the addresses in your wallet Bunlar, cüzdanınızdaki tüm adreslerin özel anahtarlarıdır - + Private key for için özel anahtar - - + + Save File Dosyayı Kaydet - - Wallet is already encrypted - - - - - Your wallet is already encrypted with a password. -Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - - - - + Passwords don't match - - Error was: - - - - - - Wallet Encrypted - - - - - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - - - - - + + Wallet Encryption Failed - + Wallet is not encrypted - - Your wallet is not encrypted with a password. - - - - - Wallet Password - - - - - Please enter your wallet password - - - - - - - Wallet Decryption Failed - - - - - Please enter a password to decrypt your wallet! - - - - - Wallet Encryption Removed - - - - - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - - - - - + + Copy block explorer link - + Currency Change - + This is your wallet seed. Please back it up carefully and safely. - - + + Unable to open file Dosya açılamıyor - + Error getting private keys - + Error loading private keys: - - + + Copy address Adresi kopyala - - - + + + + Copied to clipboard Panoya kopyalandı - + Get private key Özel anahtarı al - - + + View on block explorer Blok gezgini üzerinde göster @@ -968,83 +1150,114 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Sapling'e geç - + Copy Address Adresi kopyala - + Address has been previously used Adres daha önce kullanılmış - + Address is unused Adres kullanılmamış - - + + Copy txid txid'i kopyala - - Restart + + + Wallet Encryption Success - - Please restart Silentdragonlite to have the theme apply - - - - - This change can take a few seconds. + + Your wallet is not encrypted with a passphrase. + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + + Restart + + + + + Please restart Silentdragonlite to have the theme apply + + + + + This change can take a few seconds. + + + + Some feedback about SilentDragonlite or Hush... - + or SilentDragonLite - + Send DenioD some private and shielded feedback about - + Paste HUSH URI - + Error paying HUSH URI - + View Payment Request Ödeme Talebini Görüntüle - + View Memo Memo'yu Görüntüle - + Reply to - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr Yeni t-Addr oluşturuldu @@ -1069,49 +1282,38 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet Sadece z-adres'leri memo'lara sahip olabilir - Memos can only be used with z-addresses - Memo'lar yalnızca z-adres'leriyle kullanılabilir + Memo'lar yalnızca z-adres'leriyle kullanılabilir - The memo field can only be used with a z-address. - Memo alanı yalnızca bir z-adres'i ile kullanılabilir. + Memo alanı yalnızca bir z-adres'i ile kullanılabilir. - doesn't look like a z-address - + z-adres'i gibi görünmüyor - + + Please wait... - + Computing your transaction - + + Done! - - - Not enough available funds to send this transaction - -Have: %1 -Need: %2 - -Note: Funds need 5 confirmations before they can be spent - - Change from Şuradan para üstü @@ -1134,20 +1336,100 @@ Note: Funds need 5 confirmations before they can be spent Gönderen Adresi Geçersiz - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address Alıcı Adresi - + + + is Invalid geçersizdir - + + + Amount for address '%1' is invalid! '% 1' adresinin tutarı geçersiz! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + MemoDialog @@ -1214,9 +1496,13 @@ Note: Funds need 5 confirmations before they can be spent MobileAppConnector - Connect Mobile App - Mobil Uygulamaya Bağlan + Mobil Uygulamaya Bağlan + + + + Mobile Connector App + @@ -1265,6 +1551,14 @@ Note: Funds need 5 confirmations before they can be spent Bağlantı tipi: + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1278,7 +1572,7 @@ Note: Funds need 5 confirmations before they can be spent - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it @@ -1286,17 +1580,17 @@ Note: Funds need 5 confirmations before they can be spent NewSeedPage - + Error creating a wallet - + Failed to save wallet - + Couldn't save the wallet @@ -1444,29 +1738,37 @@ daemon=1 hushd'nin eş bağlantısı yok - There was an error connecting to hushd. The error was - hushd ile bağlantı kurulurken bir hata oluştu. Hata + hushd ile bağlantı kurulurken bir hata oluştu. Hata - - + + + + The transaction with id id ile işlem - - + + + + failed. The error was başarısız oldu. Hata - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available Güncelleme Mevcut - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1475,17 +1777,18 @@ Would you like to visit the releases page? Yayınlanan sürümler sayfasını ziyaret etmek ister misiniz? - + No updates available Güncelleme yok - + You already have the latest release v%1 Zaten en son sürüme (v%1) sahipsiniz - + + Please wait for SilentDragonLite to exit @@ -1503,16 +1806,20 @@ Yayınlanan sürümler sayfasını ziyaret etmek ister misiniz? Düzenli İşlem Hesaplama: - + + + - + failed başarısız oldu - + + + - + Tx işlem @@ -1551,7 +1858,8 @@ Yayınlanan sürümler sayfasını ziyaret etmek ister misiniz? Lütfen çıkmak için silentdragon'i bekleyin - + + Waiting for hushd to exit Çıkmak için hushd bekleniyor @@ -1592,46 +1900,50 @@ Lütfen Düzenle->Ayarlar menüsünde sunucu/bağlantı noktası ve kullanıc Bu birkaç saat sürebilir - + Attempting to initialize library with - + Using existing wallet. - + Create/restore wallet. - - + + Connection Error Bağlantı Hatası - - - + + + + + Transaction Error İşlem Hatası - + There was an error sending the transaction. The error was: İşlem gönderilirken bir hata oluştu. Hata: - - + + No Connection Bağlantı Yok - + + + Address Format Error Adres Formatı Hatası @@ -1640,72 +1952,90 @@ Lütfen Düzenle->Ayarlar menüsünde sunucu/bağlantı noktası ve kullanıc geçerli bir hush adresi gibi görünmüyor. - + Pick Seç - + + + Address or Label Error Adres veya Etiket Hatası - + + + Address or Label cannot be empty Adres veya Etiket boş olamaz - + + + %1 doesn't seem to be a valid hush address. %1 geçerli bir hush adresi gibi gözükmüyor. - + Label Error Etiket Hatası - + The label '%1' already exists. Please remove the existing label. '%1' etiketi zaten var. Lütfen mevcut etiketi kaldırın. - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book Adres Defterini İçe Aktar - + Unable to open file Dosya açılamıyor - + Address Book Import Done Adres Defteri İçe Aktarma İşlemi Yapıldı - + Imported %1 new Address book entries %1 yeni Adres defteri girişi içeri aktarıldı - + Copy address Adresi kopyala - + Copied to clipboard Panoya kopyalandı - + Delete label Etiketi sil - + Tx submitted (right click to copy) txid: İşlem gönderildi (kopyalamak için sağ tıklayın) id: @@ -1774,9 +2104,13 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük. RecurringDialog - Dialog - Diyalog + Diyalog + + + + Reccuring Dialog + @@ -1830,9 +2164,13 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük. RecurringPayments - Payments - Ödemeler + Ödemeler + + + + Reocurring Payments + @@ -1887,9 +2225,13 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük. RecurringPending - Dialog - Diyalog + Diyalog + + + + Recurring Multiple Payments + @@ -1955,57 +2297,57 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.Ödeme Talebi - + AddressBook Adres Defteri - + Request From İstek Adresi - + My Address Benim Adresim - + Amount in Miktar: - + z address z adres - + Amount Miktar - + The recipient will see this address in the "to" field when they pay your request. Alıcı, isteğinizi ödediğinde bu adresi "alıcı" alanında görecektir. - + Amount USD USD Miktarı - + Memo Memo - + TextLabel Metin Etiketi - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. Bir Sapling adresinden ödeme talep edin. Bir hush ödeme URI'si olan bir adrese hush 0.0001 işlemi gönderirsiniz. Adres size ödeme yaptığında Memo işleme dahil edilecektir. @@ -2044,7 +2386,7 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.RestoreSeedForm - Form + Restore Wallet Seed @@ -2076,38 +2418,38 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük. RestoreSeedPage - - + + Failed to restore wallet - + SilentDragonLite needs 24 words to restore wallet - + Failed to parse wallet birthday - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. - + Couldn't restore the wallet - + Failed to save wallet - + Couldn't save the wallet @@ -2115,7 +2457,7 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük. Settings - + Settings Ayarlar @@ -2140,7 +2482,7 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.RPC Şifresi - + Options Seçenekler @@ -2149,7 +2491,7 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.Tor ile bağlan - + Check github for updates at startup Başlangıçta güncellemeler için github'u kontrol et @@ -2162,12 +2504,12 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.Tor ağına 127.0.0.1:9050'de çalışan SOCKS proxy üzerinden bağlanın. Lütfen Tor servisini harici olarak kurmanız ve çalıştırmanız gerektiğini lütfen unutmayın. - + Connect to github on startup to check for updates Güncellemeleri denetlemek için başlangıçta github'a bağlanır - + Connect to the internet to fetch hush prices hush fiyatlarını çekmek için internete bağlanır @@ -2176,97 +2518,102 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.hush / USD fiyatlarını çek - + Theme - - default - - - - + Connection - + Lightwallet Server - - blue + + Dark - - light + + Midnight - - dark + + Light - + + Blue + + + + + Default + + + + Fetch hush prices - + Currency - + AUD - + BTC - + CAD - + CHF - + CNY - + EUR - + GBP - + INR - + RUB - + USD @@ -2441,27 +2788,116 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.Adres Defteri - + Add New Address Yeni Adres Ekle - + Address (z-Addr or t-Addr) Adres (z-Adres veya t-Adres) - - Label - Etiket + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + Etiket + + + Add to Address Book Adres Defterine Ekle - + Import Address Book Adres Defterini İçe Aktar @@ -2571,33 +3007,133 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.<html><head/><body><p>Blok indirme işlemi sırasında en uzun süren kontrolleri atlar. <a href="https://docs.silentdragon.co/using-silentdragon/#fastsync"><span style=" text-decoration: underline; color:#0000ff;">Daha fazla bilgi edin</span></a></p></body></html> + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + Adresi kopyala + + encryptionDialog - + Encrypt Your Wallet - - Encryption Password: + + Encryption Passphrase: - - Confirm Password: + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> - - Passwords don't match + + Confirm Passphrase: - - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + hushrequest + + + Request Payment + + + + + TextLabel + Metin Etiketi + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + Bir Sapling adresinden ödeme talep edin. Bir hush ödeme URI'si olan bir adrese hush 0.0001 işlemi gönderirsiniz. Adres size ödeme yaptığında Memo işleme dahil edilecektir. + + + + Request From + İstek Adresi + + + + zaddr + + + + + Amount in + Miktar: + + + + Amount + Miktar + + + + Amount USD + USD Miktarı + + + + Memo + Memo + + + + My Address + Benim Adresim + + + + The recipient will see this address in the "to" field when they pay your request. + Alıcı, isteğinizi ödediğinde bu adresi "alıcı" alanında görecektir. + newRecurringDialog @@ -2647,6 +3183,180 @@ Onaylanmamış fonunuz var veya otomatik geçiş için bakiye çok düşük.Ödeme sayısı + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + İptal + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + zboard diff --git a/res/silentdragonlite_zh.ts b/res/silentdragonlite_zh.ts index 3eaf441..a22ee06 100644 --- a/res/silentdragonlite_zh.ts +++ b/res/silentdragonlite_zh.ts @@ -4,29 +4,80 @@ AddressBookModel - + Label 标签 - + Address 地址 + + + Avatar + + + + + HushChatAddress + + + + + CID + + BalancesTableModel - + Address 地址 - + Amount 金额 + + ChatBubbleMe + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + + + ChatBubblePartner + + + Form + + + + + Lorem ipsum dolor sit amet + + + + + 12/03/2020 12:34 + 12/03/2020 12:34 + + ConnectionDialog @@ -34,42 +85,46 @@ hush钱包 - + SilentDragonLite - + + The Dragon Awakens... + + + Starting Up - 启动中 + 启动中 Controller - + Wallet Password - + Your wallet is encrypted. Please enter your wallet password - - + + Wallet Decryption Failed - + Please enter a valid password - + Failed to unlock wallet @@ -78,30 +133,178 @@ Please enter your wallet password CreateWalletForm - Form + Create New SDL Wallet - + + Confirm Passphrase: + + + + Restore wallet from seed - + Restore an existing wallet, using the 24-word seed. - - Create a new Wallet + + Create a new wallet - + + Encryption Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + Create a new wallet with a randomly generated seed. + + Dialog + + + Send Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a nickname for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Choose an avatar for your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert a memo for your request:</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Your HushChat Address:</span></p></body></html> + + + + + Create New Address + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Insert the address of your contact:</span></p></body></html> + + + + + <html><head/><body><p><span style=" color:#d3d7cf;">Generate your HushChat Address - please wait a second - </span></p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Stag + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + 0/512 + 0/512 + + + + Add a memo to your request + + + + + Cancel + 取消 + + + + Add Contact and Send Request + + + MainWindow @@ -109,57 +312,62 @@ Please enter your wallet password hush钱包 - + Balance 余额 - + Summary 概要 - + Shielded 隐蔽余额 - + Notarized - + Transparent 非隐蔽余额 - + Total 所有余额 - + Your node is still syncing, balances may not be updated. - + Some transactions are not yet confirmed. Balances may change. - + + Deposit Hush + + + + Total notarized funds available: - + Next Address - + Your node is still syncing, balances may not be updated 您的节点仍在同步,余额可能没有更新 @@ -168,13 +376,13 @@ Please enter your wallet password 部分交易尚未得到确认 - + Address Balances 地址余额 - - + + Send 发送 @@ -187,160 +395,157 @@ Please enter your wallet password 地址余额 - + SilentDragonLite - + Send To 发送给 - + Recipient 接收者 - - - + + + Address 地址 - + Address Book 地址薄 - - + + Amount 金额 - + Max Available 最大可发送金额 - - - + + + Memo 备注 - + Add Recipient 添加接收者 - Recurring payment - 循环支付 + 循环支付 - Every month, starting 12-May-2012, for 6 payments - 从2012年5月12日开始,每月支付6次 + 从2012年5月12日开始,每月支付6次 - Edit Schedule - 编辑计划 + 编辑计划 - + Miner Fee 矿工费用 - + 0 0 - + Cancel 取消 - + Receive 接收 - + Address Type 地址类型 - + z-Addr 隐蔽地址(z-Addr) - + t-Addr 非隐蔽地址(t-Addr) - + Information about Hush - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Blockchain Information</span></p></body></html> - - - - - - - - - - - - + + + + + + + + + + + + <html><head/><body><p align="center">|</p></body></html> - + Next Halving - + Difficulty - + Last Notarized Block - + Total Supply - + Longestchain @@ -349,103 +554,143 @@ Please enter your wallet password 创建新地址 - + View All Addresses - + Label 标签 - + Update Label 更新标签 - + Address balance 地址余额 - + Optional 可选 - - + + Export Private Key 导出私钥 - + Transactions 交易 - + Version hushlightd - + BlockHeight - + Supply zAddr - + Supply tAddr - + <html><head/><body><p align="center"><span style=" font-weight:600;">Hush Market Information</span></p></body></html> - + Market Cap - + Volume on Exchanges - + <html><head/><body><p align="center">This is a Lightwallet, you cant mine with it!</p></body></html> - + + HushChat + + + + + Incoming contact request + + + + + Add a new contact + + + + + Get a new Address + + + + + <html><head/><body><p align="center"><span style=" font-weight:600; text-decoration: underline;">Contactlist</span></p></body></html> + + + + + <html><head/><body><p align="center"><span style=" font-weight:600;">Contact Name :</span></p></body></html> + + + + + <html><head/><body><p align="center"><br/></p></body></html> + + + + + The locks shows you the status of the message. Red lock = unconfirmed, green lock = min. 1 confirmations, orange lock = message is notarized + + + + &Send DenioD Feedback - + &Export seed phrase - + Encrypt Wallet - + Remove Wallet Encryption - + Rescan 重新扫描 @@ -454,12 +699,12 @@ Please enter your wallet password 节点 - + &Hush Discord - + &Hush Website @@ -468,18 +713,18 @@ Please enter your wallet password 您目前没有在挖矿 - - - - - - - - - - - - + + + + + + + + + + + + Loading... 加载中... @@ -492,7 +737,7 @@ Please enter your wallet password 全网算力 - + Vendor 连接数 @@ -501,42 +746,42 @@ Please enter your wallet password | - + &File &文件 - + &Help &帮助 - + &Apps &应用 - + &Edit &编辑 - + E&xit &退出 - + &About &关于 - + &Settings &设置 - + Ctrl+P Ctrl+P @@ -545,7 +790,7 @@ Please enter your wallet password &捐赠 - + Check github.com for &updates 检查github.com获取和&更新 @@ -562,7 +807,7 @@ Please enter your wallet password &导入私钥 - + &Export all private keys &导出所有私钥 @@ -575,12 +820,12 @@ Please enter your wallet password Ctrl+A, Ctrl+Z - + Address &book &地址簿 - + Ctrl+B Ctrl+B @@ -589,38 +834,38 @@ Please enter your wallet password &备份 wallet.dat - - + + Export transactions 导出交易 - + Pay hush &URI... 支付hush &URI ... - + Connect mobile &app 连接移动&App - + Ctrl+M Ctrl+M - + &Recurring Payments &定期付款 - + Request hush... 请求 hush... - + File a bug... 提交错误... @@ -633,12 +878,12 @@ Please enter your wallet password hushd尚未准备好。 请等待UI加载 - + View tx on block explorer - + Refresh @@ -715,7 +960,7 @@ Please enter your wallet password 支付hush URI时出错 - + URI should be of the form 'hush:<addr>?amt=x&memo=y URI的格式应为 'hush:<addr>?amt=x&memo=y' @@ -732,12 +977,12 @@ Please enter your wallet password 钥匙是导入的。 重新扫描区块链可能需要几分钟时间。 在此之前,功能可能会受到限制 - + Error 错误 - + Error exporting transactions, file was not saved 导出交易时出错,文件未保存 @@ -770,148 +1015,106 @@ Please enter your wallet password 您需要手动备份它。 - + These are all the private keys for all the addresses in your wallet 这些都是钱包中所有地址的私钥 - + Private key for 私钥 - - + + Save File 保存文件 - - Wallet is already encrypted - - - - - Your wallet is already encrypted with a password. -Please use 'Remove Wallet Encryption' if you want to remove the wallet encryption. - - - - + Passwords don't match - - Error was: - - - - - - Wallet Encrypted - - - - - Your wallet was successfully encrypted! The password will be needed to send funds or export private keys. - - - - - + + Wallet Encryption Failed - + Wallet is not encrypted - - Your wallet is not encrypted with a password. - - - - - Wallet Password - - - - - Please enter your wallet password - - - - - - - Wallet Decryption Failed - - - - - Please enter a password to decrypt your wallet! - - - - - Wallet Encryption Removed - - - - - Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys. - - - - - + + Copy block explorer link - + Currency Change - + This is your wallet seed. Please back it up carefully and safely. - - + + Unable to open file 无法打开文件 - + Error getting private keys - + Error loading private keys: - - + + Copy address 复制成功 - - - + + + + Copied to clipboard 复制到剪贴板 - + + + Wallet Encryption Success + + + + + Your wallet is not encrypted with a passphrase. + + + + + Wallet decryption Success + + + + + You still have plaintext data on your disk! + + + + Get private key 获取私钥 @@ -920,8 +1123,8 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet 屏蔽余额到Sapling地址 - - + + View on block explorer 从区块浏览器中查看 @@ -930,83 +1133,93 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet 迁移到Sapling地址 - - + + Copy txid 复制交易ID - + Restart - + Please restart Silentdragonlite to have the theme apply - + This change can take a few seconds. - + Some feedback about SilentDragonlite or Hush... - + or SilentDragonLite - + Send DenioD some private and shielded feedback about - + Paste HUSH URI - + Error paying HUSH URI - + View Payment Request 查看付款申请 - + View Memo 查看备注 - + Reply to 回复给 - + + Copied message to clipboard + + + + + Copied Txid to clipboard + + + + Created new t-Addr 创建了新的t-Addr - + Copy Address - + Address has been previously used 该地址以前使用过 - + Address is unused 地址未使用 @@ -1031,49 +1244,38 @@ Please use 'Remove Wallet Encryption' if you want to remove the wallet 只有 z-addresses 才能有备注 - Memos can only be used with z-addresses - 备注只能与z-addresses一起使用 + 备注只能与z-addresses一起使用 - The memo field can only be used with a z-address. - 备注字段只能与z-address一起使用。 + 备注字段只能与z-address一起使用。 - doesn't look like a z-address - + 看起来不像是z-address - + + Please wait... - + Computing your transaction - + + Done! - - - Not enough available funds to send this transaction - -Have: %1 -Need: %2 - -Note: Funds need 5 confirmations before they can be spent - - Change from 更改发送地址 @@ -1096,20 +1298,100 @@ Note: Funds need 5 confirmations before they can be spent 发送地址无效 - + + + You have to select a contact and insert a Memo + + + + + + You have selected no Contact from Contactlist, + + + + + + + +or your Memo is empty + + + + + + Your Message is too long + + + + + + You can only write messages with 235 character maximum + + + + + + + + Please reduce your message to 235 character. + + + + + + Message Error + + + + + + Recipient Address 接收地址 - + + + is Invalid 无效 - + + + Amount for address '%1' is invalid! + + + + + Not enough available funds to send this transaction + +Have: %1 +Need: %2 + +Note: Funds need 1 confirmations before they can be spent + + + + + Missing HushChat Address + + + + + You have to create your HushChat address to send a contact request, + + + + + + Your contact request will be sent + + Amount '%1' is invalid! 转账金额 '%1' 无效! @@ -1180,9 +1462,13 @@ Note: Funds need 5 confirmations before they can be spent MobileAppConnector - Connect Mobile App - 连接手机App + 连接手机App + + + + Mobile Connector App + @@ -1231,6 +1517,14 @@ Note: Funds need 5 confirmations before they can be spent 连接类型: + + NewOrRestorePage + + + Passphrase don't match or You have entered too few letters (16 minimum) + + + NewSeedForm @@ -1244,7 +1538,7 @@ Note: Funds need 5 confirmations before they can be spent - + The seed phrase is the only way to restore the wallet. If you forget the seed phrase, THERE IS NO WAY TO RESTORE YOUR WALLET AND THE FUNDS in it @@ -1252,17 +1546,17 @@ Note: Funds need 5 confirmations before they can be spent NewSeedPage - + Error creating a wallet - + Failed to save wallet - + Couldn't save the wallet @@ -1282,72 +1576,92 @@ Note: Funds need 5 confirmations before they can be spent QObject - + Pick 选择 - + + + Address or Label Error 地址或标签错误 - + + + Address or Label cannot be empty 地址或标签不能为空 - + + + Address Format Error 地址格式错误 - + + + %1 doesn't seem to be a valid hush address. %1 似乎不是有效的hush地址。 - + Label Error 标签错误 - + The label '%1' already exists. Please remove the existing label. 标签 '%1' 已存在。 请删除现有标签。 - + + + Added Contact + + + + + + successfully added your new contact + + + + Import Address Book 导入地址簿 - + Unable to open file 无法打开文件 - + Address Book Import Done 地址簿导入完成 - + Imported %1 new Address book entries 已导入 %1 个新地址簿条目 - + Copy address 复制地址 - + Copied to clipboard 复制到剪贴板 - + Delete label 删除标签 @@ -1478,66 +1792,77 @@ Please set the host/port and user/password in the Edit->Settings menu.这可能需要几个小时 - + Attempting to initialize library with - + Using existing wallet. - + Create/restore wallet. - - + + Connection Error 连接错误 - - - + + + + + Transaction Error 交易错误 - + There was an error sending the transaction. The error was: 发送交易时出错。 错误是: - + + + - + Tx 交易 - + + + - + failed 失败 - - + + + + The transaction with id 交易 - - + + + + failed. The error was 失败。 错误是 - + + Please wait for SilentDragonLite to exit @@ -1577,8 +1902,8 @@ Please set the host/port and user/password in the Edit->Settings menu.所有未来的付款都将被取消。 - - + + No Connection 没有连接 @@ -1611,21 +1936,25 @@ Please set the host/port and user/password in the Edit->Settings menu.hushd没有节点可连接 - There was an error connecting to hushd. The error was - 连接到hushd时出错。 错误是 + 连接到hushd时出错。 错误是 tx computing. This can take several minutes. 交易计算中。 这可能需要几分钟。 - + + There was an error connecting to the server. Please check your internet connection. The error was + + + + Update Available 可用更新 - + A new release v%1 is available! You have v%2. Would you like to visit the releases page? @@ -1634,12 +1963,12 @@ Would you like to visit the releases page? 您想访问发布页面吗? - + No updates available 没有可用的更新 - + You already have the latest release v%1 您已拥有最新版本 v%1 @@ -1648,12 +1977,13 @@ Would you like to visit the releases page? 请等待silentdragon退出 - + + Waiting for hushd to exit 等待hushd退出 - + Tx submitted (right click to copy) txid: 交易提交(右键单击复制)交易ID: @@ -1722,9 +2052,13 @@ You either have unconfirmed funds or the balance is too low for an automatic mig RecurringDialog - Dialog - 对话框 + 对话框 + + + + Reccuring Dialog + @@ -1778,9 +2112,13 @@ You either have unconfirmed funds or the balance is too low for an automatic mig RecurringPayments - Payments - 支付 + 支付 + + + + Reocurring Payments + @@ -1835,9 +2173,13 @@ You either have unconfirmed funds or the balance is too low for an automatic mig RecurringPending - Dialog - 对话框 + 对话框 + + + + Recurring Multiple Payments + @@ -1903,57 +2245,57 @@ You either have unconfirmed funds or the balance is too low for an automatic mig 付款请求 - + AddressBook 地址簿 - + Request From 请求来自 - + My Address 我的地址 - + Amount in 金额 - + z address z address - + Amount 金额 - + The recipient will see this address in the "to" field when they pay your request. 支付者在付款时会在“接收者”字段中看到此地址。 - + Amount USD 金额 美元 - + Memo 备注 - + TextLabel TextLabel - + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. 要求从树苗地址付款。 您将使用hush支付URI将hush 0.0001交易发送到该地址。 当地址付款时,备注将包含在交易中。 @@ -1992,7 +2334,7 @@ You either have unconfirmed funds or the balance is too low for an automatic mig RestoreSeedForm - Form + Restore Wallet Seed @@ -2024,38 +2366,38 @@ You either have unconfirmed funds or the balance is too low for an automatic mig RestoreSeedPage - - + + Failed to restore wallet - + SilentDragonLite needs 24 words to restore wallet - + Failed to parse wallet birthday - + Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be. - + Couldn't restore the wallet - + Failed to save wallet - + Couldn't save the wallet @@ -2063,7 +2405,7 @@ You either have unconfirmed funds or the balance is too low for an automatic mig Settings - + Settings 设置 @@ -2088,7 +2430,7 @@ You either have unconfirmed funds or the balance is too low for an automatic mig RPC密码 - + Options 选项 @@ -2097,7 +2439,7 @@ You either have unconfirmed funds or the balance is too low for an automatic mig 通过Tor连接 - + Check github for updates at startup 启动时检查github更新 @@ -2134,12 +2476,12 @@ You either have unconfirmed funds or the balance is too low for an automatic mig 通过运行在127.0.0.1:9050上的SOCKS代理连接到Tor网络。 请注意,您必须在外部安装和运行Tor服务。 - + Connect to github on startup to check for updates 在启动时连接到github以检查更新 - + Connect to the internet to fetch hush prices 连接到互联网以获取hush价格 @@ -2148,97 +2490,102 @@ You either have unconfirmed funds or the balance is too low for an automatic mig 获取 hush/USD 价格 - + Theme - - default - - - - + Connection - + Lightwallet Server - - blue + + Dark - - light + + Midnight - - dark + + Light - + + Blue + + + + + Default + + + + Fetch hush prices - + Currency - + AUD - + BTC - + CAD - + CHF - + CNY - + EUR - + GBP - + INR - + RUB - + USD @@ -2374,27 +2721,116 @@ You either have unconfirmed funds or the balance is too low for an automatic mig 地址簿 - + Add New Address 添加新地址 - + Address (z-Addr or t-Addr) 地址 (z-Addr or t-Addr) - - Label - 标签 + + <html><head/><body><p>Nickname :</p></body></html> + - + + HushChat Address - give this Address only to your contact + + + + + <html><head/><body><p>Conversation ID:</p></body></html> + + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garflied + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p>Avatar :</p></body></html> + + + + + Create a new HushChat zaddr + + + + Label + 标签 + + + Add to Address Book 添加到地址薄 - + Import Address Book 导入地址簿 @@ -2504,33 +2940,133 @@ You either have unconfirmed funds or the balance is too low for an automatic mig <html><head/><body><p>在初始块下载期间跳过了最费时的检查。 <a href="https://docs.silentdragon.co/using-silentdragon/#fastsync"><span style=" text-decoration: underline; color:#0000ff;">了解更多</span></a></p></body></html> + + deposithush + + + Deposit Hush + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:16pt;">Please use the following hush address to transfer funds to SilentDragonLite. You can either copy the address or use the QR Code. </span></p></body></html> + + + + + <html><head/><body><p align="center">QR Code of your Hush Address</p></body></html> + + + + + <html><head/><body><p align="center"><span style=" text-decoration: underline;">Your Hush Address </span></p></body></html> + + + + + Hush zaddr + + + + + Copy Address + + + encryptionDialog - + Encrypt Your Wallet - - Encryption Password: + + Encryption Passphrase: - - Confirm Password: + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you forget your passphrase, the only way to recover the wallet is from the seed phrase. If you don't have a backup of your seed phrase, please do it now!</p></body></html> - - Passwords don't match + + Confirm Passphrase: - - WARNING: If you forget your password, the only way to recover the wallet is from the seed phrase. + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + hushrequest + + + Request Payment + + + + + TextLabel + TextLabel + + + + Request payment from a Sapling address. You'll send a hush 0.0001 transaction to the address with a hush payment URI. The memo will be included in the transaction when the address pays you. + 要求从树苗地址付款。 您将使用hush支付URI将hush 0.0001交易发送到该地址。 当地址付款时,备注将包含在交易中。 + + + + Request From + 请求来自 + + + + zaddr + + + + + Amount in + 金额 + + + + Amount + 金额 + + + + Amount USD + 金额 美元 + + + + Memo + 备注 + + + + My Address + 我的地址 + + + + The recipient will see this address in the "to" field when they pay your request. + 支付者在付款时会在“接收者”字段中看到此地址。 + newRecurringDialog @@ -2580,6 +3116,180 @@ You either have unconfirmed funds or the balance is too low for an automatic mig 支付次数 + + removeencryption + + + Decrypt Your Wallet + + + + + <html><head/><body><p><span style=" font-size:14pt; color:#ef2929;">WARNING:</span> If you remove your wallet.dat encryption, all your transactions and contacts are plaintext on disk!<br/><br/>Messages sent and received are always encrypted.</p></body></html> + + + + + <html><head/><body><p><span style=" font-style:italic;">16 letters minimum</span></p></body></html> + + + + + Encryption Passphrase: + + + + + Confirm Passphrase: + + + + + <html><head/><body><p><span style=" font-style:italic;">Passphrase don't match</span></p></body></html> + + + + + requestDialog + + + Incoming Contact Request + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Memo of the request</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Open requests</span></p></body></html> + + + + + Request from: + + + + + Add New Contact + + + + + <html><head/><body><p>Choose an avatar for your contact:</p></body></html> + + + + + My Zaddr: + + + + + Cancel + 取消 + + + + SDLogo + + + + + Duke + + + + + Denio + + + + + Berg + + + + + Sharpee + + + + + Elsa + + + + + Yoda + + + + + Garfield + + + + + Snoopy + + + + + Popey + + + + + Pinguin + + + + + Mickey + + + + + Stag + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Recently closed requests</span></p></body></html> + + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Details of the request</span></p></body></html> + + + + + Give a Nickname: + + + + + startup + + + SDL Startup Decryption + + + + + <html><head/><body><p>If you have forgotten your passphrase, restore your wallet with your seed!</p></body></html> + + + + + Encryption Passphrase: + + + zboard From 7f851663ab8420503cb45d74590e3f6e970369dd Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 11 Jun 2020 17:32:22 +0200 Subject: [PATCH 253/253] add arabic --- res/silentdragonlite_ar.qm | Bin 23614 -> 20930 bytes silentdragon-lite.pro | 1 + 2 files changed, 1 insertion(+) diff --git a/res/silentdragonlite_ar.qm b/res/silentdragonlite_ar.qm index cc809ec63da02bc769858fca540d2bd75169c42b..cdef56cc1c07491832658e24fbdbcbfea200c1e5 100644 GIT binary patch delta 2786 zcmXYzdt6QV8phvs+iUH$*Iqlis3s{Dx+qB$Dwi(Er4mw@jL?`vlEE14CZRc+oMUHb z$WWP!OwyKnX%dsmxSeJW=EyaC+$C}wGY{+hu|MCn*X8%V@AE$IZ>`#WOnoV19=I>f z@x-G|>wa~2Ih?w+=JF6Cxfc=PC(O_ovJA&NiTtN)3@Xz&__@ZIF+|aYL<1)i#Uz5o z;Bs&&cnqu|8Wsv(CK^#f6z)b8I~SZoWFFlc2L(jqza$DCK{R14Q3OMjJReLaHf0M@ z*B0V`*oFkw694;GL~b{Tzc?8|JxLfCL1Z&Vqst+UeO_pc#`*D4L_JTEFtd#)AcBO9 zjYQtdNZ1rfWOtOzLM<-z@*trO)%i{%;mj|1K&B4QP7_7el4IowBFA3jeEuRRkZW@V z(FeE5XH^yvw~BlY@?bgnob@8&L&)bol;bB+=&d-Sj{l;VuN#O4rBKWj+^0OD*tAUW zR~lLL5s`6-Sv&AQPVu8&5=8}4!lFZv-A|)w3?-M_5xKfk^8H{a5=|+ymJoHiMzcoO z5!o6kV}m~mD5TFf4zZ-|% ztl>M}#s%-qeEjehqHf82!i)+cF9VHaxHrFHxEW^C-{8v&TH#6&{1f!!%hzCCC7$2m zw+%hJ%Gb&&By8dv9N#T4k3Xh-L)0adKXtqkN=)M~+;)R^9`dc0c}UzU5Qi4@StPhE zD@35zLTKw~qJAXAj!J^pvW0Pjo)Wp_3905LJ$iXYnD%fN0u>AC)!1l)Glcvin9nXj zCyTZ;nP{Lgls*XQFLGeO;+Ge7m zEyAf-jG0rZ&emZ+O!_}vQ)4uC1NvlE7#>>!^zV) z;Eb*!8J?h9y2^5#H_p&CRCYqZ1-fHXph%|(-LaKeh&!WeWKpSypu4%$9xc7Adm4vC zJ(5N5B~9>#rx=hAGD%`kK9uwAA`b9CJli*BG0OQjjL{Bpu#+Qjn5P$p!oSn&()4|WwRr^1vS z#*2H~5XVprD6Vq*Gugq=EMCpQhODow!5S6yT=YKh}RF;zZ*SH&<{^4fj4aQ zqh`K^nOOZ4^Ja{xpr5@9W^>HY=+mm7AF&+@ZPMpWIEh~WsNd5z3>7ccH%y1y?FZ;j zINRc#@ss{^23k45qQ9K-7V{r{OMkBh3;HPfdxxv>lIg86$X;WNoBm&kAT zvKCoagZn%~Ww!?gNj_m2+?5 zx$f!mm(!atMUUl@fO(jI=L7OiD>Ad4Deo(6zz&!$H-sEVg;V7ds}o_$M!D4`hA3!= zf!VVR(tT%8-rd(Z#}NMZd-S-}Fs8qV1&i7bUAI0H(d7%wLav!>(9amwpBX`Y0Q! zvoXFuD;w%C?qRQ$pGHDad6=@(9A1mL-K*@I8;&h_rE=g=78tG^WWWe_rLHmvH%iL! zcOMu%<|~)lenbV{%GHQJpvXz3~_U?v{MsyxL3x@ z2O;6mHOAJAj#!|=_$nI#2YIQk*Ulp`Pt`m1C0;g9RsYfWz>q>U4t7uj9FdTerp5-K zMO_$md=M0KD^aKa5r;T6X7%Igl|@c4o1ePoya&$TRL`D*7u5Uec_YTj zp-OFf&sFMG+p(y?QGFBO33pF5sU09`*BaA==x#`~n(E`&M)0VO_Y%lqylEyU5`F>OV+ue9yuQr{_u0Y1Q zri+}4DVS!u7L$vBP8$2ineHSOW20#_J#L1yY^RU$@wdoQXK=RU8ZKE2lt9MPZcMT) zQopvwnrvk2DyLzLb@&JNtfj2;GHbnSXU00)Et#>lyD#9ZwO(U*OO{W7Wr*($tFQkN z*3xStZ}kmaZ?M{iJ?E_b25(`lY-FZr-5A@Vvr1zhFjnVr4!mW?#1P9HgJLaB-pKq7 DHb3^b delta 4353 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 hBOSi?QUiO

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 tXMM!gv06mY2L)QqZt$# literal 0 HcmV?d00001 diff --git a/res/sdlogo.png b/res/sdlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5dde4f0dda19c805f99e3556707277d558cc72e8 GIT binary patch literal 43333 zcmZ_0bzE25^F4g%?vj#FQc6lnx};jQ931l zbMEK){`vU2_o`gpC-$B_vu3R|ywKB8BOzoUL=c2TLtR-PK``NumD{I=^kbc`Sv z!FEbYdKyYftWGYD5AEz9AP9GyPuz9&WmkJ%vR$X2ndmCQNf%CL<*z*mn zV8f`whvt}iVqG1VsVwVCcth_~$dk)s-+Yn!jQ49w(DLz@u$W8_=Zs&ce|yEUsBhpN zD$h&4Wu)E0-Rgdu?>fDFyX0jac_vj1qXFyIrO^k;GZM+nw4M)JIvy;&xYS}<6ZY%k zLmDNH49;kt_o_#V(+@&+Xl*J-%+sa3!sc?SUj35#Lvgt@n0kPmEjNJoQ3?6GTbEju zL;q4;JS$kxjo0G5LlenFRG<{Hc-VM8dtm=#U?}emwGPrqH+gmeNAautSG&oX_Nt$< z7$?0Ai6eWXCJpOct3N){N@L=F4v6^uk#hqhS-N2}UV#49r6W6{e9BE<)fodM^hv;( zn8%a!=V`KtlQ!h}^%J3EP5esime2zr(L1 zrLTVQ8-bI$u`7ZITtffF@XVKUhcDu}Y1~l3Tg1jeF7p-=M^(X>=-pI|+>{(093DJz zLzG+|Shzi~X7#Xhvt?D&xS@9^fRqkFSP>0n1q08C^>hy-gZ9z(-YI@jEoG}HOXa9< zZL~O;yyjR$ye+THV@PPEE!W5T3NSv5g%q$7(yr6sh>1rsh&>{%z523Eb@He5221DE z49-o9aTkvR?~HaXRp*0go@MXl?o<&3KalnR=bseObg8GW!;1Y`lL*3Yz<(nW6BDVb zFaxs?dGeN~lBz2AHbZ%GYPf{a1rDvG7FF~wZ=>SlZ#`Jo!RBFbsbONoP1dvc_tap*bHe8(mUe#+Z62V>`oc19cqSW*Pcve zQE_TF)L0T$S67Qxdmjm3_c<1I82y-jy$U~&T3cJ2m_ZENi!7e=M$YIbvv&jp1QNR1 zFO16{_WvIJbgP>{KK6i$g(YSOOF_0|yWVSu^Xb#4t%1gGRV^*qzdhUIMK8x7iOu7` zxM-cmi2o|)1r^r-TE*q>W8hbkBv(jtiU!-q`?Jh!^fy6aW&{jWdYuh7=ez{pruC^p1m!|utH zi-C{YeowrDCn+g8Mjoz0b>V_K9w`&POfOM>sgjb?E&jQm{7X`^a7BvByCezv@K)wl zR#=^#okKr<{9t~ESiVRQFlE3&EVr)s!7sf+0|bHBOp|&_XlZ4|n1cw37=AFqU~0$6 zrzKl4|EG4tSb{+Y{j`!oDY-6ZL+6eYT=mdfdS)n<-bV z_})%^QX%knn5>E$8ZyY*omr8~r=}*v2@Vc!$;OxGBY~xx^}0w+sDfor(((!)A3rMy zmjqK0Ur$pZx8GmCF!(`NlCgobQ_{%R>G9qrLqkJ(d{_Ytq~ZH_LRvl}e^>$T_4Rds zeL`_@af!ba5fKUy9H zLPF{9&#zn(e$fm5%U-aa0TA77G}w~dUz-t!uM z2!~62+u0Z{qC@;k=9j%LS_{)peR)dM)ZF}nqbj16(BE~r=YhjS1%b7&@igw7L~N&Z ziQDQx$w$+#s`En%-89nD(y$wPh58)!#4Ywmb73sDpYDHy=brVtAATszR^ol+Vxr~1 z*z*ccRb3rlLsz$V$HrdIi3x9K>Bo*5g@4Kw!Vpa4j2}Okb!qM7`TjaV!hlSD3NlvZ zz?dfOAwY!VAF@5DE2jd1L4+05m@prRLv-@hZIv?g7QxkPV;5``5rys-tr2vCvOdSK zlvtXDB^$k-hnsACMkW46E{w*tNO(-lK}19ZmSVUQuYY#GtvqMEg1UN#x}e}Ei8TH2 zn%VjJ0e|M82fuVFS|VxPD{j5h$ucYoS(qkH`d#_($7@?HM=sJZ!iL4p_)ggC=_6Oz zIyhnovec9Q`}C*B%-ktPxUsp7&2n#3)&>?iYQ1dTaCZ`m^sd$M>w-qZPcpYgq^p zYy{okogR6Lb2&Ebwip&NEId+WSOuA?s;WAKH9$qc*WmkS&u*m>MH;tqezj-sh(W=tIyVd`B_lm~g71nhX`RM(`cL$MH`N z7h)D6@;8)`Z8d;Un3$O6yDR|lXIJXsgSNBv5$ig@>D4W5H=?mxR|}YYf8M34XPmiBBF8JD7)dXp2g?z3Pk`=~ zsbqAJuIv#uBhFQN_dgRVP)0JjY6Ru@Smd+y8fv|E7%Ypj5pGeac9$UVDFq0=`?32I zVD3L>VPQ#;bme@Bw1{%nacjI>_9`$eW)LT|q+Fk=&y z-jp4iYq_^S-DhURjT3#Rlb%DvYe2rvU$oWRVRqCDS?{fOsxXTQDUSb06EhGqLvBds>SM~WBWZz0FV?kH(v&Y$bj90&yV{<5dP<115+XmhAe$s6cKu@E7suGF z*Gqux`)qHmap}jK{x9sWvhUTn1TNqq77u3<6qefB*dJftvSDeozpWIH{$9w~x-}<(v=wE5 zL;_bLv*}4wpzyzt1}AHLSrChO)A4Yqr-zgg|Eh#i7-{|`wP@;|Ln=kWZ$G{}Gm$H@ z^6(JAx89~Tp~CT37=wHeM`_T~{&DD$7=Reuo^)xo^t3dgzb|Wp>e^IR2lAJf>c?I> zV9kcehi9h>Szt0tyMNG&dlmKL#vK_5yXIInC86CfAGo3xGrA2IMmpf z-KW88ncKA^Gd4cn7$bLT*xIQdhE|++3Gneem(#ZzZ^u0%tr1 z8@8~paKrHM?Pb+s%|zZyGY1|aVqa8Ro13iy>+Ah&U0j4^JU3_E?%hix+Lsl6Ji<3o zZlh~K!BLf~(pe1ojY#}$Qr070+@7AEXgLV!Z#idQPq6Oi>o-Et``g~qGSp%yCWl7Q z>dMNB*|%p;3vL(DdhZS2*|Z z)DW0*&GF*i{{F~&B+;|>>}WZ&ug2A8*Xja>kjy*X%sR+*WcTmiZ+c%>5>ACrLx`iD zE;W2JTd!|r#g?g?^Y1zw-QP16cDK;S<)$Xg{xtsb*VaNitB$*+pBfKN%{|gbl?(#| z1H0Sa!%%PfR?6hcKYxzFM$(D=KReD~vSGWppl80LvlAm1 z9=u5}y8gcWckYw?`UIBYnb*?xude!o@v)iTK@}CE+-7w$9oE8g%ES%l??1o5fdi7* zFgeKx2?hs+YV`E<=$@!+Xat}ggL^7L`J-XpwY4?g%O`eNU%x*)KRfkYV!`p>GOqLX z8rfYPbRfLNdFX?6x6mL^H8-F?S1l+#o!PX`Tk<7BAZ*!!Kk?=1;{xMyPVenbF4nr+ zf>*9w(UmZpEM<-F+@;0fzM0d4mwCf%6jRP~6GePRdEz&VhT$kS00w+5?m+nC%{9D? zl%N342SpY>^e4y7y^78X(yx#DgKTugehrBlQ(UkGg=tmO3^O8X0ID9ZjC9^Lg{$;Jqc! zJpgPFV(@x+!l{uxZ?2K4_+vP`xV&GVpMNz1nWW%ejj)liae!(rMymFHPht(u13@~v z=mjYA{<4OZkQS(9_dl%Xu$t~HXZkHU&xe?D z!`w)*2{|KU#3T+S>(#4qhVKnD$o(d|>D;MU*|4D{Bffd_rY+q~L_K12)9He+HNNdv z8UzU}&rVR>nEsXxK+f&ta7$urFZ|s*8$HP7OHbFwD847~T%u;9_+(gVT1ibqyFY>l zr-kTrjIb7ZzGF%xAUL)!#&q@WJ$yF3x7zf!gKtSH9*+uW3nYi7%Xm@tq)B2y;cEA? zzPxO9FXcu;r?rsNto*u~=?^-4%%6}DDDGw};$)Yo+@uJTHkLSq*cNhI(ObX5JP!yt z3jox$yA`$=?(Xh^wpQb<^JhZA3v@(L5cn$t`4K(!q7o7*$H&LMLKs?w28zH)>~1%~ zhw|t7g?-rmiiqPu_P2iUpb>HoD<>!JomgB}Ny*fSv9T5V`_K}=>GcQHVmY&l{{g$e zDoN0+uDhp4=l5+U*OU1-*pn4@SO7hn1{$TDj$yfT>d%g^kdTqp&n+!+Ce%M5y}5p} z_oraGoyG4YJGr-5Kc5heEZN68p8URV&kt@LAD&H3-3zKHJlv6trfR89Or$|0>|u8b zhR5HjY`Am|6!O{t5v9-7U%p70)p;A+^ki-=c2c>WaU*#@0A}pNOH~a77|YM30b9}8+1aem9jZ44`UdFusM2W?*n;ID z+*pBi*%~UmB`PFDzMMjPcy!bc%+BGO(xPdtCx!dQv?-1WJ&wNyIWsc}VF-IK$(;!a ztgZU^PHVkB zg&UlNCR5rkXq0m0*p!9(SaO6+a3+9>3G#~~wPASpPBn@_$nWd~ zmrmeb762i&{?m(qLDjG@G2MJqsZAtQR8%Z3c7hkj#?UW{h9oHaJJRXV)y6~@1MbUF(sdS zn`*inHTWyc^v+9{X_LuD?hwqr7JIx@SaV)#GngE2#r}i59pmYozqN2`tk8P{-fSqR zC69*R7ySI{F^GYMYvg8tQdUFl?P?dke!06C9;2Y9tgM{NrGQ~x7Rh)my4L5Pq2rZX zP`IJc3fYedm5ZwaTyU25_?ri-zp zqz`4r|D?h|{io?UI$TA$o$ zjRw4(o!utfyxQd#A?$zH#!S6mLUzU;a7(+xMR!=3pRb#u%{rumzAgzDS6A0hfJQ8T zetDV=&88l}i;~Zuq4bA1cN->kciOskCfz4l_Umm6zRvijrluw~CB>H3b<@W^lH)~L zF_Y;5Ub}P2lb=#XrIt9yT-3-?KtzOAPt0O_v@xIFJBT3#1o$m=YBQshf`< z*n;~T&cKhs4xqTphl&u{u>=r1)YYZ+>EB?tI-GZUT(XPy!l%ENm(|pwnFzWY)V;_u z|BOdmq9nU0;}0Fa5`fK$p?!X}C64&CE)d081IgcKa;XA~A6R>q-Q zA!cA!!tlQknUFyJ$ibmFxyZVe9YJORHuSyIWzjfrhJ5*#gkHF%6iyo2Iwcl9;a=cZ zO)Gi$_%RVw#^8bi?rPuDFN>ejOlw>?fXL?G{T}rnNht&+t)Zo*<$?aQF7iIgHp{s`r>s$&wn5U zl;;Dtgd$50B2h@}i=m9q1`_B_$-(UBr^l3#I{H%t7u2 z42jJsZZA~mRSv6hcgUSHxM8C5u?4`DS3Y-8+6|Uw19B^h46(V`dw!VrGdO25wDz5S zj*3f7B>>JnxbpF+rZ4f)@iEH0E6A@t&L~Ut1DXddygrn$v77<|(IW*nl{PdSJ|rx` z#*x%z{$uk!Ugbg)r6&jy(1>dM-7C*k2f!Kt0Q`Sl&n;%h<=)J9>m$uMPTPwb7oaQb z9190*J&3MU<)h)?s~m||q4Ub7{(g>CL_|c=%ye|i?88+|k}j8_vzj~FlhpOf2n!F# zH!6Qfa(o$1Lob{;9#_$0cmD)^2-84-f z*Z%%}(s%kq5x*NSFUr^D?ma*F`&0LHvze@Cp7(L6r(bCwN~jy~hQw}xHZj|mt>m;e zRLBd>`PHH;YChiH18{>|sl|&gCm!B-Eqc|9@v6(>f3>K<^lO#V-JoB1CACym*@i`p zZEd)K4M-Xr8h%Sjjq^2H&+xAHR}W&NnTI z=T=*m+Ltk3AvSEl3^+VIJWfCaMuC14)crK_My6~!z{*GbqHrP~80OdxQ zZK}ZDRXI$uUcTH?a9Z!WtaJCB4s(!-T!JPCJRi>f`nc5)cR1UNh=^P$*h7!bqdt7R_<_w@_dxVQ{Yi9eWrO{%gRTuQ%t_Qhy5Lg@rjQ2^w*yHlQiyDJnvTk|0! zHJo9j%z>TpTyLI!B?0CZxDOi01{}(rEtMCy?_3&k&+k&E`InfUPGVtUp(;rIba&iVSSQYSoqcM`gnXK$W59c zn<4(OS>M;r=se!&+>-+SsH3MR6hP%so7))>eTltkk|ox*RM-t#nvOLIe0GLRTvbs; zL_)&x@#9Bph@{n+i`Ox)Tq%-SxOvZKQz=?UCK`(6t5=q8%NrXTx`0n71696{F%5hk zw6P*YW(V@M{Cik%kZl&gs<`!w!GFHq(#(bi7(SzT{rdHw$YERvjMp>3lx#z@v*>&{ zzf2uw4Hu1z!vJkoul(VSGV4xCw-fd{C{QvS&XsJ}uF<^~wR8EdKj{Q3eH*9_O`zK` zLBwQ>)JU@0&R$g5atH-goPc04=?{A|eB?Me-@d&%$qpeR4sCc$9Hn$Ao#6e3FHe7)16?2y zI@1h6$?a-zbcr`4VA%_RlheO_2k4p_-EsXt)t`M)srNnAzgzieuU`st9$((bD5XDU zIy5wN0Hs%V!V@oDQ(lYiFpBm)A$Nn2RXOTkigM$}Zy4(y6DXr}iO0VI{yuA;a&*+Y#dyoW~W* z`KbH>u&KkgKL>}K`lSc&Y3c2A(0$Nsu~Nwihg=P|o_~=&JeMkT?7(Jb?|ARA?dV6( zUqR9T=LKMn=AcH@75?K;o=i#T7T!~8a>2r9D}jDIMeK1>|G^b5?GywEp%UNIXQTA6k{_gKl!RGOCdIQh_OXnp>FUor31BMfM_LbxEWj#DR zyxf_ZMrWq(bm>vcM^2#jSImQ4Yv7GLo`p4EzhPyw(wi=gcS$v}!P(L>O~&ih#N;I1 zJ#!N5~f2Rna6EERUHRvXjgTRk{g49KypxVF+Z%cM^i%pma~?8lc?kLz2zg+3xEs4 z_PPf_`Ln%8YYPjPYL+KpKix^;A_X7r)s$JBJ+cfn++6=UZtMcJ5N(3IwyoW8DOKqH zo#VV{gy=P2&`f}cK8Dq#uXyWcv99*;A!l%C=sd_&h`s?T4?SBQ;ONx0RRz9@_<|4u zTwVaXyrmnwQ9{VsQyvDM{LOKjObaZnSSYsrz&L9Bt$}jZohC^|b*_i7P6z`*rw{Af z`2uol_1CXTZf>H$BF-%?iU$0wdfRoixu@zYAb+bXT0toDVEV=F1%Rn{s&Zlm9Z(#=NXUn;=CH1E!5#cp}}4R9A3mrj~I1uI2uZLL2!rc2E|!PDtHjd*4I2MZz) z&R+mnnnCx6u)fHXGZYCV#{{w&mxLi0)pgXJjla0@bON$Bs7uJfNYID2Bn)uKJOKs) zYn{BtavSCja#=x7kDLS_Uq~~%gsd@|1ncB^4SgUc(oX>m8Kvef!#_`Rg=pa58-eHM z1l0;N7em!@zU75MzW(a%^+Z9li;NTDAI$1AAXKl#3?{xh%u8qjQwJ+IH~t+^I>=2+ zeg3&`uk`22j7Dhk5V9tBf$N~T;AXBl2)5jqk@6ty@6lqIFX#Xp?=j;OcKR3_uBB#D z`G`ZpcVtu_-m1U9`cDizlqBTfuCdGU?A=>HH86s95UkVG09=y^x%Dx*mwo1VR~HfE zq`%wRkli%uhuK>j-eLNYc-Io}PX@q3c&Vmgh(YC1CJ86j&6A^@SD(J`&+L^tt@N=` zW8mgM*J=P<$#C_K3>naxOiWBAjU+9=TG*+ptAiS!zsvd8O;Q!zJ%e>I$dDPRMq@E2 z$HRcNMZXIfq8W%b+s{va=9Db&)@h1%jKqR;4m>;@M^(;f;r9u>scI($K53={#6b;&`@gGbs4JIlSdK;!SE4-Uk} zkp7qu8;gJp-+J|(Ro%b8(r6_L@_h$D3+j@&*;)X^;(*Jq?;1K&e(Fe?oZm&&$O{1r z7?+T6w(#g^T%W&3YlO5HLE)bL^$Q2Gb*s96^eV7CjrF%+U$Yc~N(7&VCnw*T0_T8T z2qDe3gdfk7y;589H(-Yvm#<&{nfKA|cF}NOwX;<<7=)xqne{*2zaB&v zGUs)1>Srl$$;S)O3X%{IY*m$&J!_xS+A3g?KE4v)S+YV#h_qa=A1hH9FmCk1o$$ND z;O>3|4D{|B$2tWzJ#By>N}!d1UJx`KW^OTqz8T(%Ke)5{;x4HL-YphSwc!l*zgryo z;R7G4zcCb*e2FpWd z!YV9GnI2B-wm#Nh53~U;*?BoPDI2zw$KOciY#b<%QMI5D6&n`6?(;aVZqUfIngyB6 zzobOy-f1p+S(GdV?01RU?y8t)M%ddMZ<@eMwK8hv_Y?DZ#U_M4&w!Cnk6{r=!1U-r zxVW!62g*L5X^DA2y?&u+AydW)rZ1eju~bgd_t!+`(6aWO!as(dYDo_aDkv8!AwZ;{ zsrjHdnf-RT_YCAO*6jUA7$`VaL(Qkg+T4 z6{s7tUhIe~vF&G{qCCV0Q&0|gFjOV4^hEoWn(^N?pM5KInUhoh&Ye4K&UYS-9??FG zE_)-FENB)@gQin`3n1uQCMG5pXW-5m85!hMR6*>sSi~1)j3`Nii!HIRuuAKvgEBK& zzJXD#80tW0+C*oJVm1Q)s@(nt0Q_q-WET6)~nv2WfGjf{*4dHlWi4|$T7#q$NRvLbqG>e ze+?r4A2V|83E!f&diJN3pu_!1$I>7q3;MupShu&(JYqzt#@nSAJHq53%z z#|z!dBAi3u%eCF>Z?4}n3i%4>1jUL4pFex#a2#xmm0B$j-`@IE;&VB&!pOW>gEAK2@AoegI+sJHM*(7 zt?cQMVPWmT5c`^%W1ZH*dPT#EM$ZAN&`NLQ#c?MBi1ZcGZ z4QrX+X0T-PKg{4aE(^xR!<(F(n0S4XH2JUP0Lqs+P>a>aY8d`0gg~ZNeDnENB^39g zQ=;^;8VG@)S~Kw7uN_-gX@F{63)G_%6W3~8UP54Hr5GyFe)!kY+M3^3=kw1Nx{#gV z&L2GrPE7Z~oP%6df%e!v?)G2dYYQz*Y`r^ug}1m+OUIwS?4VDnQhs;Ah!)=gb@CUe ze~mLUGxp2FuuC9?YdIQxx^LPMeNAmymnX#U>@#n?& zzcDzTG~*+d@1dxll}IuXoW#aanthmGUd97|qR^Y zu!dwd#HbC}{w!1;zGSm8Y%K*q$LYaq4g?&CbQi$S*e%{%&)V3Q!vIv9a`Ow=aXQFB z521MmHi*`urKL?9kWM(oB~~`J#>;7Xz$Bcmm-lW~bN4@=42vw9f(d4qmX-vDZKeQ5lMoYQyXw3?El`@37^`vRV$deSxSfGB_vcT# zgx{IB$E`XZJ(Dr9=5_Zfu>3YdSCg?ZQCalCAj26bB)7xOxxk&PpZi4esi$E9!6%wH zq=kcrHwZzG*}J3oDlp3 zp+gCejI6j0IW*~N=I=?z`h1k}Hdz+*eFwao)6=J7$6b3HGnw$h)Urp5@g7wsd_0&9 zypO;Ca=|Ae0=^voe>Z4>r0xLZK;n<S=r4Aiw7Re0mXe*b-kbucG<2-Mk|M z7BgH3Q^WuC?$9$|C`Zespd%auP0lYh)te?~LJUHn5=2HH7qoxfsVMr_l{+2EnPjcU zpOqj5>fZudesGammUvx-C7by6+@lfSWWf0bFe#wc<4%U!frZ)!m@1L9v@}+r3Vn!rOx$959b88RN_nuK20p1F?+?xzHu%jD`YZk_}{;Hy48i zfkRI)zy(W7OB6mod%gw9Wa9An_@R`vG?7ntG&eh>H(ZFqEa0?O$e^4i$%8wl5-PCm z^11ACo?#Jyc?BSQfyQ2uVJ9aimq%^Kgdt7r@jnRfhMYmTl|Yu=JpFeNGcdgDzS0MJ z|LC>%piRB1SLrtbR0T=>ziu0l69X2UYz`stOMvY~-9FsAWDwK-L5mK_$#$0@XqbOI zAXaQ0tN_Ma?~9w=ToY4>qQ%ygo6hqKP>BE$mCb?Ht6zCqyHWQq8aM?7fQT4K z-;tkntqC{)pe^sGgDpVLZcvt0R{nVmc2F{8vy&@xES!YKgs0B?h*Ff{#xbfeh=_>f zM#c3RFzMgARd~0!Dn*e?MJ)1YGGsvl<*gwt1F+FNfW7>4I<_n!DS6x7)m7{FRE$>lq&i{2ZBkHM=GG|M#3O)rP-p@K8M!7RMS@GS<4&d<{!4yFXBplj8d{}&6r53=Q z59K`gy9KnkNh<-6m98NX&g3v4_*b{lYtzhEIKKQQwC_V0{{ z2qMuZQ$~l^K17!FM-BQlu}VubUX<}fptuC0blr~3c~fH}TLFYgUzP$^Noi@LLSgF| zc%{rAJiq}E$O}rr__F>pSya1$WHJpTP{<9icZL+uOE+D~xD`U-W%;}(m@MKiR9jl~ z+Cc9G&iMW#85kTi1-09m0ZjOFtE=>jv$I0I)6*9p4HaMjT^|B2*hc7b=71{Bf<`79 zN@vrW+WJXr5$o1_GjHW9=e;F~p`Q7Peyw{DH2zUhB$qE=ZV;?L!359ou7vN&p@r4w zark&42MfW_-lLbrYdfFvqS#P>Id~z6d{4I8|KrSM_jjPi4vmh|0c~_Sy1lfflW@0I zFsJd1<&tp-OHm|P|A#x8wa@4#y|(5* zaObEo(RZ=Xllz4orW#fFtFQutyeUI=ezHS`TH&8e*Amp9pZz-lMX^U7BTMPz;fQ2V)V>y|u*7 zNS@MIL2klUXC~0K4tEE2|C3Sy<~M^y0vDPeRVt&0^cb7_`#L9}OHKhmBn34q5Uc@# z`i0&$iH@3AFt*l0^$F3p1FLASxr!v{H8+@F5m`m7u8<-3C>U}$B*^uX|jokP@NtB7OeI= zmpuXWzX=sG)!@wESp69pSquSmour_Ka}0rN38<;X#l@6+sk)^(U_?R{ZIr&V8+^N3 znTbn$LH?a~DrSsIFfE-)1 zQyZL_Kz-3)PF)8>>n@9sx%^_XnJ>Yk$_eYG7;R1}ojQmQP@Om;1^chbUve?6}s=#qnJAOw_X2}+D+aqT;}78^aU^K#?Y;+Au#OJ011As zpHmT_GTQ&p=3A`~nSMyXBoiowg3Jzb5p?WwY{$vUt&cUdLO*A;x zNf|`(!MGe8Z*8QE~BnLj!?@_NX4i1ifARBWoh+2%% zQm|n|%a#>?^;JrWIt0pz4!s=@o9s^S-|6b-2LkI8l|(r?IegRA7Q>O}DKORofQva* z>gl7yOusW8>hH06kN!Ezmz%+9cLFfI25S7Bv|iKCPna!gD8lXNJrI8Yx4%toS>Ilv zhA@R1Su>U?<~*Q2~e~!2Xu$7OCNkBGmFu>4DY|S-d=5akOwwn zoYmFUO;DQTRaM)hALNqE$)B49JXrnxbMI%>k)Pnlv{VqDz!nf-)0;tK#dh1 zCIYaVMjv`5LG%1GQ!lp&n4YK6zT1|Ek?Uv!*WA^$J(_uTWkubMfS8k>WkUNrR1NZc{`|8oq#ARBU(Ml;s@BoxXe5IEi@LZ;d(U^!qjRvk8@Ucm>&1ZR z2mW$0?l3q|DIh5ee{aQ2V(*I5(2{B z9F+)Lc$naSn0fZ7x4osUt%*$TL~l{H4xr4lB1}U)X!jvvP`V18B2cU>LYW7E@S#!? z5-SfvcxeNHANes+&3L3upb~a0!<93CRu$sY}%O)ekR z{Ygc+d(ad}@%qb%b+O3#62nNrz?Ykla&=$5dbO#a?hT40g1}^3_Q>1>IKN_HeF@%q z2!-XFV>kh)UKVnC1giG{0Tm}ygJJ3D(J_avC62Dv7g13mN&F_1t{;ZNFy(U~k=t(o z)u5!PsK|Qhl2VzfTDG423rY@iFdCG={FUN$v^zW~E9*=m{(TGb2&g~;RnGKREwMX0 zI^>rV9KHX-;00tMqYwM0^}g37on{;G;<5Qt*Vpa2wSPWC3nol@>Cw?8du$8m1p@;M z?XE3s4FM^sYCG8WBp?ohz;^ly;&Sn3r+xrUT~?Fg+9Ua()X8P zV6IzP7lG-^Yh@;_v3`PruVsC{=y3i3ySN6(M&`p!9yMU{Q1g2T@W&0Bl!LKxU(UdM z>%p&K!wn;X;fkpBwGd$eGn)oo+?ddVVwMD_c8fmRx%0ghhqLTbnP#4&j0SWap{Ul;(` zMQ~e{zK#0UQOqFNd>g=!*6`y;6hz)o%d`pxD-Q&0@~_{&wSdqK`F6wIx^L`-#ys); z=mm4g1wv314|>)isTh0vegCx`!=U2;4vLhLI}U|M$oj6Lv(ov|i|}wT5leF4-}!L_ zFa5)BruWZydDydO&ol+R^zS)d0yqV1%irvnh(72ur8uBUfrBV=>Z=DCw7Hif*~-vD`Q@!LYwELk3a831$Yl$Y~rL|IR*`^`L~ogJprI zRvbg&N?!JRDm)jzA8d*d{*QK*GAm~zhOk1zwo(kN;-5=v5AQ|08hV$)11HvF&_ZB%kXb) z?@n#30jJmkPz88^lp+{}t;09Xp`=q0oSGtYNdZ^=9& zIF}Xx*`)y{vxNWcfd8={9A%n1{$)9`3Hqp;I2%Beb#KOX{(jV9X$LL;BhdcSV9-Ur zz=)$zVRL4`0jM+3&Vw-#2?+@!?|S+i-}?NjE0Z(B?>b7{S_nG8&cTR*ph5*SaB!$K z7CC?U-G_N%0Q(3Gm#oW!!%7AEtPW^AIFj?bbHD|)GEsR2`sABxYHDdr&(<%|x>qWz zwYng?tKLpTte@~1q}&RgL;gTTicJrFZcUDhc)+GYPv_>&N3DRtDybTC@dlJ-?64~| zY^>8*Zft%`)Z!M9c8<7EHq3|<5v!^ zVwy{$`Z5@8-n}1Qlj*s`TO=~2q(UwtyqiZUt{6i8t>1-63QhFg9~2ZB_?9Q*E{Njg-u?&5&7JswOzrCJC^-Dj+Utl^S7aGgMq zAy9g=W3D-@8Tf#|?a?YPiuT#?15;{qj~s~tm%XZ8mq~%5LGS1wl{z zi-D^&tYxADLBMB6g_7VPuQIEvC6eKg2SP3b%RBm$1yXKc&jRn*2PP=dM_@oZprD~q zG5mBN9O9UW5IvcKb_f}P`&MODk~&PE!yHaFdN1!tKzy++Ey~%3pH*|OK5k}{&Fm(; z{Guzxg^BA#@+G_SBdg@7_7hB)+9jx`bNpjGaQI-yI`nF&H302LU^s>w zACu?)$6zDU53iW>slfz_ers$}5-zwjz=D|t8jN1$quWkSPX3^Y1)#JIBWvo88F&EE z{45JvxM#4?h!~vrcuw@AFJl7^DUAN|23xUvi`1{b*(#p=eC^$RgoVIT#zUHphleG?Y?x{j=-mlq z)z#Gv166IByJx1iH|C<08$JmZp?}WY+S+TI-gJFJ@ZSYON<4kmTOIdknMTDj0g)wcox`$sH|HS?KCA-K{Dw4+1BM zlCpAeqsYD97~F#pV>ew4LyJKP+|1@zKd=bQTST z@Ij<0C^z}hsC525j6sA9(m}@vBRc`{EI9JnG>g($Qs)~y`7lt#Uk#%Pd(b?K43#rq zey4g*G@9|jes)VwmYPXq~)7bF1n*%lP_GK)MUzM32?uZT~zw?lID zjfj>n3(Viomn*2@sJXg=g2d7;M(9sQ1ynE5Z=-Q}voh-!2Vh1e5wCu$o2dhdx4SJ% zRaLd8@0U$mON;013xAoMaOm~aB`g&1F)Ht-FMCTd_QH${aJqA_YUl)&tq>7;F&||$ zJhOqR?>4&|^Lhh+udBQUINwg#S&%`$E#m9V07r zr@%Gc7R^iq=LAp?kTtLg>wt=lwQFyYuYgA~p<}#tXguu|@q- zoL$SzWzCKYwqq76E!tsx@PIX^wuOIS4hlS5?7o0y*eQNKaT!Lg2f1TvAfh z2+kld@Rp|aT}@kHyAto%c`{M);smq+&Oft|uXnd=9B1mp?40v{jKL@pnzK`bEq#IRu4Ahp=+ zx^pAjvmjI$0gesQfb56!Oe54FyjiYd=oJ;sAgRIqqFayB@L#c#8C(th_wp!6NXu zaDeD{Ynq#y@Si`yRv@=>KHjza=BMW5B=pqPb?|sw5Ks}c2rWH|7_rHp>W($Ju1vtC zR2YxPfmT<@*Pr87C2!$|W_7II@0``gF9wzlAXV|_eeQgiO^IO+#bgzP;eGCXUYJfA zAZKCOu)+TIlkyT2@CytNJu+mxFoB30FWA`7($N{|bWh0EfuB4fgaM72%F{Sc)Z~^c za}E@&;OjwV45<3JAGq~lo=c$)Rq5x}^OD5X^o{?-!3nflhM-M`O{9_DNg~IDl6N37 zB8`sZ>>%XWS3R*&!vajd6I*%%UY64YkJz4Wg%`m8EWqM@RSqVM>k8CJL(i*6A}JS) zjg3)PxUJQv&nD8P)JKkT5#R{f&fQ0`sFUu z8w83c${NU9)px;wK!gD`mI8U61mtnZp9927zRRd21iV3nX%cv9C&mJj1P~@>=7`Ei z4~Lg1si>0a|CxTgSEFzK!vnot!%l6F;0|vdKDT?PH8hf-rZhSrS~SQLAl<>#FmNo) zZ1_w}R`x#S1{E{&4H!FCg{A732Gd32_1<3a(7gOM3kRaST!a(z?t8=*W;57{F4;Y| zAY{Xaj%7pZS2~dXtyBJCtl`dg&Veuy`tHF3HnNgx3h@1b)QT-VppWAp6B8puUO|Bb zlmCw?ymgCrV|Q)%O8hs53sPQ7kgQYjk!3q_y03df|` zHX=HMKw^z zlUA(h2vT;e6IQLHOLs3yi9oc8}{`Vw#~yY>6$HD?HA zD5(%4G?R)98A2s0Gf^25N+cr55UKFVkc`Pt=6Q&OGAD#gDTOo;ktoT3?au#quB+>u z?>l+D&wlp4_kFK>t#zx?e5jEpS=In}ryyQ>y1{5^Z|!3T{3AsHJ~;X1^JmGdup{h3 zllih5SFfM&{>8Wt2>i(#BipT;|EbLpN*3PeFTDC-`w10kn%IZ^Z{szg$U;NLB7Y!gS%_nFO$16=+K-hHVhb>y-e;$6|yU^0w8h}`1 zYgF_kFC`k%{li@)^PHyKO`{j&J%2hxb-kTH>N5w#N+^n>ZHC-)V0?)mjx!p$=8c~D z6hcezkj$ONg~sOXRloLn&7UtrbbGBDIcQ6|Ricd$i3G*dA5JrEA``b&!RR#uAbJxn|TJ|s|OV7#1u zms=KnS}3iJly<+2MR8Bf(83fBh;__^tUe==LxIsSG&W|NAJfUVqc9!>;uya!IcEmy zmH}Pi*2zFA*_NI45&AV+V8iRB`&nXJ;OfY`EF?l)0kjkvkZN&`ef-Gxbq9pirB3Fz zsJnZC=T$TmC>3wBkuJAK&L94xfHfeQ1~Gx_iY5N;%kxwBUn=dDlzb%ZL@z{ys4_9O z*yV@wm7ay?GMB8Pk^ZCbkK98C?r@1T%`Dx*4OsVnQ|tD4rJHm}ST)d5C9Oz;ZBSe^ zQ`65Q%KVpfqF{W|odj=dvFwY%Al z_rWwo1FYIPPO*e3`5Z8N_|%AMYlYcW%v)Wwg4f+h5M8yG;Zl0h;2b~aZ#Z?S=wHzU zw)iH!Sh@F$-~*)~Va73ZG$dojevL+-@Rzt-;v#N6C1yeH^y3b7>XcAT-c7K<4xM^E~UBOBd~+?N`7M!Q%_;;mfSCEdrn zMGy;Cg!l>vNy>BaWTvr6-F!;~xsnRHaP+wOdifF8TLznM+?JqRZ()b_z^|nvI)9z?UH*Q?R_3E1ndT&A$IHv~&x&Sx_Q2DRiQ^4VL*0 zRg{DCl`}u-s?q2^FfdhC));&Y8cBB0SXH;P`QD`iAKv(=(!Iyvx5)FeD4Ed>>{sye78MJQvQha&1FK4ZzB49M35!**tyc?NEuVU z4b*Q}0l|$U#?TWTUC|a173KD{%v4F%zDt>A>2&Pj5tXl5r`#B}%E}%OpOixg%E-NP zjG-f)vJ5#5WOk3a3iyxl1=Ec|e;0H&8Gc4p&?TKi5eFM=@@EjAeoYZ7(f9Z{9wYh= z&26VuKQ#|7R}B(s4CGjo*4g%RcD8jmg==vZ^fqP50ATXk$@w=cChh=3Bkch|FB;%O zSykKbNJ47%gRxic;cVF|Ni4g#B&#gE5D13 zmMk80D3@Ot715*aE<1d9sqJk{p!)GA&VLl=UQ+bQL2Nl^aw1L6I5B=$Ugld7b=RG-aj8AY@vX?qnUVP2V`+nZKdLse6U$vAt+= zRxgJM;ij(FG?X^O=O+Y|ycN2?&Rz%;@s*c~&_D0uLVu@;0W5JJA|{8-;Ywm+8yf%O zZfGqR0a{d+Y>i~2e|NLi)0?8sReooJdb+n*u((*0CNuECK0RaSgjA+ce)6H+(~_y@ zm;PP}JZlKH)9CT#Ij&sk7T3-T!ZC9!dJBjPPy%JwFt7Jg#{bWT+=N3{M@Q$R(t1Hb zg$#r)7hnxZ*t(WG1xAh5dhw4VBNn!li@lGHQ@UgO_VJ%w(EPau4$Gg=fq32dH~ z$|ef^Shi64{*Ex@X8L@+jg>qsAF}cq9TUdDISd!2warYu(%GT{`>FGSr3b@PtfNlF zi=EphaJxF>&y8e>6ZDd1w1xytWUS+tw_IIXymXY3cg(i!;#JJJ_m&RYsQf-<3zSp$ z`=KD%8+VbbwYt)1{J`pk9i|3*WYdX!s{LOPE6ns|q$PdIY|#Vy#wv2(zClSvVnkupOQ6ONr@ ziV6xt;JNnwbkYPAv-raEkYX1rQU@7`x&_G4ecfZgFpBovOI*A9QiKP5bvU5DG$_8P z)Y#V6_HE+szAJlVOo|?6Wqq&Q;VTrvzPGpo4RBT6<*wLC<;U`i>FOgd(CiE-G_GId z7w?I9!r^%2$PqOVokvgUVQ0Op1tq}>fN&|>%wA)5A6Z_@KCcs%?#?{a%Me(%JS<*) ze--fbO!EPVyL#&mHuZ0^;hNYl*;;R*ELdN5UJ%El`HKMOYgX!P;nM;kWx(C!XQ3Hx z?IGFC;J2&rCMW{-Sg@C4@NZ)wyt5coD42tRbIb3^;4GxVD%hX`5u}i`^th#!m#u+8 z)S+#ZV8gZOXnt18w!w01Z>2pv{+>=;m_)39aP8W)RpWt`Tw3AE>7Cd59Im4kR*N>D zbGy)TnyKDORZC=U*8;xB+Z6VtP3UVsYE4I-Do?2g^W^vWysfy@ws~$JqOr%;eUo)3 zpUQ`Le%taxuxzFcwl2E}K=4*0^v6t!3+$t^IC2d-A@S-!EjjqJ%(~fF`rgu^B z%)LWiS!(TZikoOoa2dMn;c@M7Iz1RVgk<}s(qkq3K9=K{`Yp^&VoyapFo%ikT-Vzz zsXGV2Qv)L`c?g|*w6^H6UJ|$#A%tFrb|kaL18x8TBhfwEEr4lnjcqkxd?ggX89RmQ zS1#5HNarZ((e5EYE)DsY!YWS%tlldwkSO|;M)}}uJOlBU5$ueqPaPXb=RPQz1<+Be zY#WyLqj*(mxL~E zddPBKJv7sXQTaa+b%(0!*$pgg+UWNff6z_7G;Un3Q*eC6Qbu?sFfvhXMf&IcJJOUmM^ix~}b*FN+%dpYO4j8Oj6c0`wFaHdtL*>G^io@UYqzCgH zzBauocKrNa`S0MnXwhZh=D@h;^E_l9`7ZEZ4!QvD<$s8lEq6FtlmqFi_Y7zKlw`Bn z8FT;7rw5@)008g594fY4)RkmZ;i^8pz3Hm0ZCkd?@8sfb%?ZwEU>v-=^}eB%+K&zW z%7NxSJpO=Xxlf!p(O-4N^H*<@fx1usEI(_fU#)i0VUPi4(ClC9cCj%ei4ZLH_4S89 zr4fT^-8V>RkWrPR1~GSp>UF1m7mGvo-23qC}pmLWh3WhvEl*H zE^{#VxQt<1K~bV$(O_RxWNq}heg9n5FQ)UOp*-#u)ti;Gz)TjtKIU=g91WcixWDvg z{kXWexX2N;FcVN*V3YF!yFvwLy-FtSo@zk6Gz3}DMADG*h%+`>&f}&JYg1Z!W38JG z^(y|CKXTxqge9fnH$lr@9HAr#rs!7d(p!Ai@C__LWfzmR!WjU~9{ux}xCfkM>RzWA zVpIXD!Sw7@*UlUqe*88|bX2Awu{W`P&bP(lApVSpixrA#(S77lLB6ogKGc|p+N_Gd zmA~?@ACk`cGm0#ET6e^QPn1G^BBT{Q`1}rH9kL#xN5FTgoDw&B>0Zp<3w#NWT$9G@ z09k!s)s>2tcy{+c^V?t*z-PF$6f$9-RdtO+gpSdtaAxZL{(-&B$49Of;96bfdHkSs zMD%deOlWYh{)^vWsZF?H#V*`n_skLiAge7|bne|cu3ZqRQYdRPtT=odnHe{x{t^&MA{Pg->$A7O) z*D7Y^d)zb+ocVt9t8nG?i5N(xqWkPer_8qHMs~!O(7qifo}=29{VHi?+sdfogCZ!Q zWcD(!rxXzBE$OD)pWs(>y|bEE`>UMaA%%SvqeN zn)ZSXi!TjYO#I55;lLv-BXb)b9Q_#@o59Yj`d+`L+~9mj(LEjp8cHp8bUh}uSUyW? zg$t%v2RBR1dKnMEizin*mQY90Vec$rfu;@(&%??dTUW8m%}SyV920Y69c8P@#nArQ zp>r3`dEKrrjIi-JaXw(tKwFYnW_!=SXWj#qhnMMOdwcsJdXPonQ|P7^TOU6`g7&us2eGN}s;eBDV zBSGio4hseqAH0l*7Z%ZAY*{^BBu$x}$=&m`cST;aKi2n>9>~}LYR|eSgqEmt7@)Fv z_t0yIbu3q1FT(tNvVkALkU#B-dXG`1X}i-gjaS#s8sYxbuQ0fN-LaX zcS1kwpTf1EcjPt>CR~kHhR{)p;AS4VuNq*7zs|WXQZ1}@*WVY7vTz6E@*Fwg@I5$h z-yvPyr#^Jb^m#LJufHt=K#CjuS?QPEz=BiakR-Y>`0|K2?Azd94Z7~_wc(mn?*-|; zZf)(eCKSO+B`+Etp-rKyHf%a82t&pzyq+|baZS9*{FMn@JUl!#GnI!l!}TaT7Pnh% zQ4$xClX(>;5D-3ZCD-$ps2SG#ou>$CQ9KnDIfxofqY1zeQLA+eiUD)obUaL#;>=gQG6RzxR{NGz$Ztu9=0f!(T7do z1t~djOSpls?KT{t?1I1&HkqJV9v_^NuyitkvBdh~8X1Zqf0*I#Y3EaNvBEodx`t%_ z+)qNCL-rur)WiB(K4z+v*;DVeAYQ#`$HgiBa;Glwk(`~H!e(io-@EGICop)|;&LCV z4S3_Sn$O`?8VbaPOK&|ItQUx#NJX|HUE^Ce!-Mu|9<=kr^&FWyX!_dVEkhg4;g`?-XrTNODU*pS!!AT~HLNPxYc(~_g zwYK~$M>>^EwF>|wXGj>!-nUMbh4#cEbO*;Dmmh7GTa&n*x6*@DVte{@HL$*zukW!v z#BkqzuL0yK6fANe+`mot8P5ANu>o`F?=qEI_%4I;1oEIP3h`sUsewgIB~L%XLuGmy zt@q12Uh^f7CkG<*cWe0HMjbq&RJgC;^}?~R?@b@JfdYMg%vcF-R8?INOp8*=Ii4Ct zfgN`Kz%ZgctC0W~_0Jc+1B>Jqo$}e!r%%7}_%olcu$$lYmF-G*?9PJf0BHD9ARLM8 zF37B5S6CU2jDSHUtRWKDd10UQn$tFR-4@QKAsty+S+Z>l<%p)5;^N}_x|j3N_xp{0 zIxmLw%DUUL{;(c)xnb^Oi!&=<@(RQNZ7N|1;!-u+$8{d$Ng){18z3l)gRWg z2%m?=gHe$kH;8)M%doFf5UNiDqwmIr&ZzWf%1@!(C^q=9Q0A)m!_4@8i)|YY>O@Hk zqkNATsHxwTyw-KkTI5jZBD+XhkD=baSZ65y3g_?Zg)M$Mr=5SH&oKmqa!cOVd*vQt zTE6(6<>M*ap~`DED9Wii39ke&VXU49aks@uCkSp3AtDco0)e9g=c@a|0j$1*94?bf z7C&atK^Mav1D_?K=sBu`NqSuh5)z0Q3Yl>1+W*wM!Ef)8M6kj7S-IF&TtDB!hwH=? zD7X_B>`{%l!DP6(q7Ux4W@2*Y*4>R}^A2KLSm@B|o++$smwb(%LF%499jR02H&cPcok>-i(4yE@4_LD*m27Fs|5mSq@riZKw?wZ3D#t9kLJ zApqZYsFhoCRv<+JXiggax7YBO01KkaOzi6F@`p1ccS(cYA%);q*oS^#UH1upW7G>Y zwD4er6yD3^>x2W$4!UPn&P+cx;TDQsL8wT}O1gcxRY@JZnOE!;eqkq?DH(@~dE!>L zuq*&c7$y!}CtGGgYp{6x-|u{2#Lv5%6CdAmC&uUYXP?C5+ITT~U;0z!VaWjC)I5}l zI1Zcl(Cg_hnYmFesWsb9J`d{m2(2hz;c%h1;?fp}{-Q_svwM(Ow-ntW@*yc8t zILeW5+6*pAk30)ST6UmH%^moveR zX?QEDLmy<#KjBR*U{l$(>V?eaU=bL4oQ&Zcm`8rsoUrHY*C+Vib=D0*Ei693yqmWK z$ll2j)gqY;p04{(LO(?C2480{N8i3x94CmuD9Q5|37O@ExUD9)F#^;^RFip4I@jet zt`hfGMv`WQd+y!!SRr0w>Mmti@+;G z&N@8J{Q=Z&q?l_qT^U5rAl2k>dk7iF(1gsw!9-6u#1`gRO`PqhitV6+q?ak~c&$Hy zJQQ2v2vtTWey7QvlQQM#$;mcnRwl3#=+??S>dKr{-k;wY(wsjoKiSVT2opemqNOp~ zq3n0cI9zm<;^iWn3-ta00c&^0w#v=55PwwEj*R3Mvz=|e{zMr}gKmc<#ET2tj@C*4 zx-Ip>x{@IGe>h_)jkh@KSGV?)7*f-KI z>hDuy*?wA38C}zCqkIvgZ-**=vmR-E=&pIfssXGn>xN7&M|Y~Xj7SsF$x++u8H`H8YxY$J>doR%0d#*+`A8kIe=V+%uTVOebS>?J-Oz*3eX6^*O!L59 zYQ_vP5*gq)JBM(v2##4b{|T@6Mc?94>*|{p80l-*z%vdUE-xCR51TXmq%(h7#Mr^o z>TK?lw3xrJm8G8rZvJq?nV{h*f(gJd>V0oJSC$%a^tS{H;IJeeaDvlEFY5EH%ttZ~ zlA~D=%*ARxUOB|c$q8QFGke>~o1pBOK#d*8{ht?`rP`XUD!Wi1v9PiRpD$TB*PADd zFB$9q8RVMJ)5F!H3{X{Q>^E&IjXfxChi#~9`;7=~+ObSD-;o|8p?+=`hrOMrx7UEy z$+y>Z4Wct+xTvxD$F8_dw(DASZ;$3}@*@fZKZO zHH0KbK{pCV4vOMk1d|1aD59T(4p_NT1aCdE}QR zRt=oTp}dRL&z?P#Y&mA%@?{BV^8A$fab(9t1tz!l%CP)$2+}|9oS1l>Jurd$tfd(# zo#t7!0m`druB- zur+YUxf1ic?zob#P@8FQ1ln0RcCuB*5)Swq~=y4dC=)BHxZ z4`^vksZ>11BJ@7-EbZ1y2^Vdu*)jQKE@A&>A{f!lJf8WnJ=GSQzkg1A z<(e@?p6jqej#?6RHU;}M$M*F{)77dT!6OMrxahzR%Rl>g2uspedAkWyEkM3pFU{(6wcPb{IAHNhlj~rC zRW1DHG}(-6k@lwjQs+|JhFl2-NfoWm$RMXr*58{r81;AV=9a4JNG|-amX6My4QkmK z2%`V#b$0CFz$+|IE6@)B!;bpRK=Y%3umWZvBC}p~2K)*iD7SR>J#PK@^^X(t5$*R# zRBM=T&3GOe(|1SY#irB3nYYJ>sb zh}#ZIB|C4e@aYK-A^&QCao>fLDffGLbGR1gDRvRvw)G%vRsW=b)fyp>27+Y6+obHTJqq zbPX?##a<{U2kyRUkd+Kt(-jrD{zJbJ6VJ_L7LwG)vdsVfnhUkDSGdzoftiWox=&z< zw^`#p7y(s$Ns=Y4$R>UCeN^8gOd906Wl96eGb-SNSy@=^b@i+0{IUZ{2uF zx`VI*bmZsG1Jspz*N=qau3R2>W4wr6Y9WbB(A8&V3HI30Wc9B8o2WVa6KF$emF==Ai zvyB0CLjfeEGt!9M&KrY_5IV@M(1ca2S%QS|gP-aJ59%%#h|wSbJ?v!|hXEvNK$~kJ zrouV9{u=$cA*$7$e@c@`jwkjQ!Q4)VNLG>k;5^*mT*j#U_ZJ!h7s~fuU7R%}6Elp9 z?IX=^FM$I1C^7Nfj=6F!f8Mk&;K-ls5!`8aBr3I9Ic#j%5pg1OI?oGl(r+rA9-)j5 zxx1GQM)$+hNRqUpvhahAdT&|6bEEGK6A>FmH(9`#O(8=lF&-10h~Mt$morfThFl}+ z36u)gh1;>Pz#}egJy`j|s6>+PN%Os9x@Vr3!au|Rxa-~D# zSFbpAJ=FUVxZXPneao=hPg9eszXw*b7-a0qJrA#=oIzF=;Ux}@h~2A5r*Hk0AODSO z@8>dI#==5DpZp0pwEBt1uFFV!4V^OdE$Kl8rJ|1dj(XT?R-Eq+l@Qaw?Y0bzp`EbC zW9DV0MvO66D-LL6AVnckI@4+J7)NeXP*i*mv%&yyNSc-!yz^Z;qdXYT{}C>M21V^S z0L=hokR7`Fex-cIRoj^#IL_%rlPCSFg72lr+E|jGZyGngQ!u(@s`2~Oi)G0v^F@ND z$VdHvh?96fY%?wlO$jA!Ru%^T&ky^ge1-1u(PNOO9}UAORB_Qe*Y2kc^%E5hNCAz- zOk4~qMXbVV3149aM@#gYUUvAh8^bATyb-29b^zpE%B`T9DYBcNv55pN8Od;x+Km;i zsA}bZ-Dj?r{e*!08eOylusp^}2nDr>1dG7rk$7}Ci>T3(t`NZx%2fMmA*oqqy#S$? zqicyH0^yhz;eK0h8Ja}3i=OcM&N$JNyB_j(N?5cfU&>ImwWvPIHk4bfY1_?H+Klu+ zM4KW|ufUlO7>R`(nZaSlL-i9ErMy!O%P|QvR5OcJ%gl2925mN-tcLsE>ru_D+T$ug z+#J;@R%$Gr7}tZDX^aAdS&zqA?E7s8)Dq$EHK*^pEnc@s*gM zLAqMDi5@moYzw0VTc`8{YFq<>-9M`TA8OVT|ZZ3DG1&( zyWI5x9{au`r6CSCV5P^$xR2j@1vf38r*3F0v^F)>lttP~^Yl)llnErX5rmm7&k|H< zLtzeYD`W6a{H}ZA1wXfmbLwpI8GSm+%M^9BZQ-g%i-QTDgU9P)L1WTN#lze%n0^fQ zw}p(>3jB-9Pu8jPCx5z&)&=%CP`9Fz@SdEb=^=j(%b$8`^tbQA%NEmfA3R+83qLBk z$++nw0Vcy4Agj5$)w-F-D<9zZaunSUuqw&NGmiZ?m)pB;r!a$iLfgeR0g)!fJWL*p zsumAkT1d299-x+(ICmfQ-(JzP>#aLIxY*MbD|#FTN+#kU#%x&(s$Z|yPhagF8Wbd- z-F1;)#zf5{;Zg=3o%fg3WU+OCmQ7ir?5@!<#bRl#){lCW4?wYMoHa>4o`SUp86AkV zPY2jZ`Gm_3e2RJD^Xz4hYF1wg__C-Lgo0vEMg6(9#vBCW#pMZvH!2}vwyeEy%6E(1 zA#CN5Ts?j7WzhvBdkBbz7x7?nC$@--+eGv^)T`WhC}$C)Cxv-O*pheP&HOfv-w7oW z85p9b2f)u|wSwj(n_KRS9duJ|-cLs38b0oNeJNSOx5MrQ@4-i%pQ|mmj%ag^qm2(7 z4Mf8c#?aI<{4xwS6UL-XGD`-9(Md~QR-f8Y%!9iR;ancb=fqor#rOOK+C*C7cRtVK z)RsP6T>Sg@?{&mr_HC=!?=$%c=OHE&*DfMZLA#Y1Tl}B!Yp90aSTOIdf90mX#@ca< zaT3A7lZOf-X?vHK!KuDKS)DEO#0LN}dVV!S;j-f~dY26(Pn@k3@=yxB5qaS$XV!XL ze{A5^B;gJ<;3&h;$#y_ZEg~mmI1@(a8^7kXRa|bXutwI38$-e%YZW>MHTbS1cf5wV zEGsu#RI(uUu7mIS>74>cfqE3CZB5vZ`X7eHnqj1sir;Mtl=$ur+vSTW>ItD)UHC}5 z^KJ8_E0_);g7a8ZhR6%tpOKIsFttnn?M7SMk1={SCu{U0Gldz@pzr~@iCa7sjLq^h zD*duVXa)|4-e?s#nfU2P(;=9!8FKHScwG+ItxT|x^2M3nSFA1d@cv2$74O%O{S&E> zgmFR2hwEn$owwS)6s%jggjR78zEj2%-EdJt+|c6@-mrn5^)X#MXb)Eq4Xq#KM%fkb z{OiGpomO44?(VK>ba@HJOgPm5q}kBZ*Dm4&MJO&FNE-un!2R{o#cywZxq?@Fb{9zM zc*cmc(|N8>@|#p;_J1X@(x#Oa=R*bp>nrXiCMK_DysJou9HmPC8x&T!p3C-J30HB1 z-S7ywASALItl_hHgUW_1Jp2$ez`;>5@2Hr5qjfa>j=DbX)c4pOJ26-ehi)!$?GNx| zI!PIXds+OZV{t={bsRU_!xlLDBg1-zf`Qm`lgTBwYSM%0C}))_2-Wvc6mYQVr?cM% zV?mYR&w%j?xmV*48%nG^4i62|PZ!wbR4Ki2qir8C^m)4Uckdf0?}PbdSV=1#j(KZ? zc_it=MMw9XdEZ?B?!sAH5DZcP(<5-_7|e3$xVwCPEko$vR`0IWFP-R3P@GBl?79a- z>jKFQ3$(YI*z!POPlx6*xq(UFj(FsIaztoL{W+0*OR*5b2O`>i5B*~R5@}Jm&?v4* z6!N8`JT?=hGyX&@y#*7+8eF@2X259yfE%tgoeqEC*_TpZvOJ5MHOiUALDl8bC6Y&} zK$D+Pu3hXFkSTjNwx?hVWZ)WPj1kx(tVpigX3E)h-wvC23_d3g!q{Fbbo6{i*5yXs zugunS0XV3jIb~^+N8>a)KhdJ>PzR)i3Q~~)d_HhT8B!T73> z>x0!QPf@FO+HnygVP-AyjG~Tt%43z-wpWVhlLK8v+p_}cWhiD(z-*mqz*XL z+FsORZ03DIi;OH(qeT!H&(Daf2f!Z1X9|~DuoQX$2$^B{Ls80hcAvfxoV^%R7=XuR z{Cf4D?+(jqif&3bCm6jH=6~Fu@85xYyvHf8HY10okHAsS*SYv=nWp;zZrpETA|MFZ z4&D*J;Vlt8N*ah!x(x|PM1__=L&>6mu~Ezv1%+q|F0||9or!7*vG|S`JP*3S z;8FFx^p+IJmVOvC0Y{lNuN?*-7xVw*!oxbd!y}$;x{m+EKL`?8=m+vx97?_;&*qP6 zzXvNJ54825+qdiZnN(;#@*9yGF4LXnQigr>ZCE;BJp8hb_>R>w=dCx@t)WoIKBO=@(J4#~2PQLo=dLD-fV}S#~eGA8a z3K(|qK^ATX|CUwyh%Xn$d$;{+yt84|0a*^7%>1EXBh!Zug|2*Mq1%2g_0Z23fYtBg zh!Kc*&{ehQh?eR~*{ZRH}m)s{E z9N7Qb&Epwa!lS_ii3UC>BArN?-YD!oW|i{|_zExpWm$C}DOTzyyG*9;CM~dukMW+{ zVjpWgdN5>oh|JMJFUxEmrA5co20ZzqBW1M_O4~XQWH;#v=s2iA zJ$TTGxJq>oGy7K_B3=j$S=s zjpsnf=qQyeYeePK=i?IGmA77jP9~S`UQzz$7VjVaSmSDY- z|65L}5nhA(uS)}tU#gvM{DO9Zc}Ysa)2B}XUT0sk$jvo}EneN*w{OXSKd98e?ctFz z;qmhFg7Z2E9eoZ=ln)6xIGwEGp39uaeQQTEbE}fc9y65m2=&dc-r90nKFVX-_@ja< z3)pggAVL8(Mr=$#&HK_V(pzw=CAD_uQ5fX%cu&89Be>k5fj$ zS=iC4*n(_tuESoZAB0si_0%r8-!B>wHQ(zInPOKb8A3SG;qLCD=I2w<;u1}L73~*unACh6RJh~wfOd3B%FoT(RmD)17 z<@YZ*ujqkYoQ42==j&RbsjiG8;i4XyqZN}?4~V;5kNk2@&U9>q2RIf6_iYVC{i})J zipQ`LilvO_TC4beG~HT4e4*V|x=fixq0i8dVNre7Hkr&m*(pTRj0?c^(U`#hp?)OY zbBuIcJziJIfokfXDcz-Sf~4)oMnM9oYlq}1$?Dm45dEDovi+rLQkrSMu_ER0$K<1$ zW&H;vM`T1&LlUv9^pR&MCSu4!=Xf z(HpbFRzr&SXidTxjM#<{6ErG@g@*Wi)~*IL-1Oo_gki*MC+3kWyZ2uF!T>bXxqQZ2 z#Vb+*v&P(^Lh=kT(a<3Gc@!foF=ZD((fJ}vCr`l7S$q#|pD?(Ptm zWy72lrh2Z4zr-%}J&sK1Wt0B`Pj+1p$uI8*AJ?YP_`fSBKkh^8e+xmVN3%k}O2u%4 zTE$Ch&iBcL&FHOv5sB6w-!mYNfojNtt0Ni_y4eUr!3%dn@Pv7xD(W&)?GqyD=8bfu z{AvaHGtRs@ySp=ZtGr+g!v7s<_8sKFrpqrBblc@y%4&@x_gD#yK}2Yiu|mZp00WO7>M2b2`# zxLp{{&f|5v4dCJ#$Zbc?z%HK^Ua#7{;NtR{KPni$25SnKIrzSV9Q`?h5_x!S4H1{1G)da=3J$4sj(ytRB6&7MMl&WZ=()`8 zwlQBIU;?xj=axF*gGg5o*i7#&YrBAbg6sJJQH}AkhlsOiOv`m&FpZWm)%e<-87*}) zwYY8fIq?QmASzG27yo@Sk5O?rqE*Irny0&aHSEgHRlNG_)7xt_4VJHcj=6pM>eqWn zo9QeeiJ&d0WS;4G=CzN)x^2^IWRRxjoNtebJjso*F{BJ<58;q{eQi zZ*K17cG;YX;o%3L@2nhebOeC2bD$AzpmtQF&Gm_n9=+3MF$?d|ghlTT#&RymY4WA; zHbn^3?!qAPBp9-G1^6Ski>Z-rIbjba`!**?8OhyvI^8Ul!QcjCM?1Hh*H%9R723Yw z3IQzOUQ8w^eKg6I>NrPHK%fxanc>-JC9i|Gcq|14*a%Kpu=VGH9}E=54qItp^q*FU z5Nom;f3EZ`0;glnJptAleBvsyq+tH*&PClzh(A_<=#M z>AUX04a4H%ZY{tVFsv2^&hRo{==U2dOWjn2UlDCg&oA1}Hs&W6^QIIZ0} zyaZ;^Gwh9!`gbw!7{}?x9-uiyhVkudRG?{ZWZ#bS1vM{GW+nal?)>e|Zu{*qJ3A8~ zE2l?t&*MRW$z)vN=q=(nwmQ3IUt1CZ>Xti$e@!YQGFVWiS4 zz`5|ZFAq9`LZ_*zN$>QzECB9d>B~xhavCHSBWi z@0wCiT!10G9bh9KndQR|=`6u0BNMFB&sh@viSFI4!nFefdkwWMQUU8BIU7RPOnn%J z@Xp7eu6QcFdGj~=7SZ+EhnO6WH_a$uT+}Mee|uQ&yb``q??CE4#Pk>l2Pq`6tPJqx zp~o_=J;XvZ9?S-h^u->ckZRAf+7IY|b97emkJ_jSZgnzl`0I~T@|Z%leD!vt>ul!^;ZF&H2!fIs+kuEl>cs^B7iay@F6eC zkTQwdVM&I#V9;ec9}N|qFi@NeF;AQgrztWG^6`LXq-Y2+32fAN} z%WoY%bcmyY`+>~2cTYJn#8)fCI}yo18~jXpuFSOV>Q4N#dpS-#2ZEGZF%17Y_MllJ z1or09MNe1(qWVO54@AO-xu{7jwqMeVii%Qz2R-0d-VYvN)BDNqq~HUmg{inS@$SG9 zFrz6nqu&eRg_N-ZxD^BGK@0W3^yzAE!!Kn*)kTMJ zZK>sx90!o(5}_#auyTVtK{M4aOO}9 z6Lb_rfVfNUfL5^2`cs6QyThz>ut*X7=c|_fdXkCTfh8F*$DwJ3^C)@V=2?!C0W1W( z3XMI@ibTtQ98630%{|vMVn|>6MoPzl$Fr`RxOuky48uP2Wk0f%B+P5XtIj_J^S?>jPpmlWR zXrH%i@FjG02wMOa0&Iqhjh$>e#_67iW2~?V;$z>ZM`A3}xo72K-=oTOX-rBXmQERZ z#@u@AwI$;eJzsyTKL?n+2n+KJpW8@??eK@CsN)+V`kvPr^dT;p>j&OZb#-UI&~EhG<( zI9_a!d~|lM1TBPt>`xN^$NM-D+WyP2&}uVof@~8?UR(Z;mtH0)#{QkWy7T}fRyrz- z{y_JNFpo|K46|AZAJGs$-ljyK=bM$McRXTb=6~67r6k;H_cAb#{{Hd6kS>c~*kk5} znhR}-O1c=2afCsBH5goe(8lmL@4tz8vIvN1W5*xfnEN}XKO^SqA; zIwBF)IBlnq^k2HA@t`t8Pimh}xt2`f{o}w&sxYu36M+)&M4r7>>C*IQ%e0=%a}P3s z>G)Cz5P{1dU#uqbKOz4S)&%QJm(<%z1KUqwoK(_xO<;Oo^0D|U2uB1BT?W8l;MckC zF~2`?du(Jx8Ry#)W>rt2O!Xx!Hx;YmMNkZDPx-u*%Xbze7>J54O$vE1ky@42ZdA4Cb_kxkHefvf0Bd??E@D-Z9=GQNXa zSo0@Sp8aL}%goXnN8mr5IlUG)p&Y-XmF+VcMbaf0p8Ak}0wU7rgHY*4y|Z-H+t;jX zn;|v~^H{X^(3}Snw~5jR{=?aYjpZGFwbrg~EOG`@#bY=H zpj?AUogFQYb=33SXri^R|w0B>lHIpV;k1zji@nl?})PSLlM2N zXP%xS9kc>qn?#XOgG47{Ws7|5uIlZy&oS^N+7umJ8i{;&5TPDCFbU$aXOn3&v)6Ny~StaIu<&*di; zk#4vT#6P({rW5nZSKxL2Ic^L|ZgUSagyhlSQ)+|fySd^;JR@K6VS?%p;mnbl@QtDS zeoMU5a71Vk%Thc9&b|UnxFSosF<|1@qittbvpK_%3&4}zT21M|+vtaI#o{%v!(!Ra zZuP%h+u1e%qs7jECWb!+eIsPCghyQU}hm($|v;zf_T9RI)(G%!hPnRGYFV5`+}VniKn zLu|CaBXZsWZz;aqVb{o4xM1k zrE5Z5b?ye6N7*b8^!k#+sGhWtE+dgK4f$?diKzb@+TxHONTWZyZ5 zoi1MiW;h{FW-ygWcFe&|6;sm)DK;%I=H9(~$lqqb`}=c#w3+vK|JeKY|Ft|EGhCH_ zXKS)VE&8KLC}~CjEA4;w@7G5IHhqQnL*_ZdTfjj2rch>G&QAD*lpaqA2AsTUdJ!6k zZ>a{n8m5*B%K(c5v*lX7`caUxC)zDXr9Sf?wi9IT$$4~C)&$KPqm&f{1=)Z3@}912 z(`Ygq9UC7VnpJH4n?=dRfDgS6$HR2-KHpVl+K=ov(trd)3G?ppMV z>B~0lIlMW7bJwxQHJvW7XGc$am)32!?X<9Wp4<#H>~AJi?i|~yIg$4WEvcX^K129{ zm|x&^u)RP?+ndoRF)?w|obC1))}r4wnIB+HCF#aVQhB_~JG!gno4Hj~SwMPikn}hd zb?$yrrqhFtyBSgG!^X3ldtGdXyDYbYLC*w|TIC-f8a-iqg$xgn-5cgbHq|r$y>KWZ z;P+di@cm;C*P~+Hmm$%-&p)kD<>41aMzIZ+PbGqCXL^?T4_7#wSc z8h_hN9+AFlmll$GAS+iUQK@1VtmJsq8yg#miglWsn|lOxcF&Zf1}@kjUP6cgHhve> zwXN?Ka_!lCd^LQ~>_Sd_Fxl^$KRj;A9qHD+D^LGk*j2jd$9w!Jla97^cPp z0aQ%f_y;6A;;t}7o&e?BzpREqFBteyIFQc&5UHLaRZZ9=aHlkg>$HL>}7wy<+RCxBJB-RV9v*-zRa-hHY9->;0O2{4kQGxwEs-{;ePvWUDAc zIk8ma6jv*H<3{j(h!2uFfLGB3U`_*ra3%{D1`3)J?ga$i(l~W3rh>u z)n<5UqJqu(Z3dR#@$&T`k;$W&f;WPd4pNO90?EuOW-Ykm{>OdYT{=6VTy2U={2G7oBQM26!+ZjoFK#1#;*0vt@{zY8XO0 zlI)1BUSAQZSUxD@0=b2s_9fe}2Zz6Vnlg&-NXLSJk?(fovnTTUv$;S9c_;5J zd)T_9WxOGx%1K{;g`@**3h3M>??D1R5`G0Ut1k)tj`w@M-bd$ctLvvDbysGkd-JwJ z$^p&muDaYct5B7fjq!BCT7xmTwHPRqB}D_L}Go%1~{ajbbb ziHBtB;AJN^PhmbAI;MzJJi9JytEJ;aVe?-{ceO6d&MJ)oSU*gac`7U%9L5DzxOg6& zB?ATpAO8E1h`ND+H4G|w9;vO)f>2+AwtEeiilhh~SU36)*ZE)^(54IV$ldka{PmV` zAMG_2X8G{qQyv?a=+#y1OnvTB!gT1#!^0moFd+M7Zs~>0tD6!U%P=JJ4Mc6Z6Sg=f zT>}HA9iH{Wek{l)81&+R@zV*bbwri`Uk8dptV^?hGGMDDr=wRJpL70)LW8sA)>T6C z^6n9`iE}`J{&hLGoUr(A2QL2qp17g2^Jt{d4pkPyM@2(kjqUOtXejbXTcdLO7HNsp zsrP~FUrK%&+c!T%kAd61S*Ye8t(bsxl7W#?eaKFoY?b6y5G`b+4q$U-7-X};gt;*o znZsN(7X9xf{HG$0dU!mO4=T&C1q*_6?6L2X0BkfZ8&P#mE4+Ge@X4|egMaTlSPv6G zyE(FvD9FRxgWP^lvx#*^+mp7iu&_^LI0VVZ zvArIBOU1TA0q^<2PCd-4vZa@iC0vPo8Z;J<>^s(~vK$B(WnQEIZ@3i6JCh~ogc*qS z0?r|6$>Wg%ynn|3bNjh4vafB%a(m1WGFC$I0PsjCRv^g+;$mrPSh#!s$PQatDi0Cl zfwLuFD%{9ceH0`NU9`|gj;EP)U@D%Fe`9^5J}dfUG$o~{W=sF$sW1c6|C@ z)sMKS3bW3HUxitYSseB!IdfsAwV{mBN9b1yc*RSVI|CwI13d($zeStcypVDjPMrJO zYya0{Y`$-a*Wl4fRhC9G({>P=-)pI<93zeo%u@dj-e@C`V{0GohW$M1eMh0HC6tF4 zfJw7EV-8NQllyQN)doB)dbwG`Ikz%VD$^=37P_8iDOa*9R9+n1fZk>Q+kDpnOfr2O zyrU_|se0f(pN8tcJ>U!r#VyQ5!Xa#I@~3CHft?~M$mwCMwMW1W`4Z5G2rv3BI|~V# zK@%_>u-qvB%>Sq8HT}0<3@pA1985Hk1N+L*RS{hLU(*Ii3r2P_;Z1-b|3)M)o_}Jp z5DW)E(1DPsf@1qVKmst=cM7QF_M941{w5tb&QDci2M$3{MrKp_6QTA=U174$&i1JB z4+BMz7;D$0O@%U7Ly1D1I3T3BhH&$t(w_uswOFEc#C(L^KjSaG1ss%+5td#jL)W71 z^N$hfhd^HgG%)}2`hTyqXP6LJQ8xx4u`=66_jB{l2e0i<@Ti0EfTnHa6EsS71!1O) zFK>2_z&t2GsCJ9TR^oOr$l?HI7eL%`#$f%0mlY(2{%#T)YLtOjW1r!larY6RMwWOM z`LTc7MI}KKL%csB9ZJIZn!}UJ`&6->l$9^Ocvw zxsSbo)BOU>vGjOYmz~NMN??#G_)$qwfEoO8F@+<$6s$=P6bfO>aA9y3!9}BihxoMh zE!9%=1Qv0C=Mi;=D}99yQ%*FYp#L}Fi@-sQB47wxmhX!V=NDU94LpGIA#kyY%j14f z6tDz#19wSI0Jd(P6zvw@_Aq^Q-L!KSz%D)Tq=JTH@?ak>QUlKBJOR%4m5G8DJp(I9<$f&J1Ap{338O_tFcO**4bzXS%^Pl0sP$aKvT{aFN8$u;;A@fi8Uj zT#Izfk_BvLl0NWm3@_m51edPC2cXdx*2mk=u@^YfdC&$}zA^#}sJLCgZ5+H@hnazQ z5QPGFnn?ru*5Fv%YYFVC^XcoaKM9P>WviC9oJ}(Zo<|29C>P*uSPo28%D`TJ`yXK4 zT=dmem6c)jD`3L5d6U6%kz>UZL6>CU1j!6B;BjLvfgwIDz)3LRxGv~Q(>caKoe#tq znlgHTCl8ziR&5ivGgZvnu4QrIlQD2DC2(nZ6EHwbSU|ygECP5b1+W#t58PL?{yMO5 zxwe+CBJP_4uql>%aGt9`Zey36qsb}YrBA?>1>x(i>}CB5y892fFsKbUGWs~CQ9+7% zJJ6|%Jtmpl1lI7c&ToF(3=AT$Cz_&xK@bQ$G3f-bi3)6HtWE-5O$pp;li;rOKmYx| z$g6FS4Ep~2^yn}22HuWfT|Q~ucUFtLU-R|}&h4^@U~%*mQ%%bh`N(heLSe~{QVtJu zS(gA6%jM3UCBVptp7cKb)P$Fe4=wi>+c2^+INZ9DwRQRTf5HzcY`iw#O!*4DN0wp9 z*$NxE9JATx`{(;``COjjw%D+QGx(^5M#XDymiRblQ>^zeM%_Q`SUkH3;% zz`)?K`ex3zY7;3>nd3R#%YFywP2b;fV)f*P!w(g% zW=-8&-@wVxum;%hN!@?n-iG&Gx5*wpX$*}fg+xJ z%vs+x8?Ht9EuZ{j-~Z+kkn?*!*}Qkn)&-ioF=C3-LWOm&g?K>fOV_==xBhSMEx=u;Adqq`{_fAMsdcZ9mxH*T Lu6{1-oD!M<=RF7Y literal 0 HcmV?d00001 diff --git a/res/sdlogo2.png b/res/sdlogo2.png new file mode 100644 index 0000000000000000000000000000000000000000..fee4fab797fbebd384f7a6de6b0e1766b96e8f9d GIT binary patch literal 59377 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 YC+bHJp3y(8h5t(#8kp!m(X$Qy9}f~1d;kCd literal 0 HcmV?d00001 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0104f56..a45f5b5 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -906,9 +906,11 @@ void MainWindow::setupTransactionsTab() { // Set up context menu on transactions tab auto theme = Settings::getInstance()->get_theme_name(); - if (theme == "dark"){ + if (theme == "dark" || theme == "midnight") { ui->listChat->setStyleSheet("background-image: url(res/sdlogo.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover"); - }else{ui->listChat->setStyleSheet("background-image: url(res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} + } + if (theme == "default") {ui->listChat->setStyleSheet("background-image: url(res/sdlogo2.png) ;background-attachment: fixed ;background-position: center center ;background-repeat: no-repeat;background-size: cover");} + ui->listChat->setResizeMode(QListView::Adjust); ui->listChat->setWordWrap(true); ui->listChat->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); @@ -997,6 +999,7 @@ void MainWindow::setupTransactionsTab() { menu.exec(ui->transactionsTable->viewport()->mapToGlobal(pos)); }); + } void MainWindow::setupchatTab() { From dbbc079432fff1edfa05b954d254728974118dab Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 18:52:29 +0200 Subject: [PATCH 058/253] add new standard avatar --- src/chatmodel.cpp | 39 +++++++++++++++++++++++++++------------ src/contactmodel.cpp | 16 ++++++++++++++-- src/controller.cpp | 42 ++++++++++++++++++++++++++++++------------ 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 68b496a..4f5a7e6 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -1,3 +1,5 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #include "chatmodel.h" #include "settings.h" #include "ui_confirm.h" @@ -395,15 +397,17 @@ Tx MainWindow::createTxForSafeContactRequest() { // QString cid = c.getCid(); // This has to be a new cid for the contact // QString myAddr = c.getMyAddress(); // this should be a new HushChat zaddr // QString addr = c.getPartnerAddress(); // this address will be insert by the user - QString cid = ""; - QString myAddr = ""; - QString addr = ""; - QString type = "Request"; + QString cid = c.getCid(); + QString myAddr = c.getMyAddress(); + QString addr = c.getPartnerAddress(); + QString type = "cont"; + + QString hmemo= createHeaderMemo(type,cid,myAddr); - // tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; qDebug() << "pushback chattx"; } @@ -439,7 +443,7 @@ void MainWindow::safeContactRequest() { // return; // } - /* Tx tx = createTxForSafeContactRequest(); + Tx tx = createTxForSafeContactRequest(); QString error = doSendRequestTxValidations(tx); @@ -455,15 +459,26 @@ void MainWindow::safeContactRequest() { qDebug() << "Tx aborted"; } + // Create a new Dialog to show that we are computing/sending the Tx // Create a new Dialog to show that we are computing/sending the Tx auto d = new QDialog(this); auto connD = new Ui_ConnectionDialog(); connD->setupUi(d); - QPixmap logo(":/img/res/logobig.gif"); - connD->topIcon->setBasePixmap(logo.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + QMovie *movie1 = new QMovie(":/img/res/silentdragonlite-animated.gif");; + QMovie *movie2 = new QMovie(":/img/res/silentdragonlite-animated-dark.gif");; + auto theme = Settings::getInstance()->get_theme_name(); + if (theme == "dark" || theme == "midnight") { + movie2->setScaledSize(QSize(512,512)); + connD->topIcon->setMovie(movie2); + movie2->start(); + } else { + movie1->setScaledSize(QSize(512,512)); + connD->topIcon->setMovie(movie1); + movie1->start(); + } connD->status->setText(tr("Please wait...")); - connD->statusDetail->setText(tr("Your Safe Contact Request will be send")); + connD->statusDetail->setText(tr("Your Contact Request will be send")); d->show(); @@ -501,14 +516,14 @@ void MainWindow::safeContactRequest() { QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); } - );*/ + ); } QString MainWindow::doSendRequestTxValidations(Tx tx) { // Check to see if we have enough verified funds to send the Tx. - /* CAmount total; + CAmount total; for (auto toAddr : tx.toAddrs) { if (!Settings::isValidAddress(toAddr.addr)) { QString addr = (toAddr.addr.length() > 100 ? toAddr.addr.left(100) + "..." : toAddr.addr); @@ -532,5 +547,5 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { .arg(available.toDecimalhushString(), total.toDecimalhushString()); } - return "";*/ + return ""; } diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index a19fe1c..1a677e1 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -10,14 +10,26 @@ void ContactModel::renderContactList(QListView* view) { //QStandardItem* Items = new QStandardItem(); - QStandardItem* Items1 = new QStandardItem(QIcon("res/darkwing.png"),c.getName()); - // contact->appendRow(Items); + auto theme = Settings::getInstance()->get_theme_name(); + if ((theme == "dark" || theme == "midnight")) { + QStandardItem* Items1 = new QStandardItem(QIcon("res/sdlogo.png"),c.getName()); + contact->appendRow(Items1); + view->setModel(contact); + view->setIconSize(QSize(80,100)); + view->setUniformItemSizes(true); + view->setDragDropMode(QAbstractItemView::DropOnly);; + } + if (theme == "default" || theme == "blue"){ + + QStandardItem* Items1 = new QStandardItem(QIcon("res/sdlogo2.png"),c.getName()); contact->appendRow(Items1); view->setModel(contact); view->setIconSize(QSize(80,100)); view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly);; + } + } diff --git a/src/controller.cpp b/src/controller.cpp index 577d438..81676e6 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -954,22 +954,43 @@ void Controller::refreshTransactions() { }; txdata.push_back(tx); - - QString cid = ""; + + QString type; + QString cid; if (memo.startsWith("{")) { + + type = memo.mid(75,4); cid = memo.mid(14,36); + + qDebug()<addCid(txid, cid); - }else{ - if(chatModel->getCidByTx(txid) != QString("0xdeadbeef")) + + } + if (type == "cont") + + { + + qDebug()<< "Als Request erkannt"; + + + } + + + if (chatModel->getCidByTx(txid) != QString("0xdeadbeef")){ + cid = chatModel->getCidByTx(txid); - else - cid = ""; } - + + + else{ + + cid = ""; + } + QString contact; for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - // for (auto &p : this->chatItems) { if (address == c.getMyAddress()){ @@ -977,7 +998,7 @@ void Controller::refreshTransactions() { qDebug()<< "Addressbuch Addresse: " << c.getMyAddress(); qDebug()<< "Addresse: " << address; - }else{ contact = "ELSE";} + }else{ contact = "";} ChatItem item = ChatItem( datetime, @@ -988,9 +1009,6 @@ void Controller::refreshTransactions() { txid, false ); - // qDebug()<< "KontaktName: " << contact; - - // qDebug()<< "Addressbuch Addresse: " << c.getMyAddress(); chatModel->addMessage(item); } From d3d19cab9e62c25436c753dcc973444b47b1fbee Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 19:44:50 +0200 Subject: [PATCH 059/253] switch sides of conversation --- src/contactrequest.ui | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/contactrequest.ui diff --git a/src/contactrequest.ui b/src/contactrequest.ui new file mode 100644 index 0000000..fb923db --- /dev/null +++ b/src/contactrequest.ui @@ -0,0 +1,72 @@ + + + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + + From 4da6eddae2ba504eb59eafb2a276ebb6c535f44a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 19:45:49 +0200 Subject: [PATCH 060/253] switch sides of conversation --- src/chatmodel.cpp | 14 ++++++++++++-- src/contactmodel.cpp | 4 ++-- src/contactmodel.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index 4f5a7e6..de38e97 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -8,6 +8,7 @@ #include "ui_mainwindow.h" #include "addressbook.h" #include "ui_memodialog.h" +#include "ui_contactrequest.h" #include "addressbook.h" #include #include @@ -122,7 +123,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { QStandardItem* Items = new QStandardItem(c.second.toChatLine()); - Items->setData("Incoming", Qt::UserRole +1); + Items->setData("Outgoing", Qt::UserRole +1); chat->appendRow(Items); ui->listChat->setModel(chat); @@ -141,7 +142,7 @@ void ChatModel::renderChatBox(Ui::MainWindow* ui, QListView *view) { QStandardItem* Items1 = new QStandardItem(c.second.toChatLine()); - Items1->setData("Outgoing", Qt::UserRole +1); + Items1->setData("Incoming", Qt::UserRole +1); chat->appendRow(Items1); } @@ -423,6 +424,15 @@ Tx MainWindow::createTxForSafeContactRequest() { //////////////////De-activated for now/////////////////// void MainWindow::safeContactRequest() { + + // Ui_ContactRequest contactRequest; + // QDialog dialog(this); + // contactRequest.setupUi(&dialog); + // Settings::saveRestore(&dialog); + + // memoDialog.memoTxt->setLenDisplayLabel(memoDialog.memoSize); + // memoDialog.memoTxt->setAcceptButton(memoDialog.buttonBox->button(QDialogButtonBox::Ok)); + ////////////////////////////Todo: Check if its a zaddr////////// // Create a Tx from the values on the send tab. Note that this Tx object diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index 1a677e1..956bd63 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -15,7 +15,7 @@ void ContactModel::renderContactList(QListView* view) QStandardItem* Items1 = new QStandardItem(QIcon("res/sdlogo.png"),c.getName()); contact->appendRow(Items1); view->setModel(contact); - view->setIconSize(QSize(80,100)); + view->setIconSize(QSize(60,70)); view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly);; } @@ -24,7 +24,7 @@ void ContactModel::renderContactList(QListView* view) QStandardItem* Items1 = new QStandardItem(QIcon("res/sdlogo2.png"),c.getName()); contact->appendRow(Items1); view->setModel(contact); - view->setIconSize(QSize(80,100)); + view->setIconSize(QSize(60,70)); view->setUniformItemSizes(true); view->setDragDropMode(QAbstractItemView::DropOnly);; diff --git a/src/contactmodel.h b/src/contactmodel.h index b97cc8a..2bf3fe3 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -1,3 +1,5 @@ +// Copyright 2019-2020 The Hush developers +// GPLv3 #ifndef CONTACTMODEL_H #define CONTACTMODEL_H From bcbee161eb277d4c5f4cef532a34ae186d4c41b2 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sun, 3 May 2020 23:37:02 +0200 Subject: [PATCH 061/253] activate contact request hm, for testing --- src/chatmodel.cpp | 111 ++++++++++++++++------------ src/contactrequest.ui | 167 ++++++++++++++++++++++++++++++++---------- src/mainwindow.cpp | 5 +- src/mainwindow.h | 3 +- 4 files changed, 201 insertions(+), 85 deletions(-) diff --git a/src/chatmodel.cpp b/src/chatmodel.cpp index de38e97..550081c 100644 --- a/src/chatmodel.cpp +++ b/src/chatmodel.cpp @@ -377,12 +377,28 @@ QString MainWindow::doSendChatTxValidations(Tx tx) { return ""; } -// Create a Contact Request. + +// Create a Tx from the current state of the Chat page. Tx MainWindow::createTxForSafeContactRequest() { - Tx tx; - CAmount totalAmt; - { + + Ui_Dialog request; + QDialog dialog(this); + request.setupUi(&dialog); + Settings::saveRestore(&dialog); +dialog.exec(); + + Tx tx; + QObject::connect(request.cancel, &QPushButton::clicked, [&] () { + + dialog.close(); + }); + + + QObject::connect(request.sendRequestButton, &QPushButton::clicked, this, &MainWindow::ContactRequest); + // For each addr/amt in the Chat tab + { + CAmount totalAmt; QString amtStr = "0"; CAmount amt; @@ -392,48 +408,46 @@ Tx MainWindow::createTxForSafeContactRequest() { for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) + if (request.zaddr->text().trimmed() != c.getPartnerAddress()) { - if (ui->contactNameMemo->text().trimmed() == c.getName()) { - - // QString cid = c.getCid(); // This has to be a new cid for the contact - // QString myAddr = c.getMyAddress(); // this should be a new HushChat zaddr - // QString addr = c.getPartnerAddress(); // this address will be insert by the user - QString cid = c.getCid(); - QString myAddr = c.getMyAddress(); - QString addr = c.getPartnerAddress(); - QString type = "cont"; - - + QString cid = c.getCid(); + QString myAddr = c.getMyAddress(); + QString type = "cont"; + QString addr = request.zaddr->text(); + + - QString hmemo= createHeaderMemo(type,cid,myAddr); - - tx.toAddrs.push_back(ToFields{addr, amt, hmemo}) ; + QString hmemo= createHeaderMemo(type,cid,myAddr,0,0); + QString memo = request.requestmemo->toPlainText().trimmed(); - qDebug() << "pushback chattx"; - } -} + + tx.toAddrs.push_back(ToFields{addr, amt, hmemo}); + tx.toAddrs.push_back(ToFields{addr, amt, memo}); - - tx.fee = Settings::getMinerFee(); + qDebug() << "pushback chattx"; + tx.fee = Settings::getMinerFee(); return tx; qDebug() << "ChatTx created"; + } if (request.zaddr->text().trimmed().isEmpty() == false){ + + QMessageBox msg(QMessageBox::Critical, tr("Please insert a contact Address"), request.zaddr->text(), + QMessageBox::Ok, this); + + msg.exec(); + + } + + } + } -//////////////////De-activated for now/////////////////// -void MainWindow::safeContactRequest() { +void MainWindow::ContactRequest() { - // Ui_ContactRequest contactRequest; - // QDialog dialog(this); - // contactRequest.setupUi(&dialog); - // Settings::saveRestore(&dialog); - // memoDialog.memoTxt->setLenDisplayLabel(memoDialog.memoSize); - // memoDialog.memoTxt->setAcceptButton(memoDialog.buttonBox->button(QDialogButtonBox::Ok)); - - ////////////////////////////Todo: Check if its a zaddr////////// + ////////////////////////////Todo: Check if a Contact is selected////////// // Create a Tx from the values on the send tab. Note that this Tx object // might not be valid yet. @@ -441,21 +455,24 @@ void MainWindow::safeContactRequest() { // Memos can only be used with zAddrs. So check that first // for(auto &c : AddressBook::getInstance()->getAllAddressLabels()) - // if (ui->ContactZaddr->text().trimmed() == c.getName()) { + // if (ui->contactNameMemo->text().trimmed().isEmpty() || ui->memoTxtChat->toPlainText().trimmed().isEmpty()) { // auto addr = ""; // if (! Settings::isZAddress(AddressBook::addressFromAddressLabel(addr->text()))) { - // QMessageBox msg(QMessageBox::Critical, tr("Contact requests can only be used with z-addresses"), - // tr("The memo field can only be used with a z-address.\n") + addr->text() + tr("\ndoesn't look like a z-address"), - // QMessageBox::Ok, this); + // QMessageBox msg(QMessageBox::Critical, tr("You have to select a contact and insert a Memo"), + // tr("You have selected no Contact from Contactlist,\n") + tr("\nor your Memo is empty"), + // QMessageBox::Ok, this); - // msg.exec(); - // return; + // msg.exec(); + // return; // } - Tx tx = createTxForSafeContactRequest(); + +//}; - QString error = doSendRequestTxValidations(tx); + Tx tx = createTxForSafeContactRequest(); + + QString error = doSendChatTxValidations(tx); if (!error.isEmpty()) { // Something went wrong, so show an error and exit @@ -469,7 +486,6 @@ void MainWindow::safeContactRequest() { qDebug() << "Tx aborted"; } - // Create a new Dialog to show that we are computing/sending the Tx // Create a new Dialog to show that we are computing/sending the Tx auto d = new QDialog(this); auto connD = new Ui_ConnectionDialog(); @@ -488,9 +504,10 @@ void MainWindow::safeContactRequest() { } connD->status->setText(tr("Please wait...")); - connD->statusDetail->setText(tr("Your Contact Request will be send")); + connD->statusDetail->setText(tr("Your Message will be send")); d->show(); + ui->memoTxtChat->clear(); // And send the Tx rpc->executeTransaction(tx, @@ -509,7 +526,8 @@ void MainWindow::safeContactRequest() { }); // Force a UI update so we get the unconfirmed Tx - rpc->refresh(true); + // rpc->refresh(true); + ui->memoTxtChat->clear(); }, // Errored out @@ -527,7 +545,8 @@ void MainWindow::safeContactRequest() { QMessageBox::critical(this, QObject::tr("Transaction Error"), errStr, QMessageBox::Ok); } ); - } + + } QString MainWindow::doSendRequestTxValidations(Tx tx) { @@ -558,4 +577,4 @@ QString MainWindow::doSendRequestTxValidations(Tx tx) { } return ""; -} +} \ No newline at end of file diff --git a/src/contactrequest.ui b/src/contactrequest.ui index fb923db..1bd758f 100644 --- a/src/contactrequest.ui +++ b/src/contactrequest.ui @@ -1,72 +1,165 @@ - - - - + + Dialog - - + + 0 0 - 400 - 300 + 780 + 416 - + Dialog - - + + - 30 - 240 - 341 - 32 + 0 + 100 + 351 + 17 - - Qt::Horizontal + + <html><head/><body><p>Please insert the Address of your contact :</p></body></html> - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + 10 + 190 + 461 + 17 + + + + <html><head/><body><p>Insert a Message, and ask your friend for the contact request : </p><p><br/></p></body></html> + + + + + + 0 + 240 + 591 + 101 + + + + + + + 0 + 140 + 591 + 25 + + + + + + + 490 + 360 + 114 + 25 + + + + + 100 + 0 + + + + Send + + + false + + + + + + 320 + 360 + 114 + 25 + + + + + 100 + 0 + + + + Cancel + + + false + + + + + + 0 + 10 + 351 + 17 + + + + <html><head/><body><p>Please insert a Nickname for your contact :</p></body></html> + + + + + + 0 + 50 + 591 + 25 + - - buttonBox - accepted() + sendRequestButton + clicked() Dialog accept() - - 248 - 254 + + 536 + 262 - - 157 - 274 + + 389 + 207 - buttonBox - rejected() + cancel + clicked() Dialog reject() - - 316 - 260 + + 396 + 262 - - 286 - 274 + + 389 + 207 - diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a45f5b5..d685005 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -14,6 +14,7 @@ #include "settings.h" #include "version.h" #include "connection.h" +#include "ui_contactrequest.h" #include "requestdialog.h" #include "websockets.h" #include @@ -1006,7 +1007,8 @@ void MainWindow::setupchatTab() { // Send button QObject::connect(ui->sendChatButton, &QPushButton::clicked, this, &MainWindow::sendChatButton); - QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::safeContactRequest); + QObject::connect(ui->safeContactRequest, &QPushButton::clicked, this, &MainWindow::ContactRequest); + ///////// Set selected Zaddr for Chat with Doubleklick @@ -1032,6 +1034,7 @@ void MainWindow::setupchatTab() { } + ChatMemoEdit::ChatMemoEdit(QWidget* parent) : QPlainTextEdit(parent) { QObject::connect(this, &QPlainTextEdit::textChanged, this, &ChatMemoEdit::updateDisplay); } diff --git a/src/mainwindow.h b/src/mainwindow.h index 1110f67..c767128 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -108,13 +108,14 @@ private: Tx createTxFromChatPage(); Tx createTxForSafeContactRequest(); + void encryptWallet(); void removeWalletEncryption(); void cancelButton(); void sendButton(); void sendChatButton(); - void safeContactRequest(); + void ContactRequest(); void addAddressSection(); void maxAmountChecked(int checked); From 30a5403833fc8548979abd30db25c3156df5fb75 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 4 May 2020 11:15:05 +0200 Subject: [PATCH 062/253] Add ComboBox for avatar --- application.qrc | 11 ++++ res/Berg.png | Bin 0 -> 70184 bytes res/Unbenannt-4 Kopie.png | Bin 0 -> 88464 bytes res/denio.png | Bin 0 -> 66558 bytes res/duke.png | Bin 0 -> 76820 bytes res/garfield.png | Bin 0 -> 108906 bytes res/hirsch.png | Bin 0 -> 142903 bytes res/mickey.png | Bin 0 -> 58807 bytes res/pinguin.png | Bin 0 -> 53787 bytes res/popey.png | Bin 0 -> 39428 bytes res/sharpee.png | Bin 0 -> 6006 bytes res/snoopy.png | Bin 0 -> 46143 bytes res/yoda.png | Bin 0 -> 84114 bytes silentdragon-lite.pro | 3 + src/addressbook.cpp | 45 +++++++------- src/addressbook.h | 6 +- src/addressbook.ui | 123 +++++++++++++++++++++++++++++++++++++- src/contactmodel.cpp | 31 ++++------ src/contactmodel.h | 15 ++++- src/mainwindow.cpp | 5 +- 20 files changed, 193 insertions(+), 46 deletions(-) create mode 100644 res/Berg.png create mode 100644 res/Unbenannt-4 Kopie.png create mode 100644 res/denio.png create mode 100644 res/duke.png create mode 100644 res/garfield.png create mode 100644 res/hirsch.png create mode 100644 res/mickey.png create mode 100644 res/pinguin.png create mode 100644 res/popey.png create mode 100644 res/sharpee.png create mode 100644 res/snoopy.png create mode 100644 res/yoda.png diff --git a/application.qrc b/application.qrc index e4cd3d2..42f093b 100644 --- a/application.qrc +++ b/application.qrc @@ -11,6 +11,17 @@ res/darkwing.png res/sdlogo.png res/sdlogo2.png + res/Berg.png + res/denio.png + res/duke.png + res/sharpee.png + res/yoda.png + res/mickey.png + res/snoopy.png + res/popey.png + res/garfield.png + res/pinguin.png + res/hirsch.png res/hushdlogo.gif diff --git a/res/Berg.png b/res/Berg.png new file mode 100644 index 0000000000000000000000000000000000000000..0aab208cc2a65527640ab6c8036876ef8fb8a8ce GIT binary patch literal 70184 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 literal 0 HcmV?d00001 diff --git a/res/Unbenannt-4 Kopie.png b/res/Unbenannt-4 Kopie.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d0d54e65200d11b447666bfe67509719442df2 GIT binary patch literal 88464 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%0ALx8KyW@??b$Thi56L| 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 literal 0 HcmV?d00001 diff --git a/res/duke.png b/res/duke.png new file mode 100644 index 0000000000000000000000000000000000000000..4310cef9311ff8c22006d34fa49880094681b561 GIT binary patch literal 76820 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