From a59eab65c9c1ea529010b353de27da6fb5cde546 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 1 Aug 2015 13:49:58 +0100 Subject: [PATCH 1/5] Plugin infrastructure. Initial separation of accounts into plugin. --- alethzero/AllAccounts.cpp | 115 ++++++++++++++++++++++++++++++++ alethzero/AllAccounts.h | 56 ++++++++++++++++ alethzero/AllAccounts.ui | 134 ++++++++++++++++++++++++++++++++++++++ alethzero/CMakeLists.txt | 5 +- alethzero/Main.ui | 92 -------------------------- alethzero/MainFace.cpp | 60 +++++++++++++++++ alethzero/MainFace.h | 86 ++++++++++++++++++++++++ alethzero/MainWin.cpp | 78 +++------------------- alethzero/MainWin.h | 11 ++-- 9 files changed, 468 insertions(+), 169 deletions(-) create mode 100644 alethzero/AllAccounts.cpp create mode 100644 alethzero/AllAccounts.h create mode 100644 alethzero/AllAccounts.ui create mode 100644 alethzero/MainFace.cpp create mode 100644 alethzero/MainFace.h diff --git a/alethzero/AllAccounts.cpp b/alethzero/AllAccounts.cpp new file mode 100644 index 000000000..3e2d5234a --- /dev/null +++ b/alethzero/AllAccounts.cpp @@ -0,0 +1,115 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file AllAccounts.h + * @author Gav Wood + * @date 2015 + */ + +#include "AllAccounts.h" +#include +#include +#include +#include +#include +#include "ui_AllAccounts.h" +using namespace std; +using namespace dev; +using namespace az; +using namespace eth; + +AllAccounts::AllAccounts(MainFace* _m): + Plugin(_m, "AllAccounts"), + m_ui(new Ui::AllAccounts) +{ + m_ui->setupUi(dock()); + + refresh(); +} + +AllAccounts::~AllAccounts() +{ + +} + +// TODO: Introduce interface for MainWin's refreshAccounts() and have it call refresh(). + +void AllAccounts::refresh() +{ + DEV_TIMED_FUNCTION; +#if ETH_FATDB || !ETH_TRUE + cwatch << "refreshAccounts()"; + m_ui->accounts->clear(); + bool showContract = m_ui->showContracts->isChecked(); + bool showBasic = m_ui->showBasic->isChecked(); + bool onlyNamed = m_ui->onlyNamed->isChecked(); + for (auto const& i: ethereum()->addresses()) + { + bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); + if (!((showContract && isContract) || (showBasic && !isContract))) + continue; + string r = render(i); + if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE")) + continue; + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ui->accounts)) + ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); + } +#endif + m_refreshAccounts->setEnabled(false); +} + +void AllAccounts::on_accounts_currentItemChanged() +{ + m_ui->accountInfo->clear(); + if (auto item = m_ui->accounts->currentItem()) + { + auto hba = item->data(Qt::UserRole).toByteArray(); + assert(hba.size() == 20); + auto address = h160((byte const*)hba.data(), h160::ConstructFromPointer); + + stringstream s; + try + { + auto storage = ethereum()->storageAt(address); + for (auto const& i: storage) + s << "@" << showbase << hex << main()->prettyU256(i.first) << "    " << showbase << hex << main()->prettyU256(i.second) << "
"; + s << "

Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")

" << disassemble(ethereum()->codeAt(address)); + s << ETH_HTML_DIV(ETH_HTML_MONO) << toHex(ethereum()->codeAt(address)) << ""; + m_ui->accountInfo->appendHtml(QString::fromStdString(s.str())); + } + catch (dev::InvalidTrie) + { + m_ui->accountInfo->appendHtml("Corrupted trie."); + } + ui->accountInfo->moveCursor(QTextCursor::Start); + } +} + +void AllAccounts::on_accounts_doubleClicked() +{ + if (ui->accounts->count()) + { + auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); + auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); + qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); + } +} + +void AllAccounts::on_refreshAccounts_clicked() +{ + refreshAccounts(); +} + diff --git a/alethzero/AllAccounts.h b/alethzero/AllAccounts.h new file mode 100644 index 000000000..910c19344 --- /dev/null +++ b/alethzero/AllAccounts.h @@ -0,0 +1,56 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file AllAccounts.h + * @author Gav Wood + * @date 2015 + */ + +#pragma once + +#include +#include +#include "MainFace.h" + +namespace Ui { +class AllAccounts; +} + +namespace dev +{ +namespace az +{ + +class AllAccounts: public Plugin +{ +public: + AllAccounts(MainFace* _m): Plugin(_m, "AllAccounts") {} + ~AllAccounts(); + + void refresh(); + +public slots: + void on_accounts_currentItemChanged(); + void on_accounts_doubleClicked(); + void on_refreshAccounts_clicked(); + +private: + Ui::AllAccounts* m_ui; + QAction* m_refreshAccounts; +}; + +} +} diff --git a/alethzero/AllAccounts.ui b/alethzero/AllAccounts.ui new file mode 100644 index 000000000..ca0ad31bc --- /dev/null +++ b/alethzero/AllAccounts.ui @@ -0,0 +1,134 @@ + + + AllAccounts + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Filter... + + + + + + + Basic + + + true + + + + + + + Contracts + + + true + + + true + + + + + + + Only Named + + + true + + + false + + + + + + + Refresh + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 0 + 0 + + + + Qt::NoFocus + + + QFrame::NoFrame + + + + + + 2 + 0 + + + + Qt::WheelFocus + + + QFrame::NoFrame + + + true + + + + + + + + + diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 1b1138eab..75576ecc1 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -31,6 +31,9 @@ qt5_wrap_ui(ui_ExportState.h ExportState.ui) qt5_wrap_ui(ui_GetPassword.h GetPassword.ui) qt5_wrap_ui(ui_GasPricing.h GasPricing.ui) +# Extensions +qt5_wrap_ui(ui_AllAccounts.h AllAccounts.ui) + file(GLOB HEADERS "*.h") if (APPLE) @@ -42,7 +45,7 @@ endif () # eth_add_executable is defined in cmake/EthExecutableHelper.cmake eth_add_executable(${EXECUTABLE} ICON alethzero - UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui GetPassword.ui GasPricing.ui + UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui GetPassword.ui GasPricing.ui AllAccounts.ui WIN_RESOURCES alethzero.rc ) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index b1a93aaab..800c74d56 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -615,98 +615,6 @@ 0 - - - - - - Filter... - - - - - - - Basic - - - true - - - - - - - Contracts - - - true - - - true - - - - - - - Only Named - - - true - - - false - - - - - - - Refresh - - - - - - - - - Qt::Horizontal - - - - - 0 - 0 - - - - Qt::NoFocus - - - QFrame::NoFrame - - - - - - 2 - 0 - - - - Qt::WheelFocus - - - QFrame::NoFrame - - - true - - - - diff --git a/alethzero/MainFace.cpp b/alethzero/MainFace.cpp new file mode 100644 index 000000000..a7ca1f1c7 --- /dev/null +++ b/alethzero/MainFace.cpp @@ -0,0 +1,60 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MainFace.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "MainFace.h" + +using namespace dev; +using namespace az; + +Plugin::Plugin(MainFace* _f, std::string const& _name): + m_main(_f), + m_name(_name) +{ + _f->adoptPlugin(this); +} + + +QDockWidget* Plugin::dock(Qt::DockWidgetArea _area, QString _title) +{ + if (_title.isEmpty()) + _title = QString::fromStdString(m_name); + if (!m_dock) + { + m_dock = new QDockWidget(_title, m_main); + m_main->addDockWidget(_area, m_dock); + } + return m_dock; +} + +void Plugin::addToDock(Qt::DockWidgetArea _area, QDockWidget* _dockwidget, Qt::Orientation _orientation) +{ + m_main->addDockWidget(_area, m_dock, _orientation); +} + +void Plugin::addAction(QAction* _a) +{ + m_main->addAction(_a); +} + +void MainFace::killPlugins() +{ + m_plugins.clear(); +} diff --git a/alethzero/MainFace.h b/alethzero/MainFace.h new file mode 100644 index 000000000..48ba25901 --- /dev/null +++ b/alethzero/MainFace.h @@ -0,0 +1,86 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file MainFace.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "Context.h" + +namespace dev +{ + +namespace web3 { class WebThreeDirect; } +namespace eth { class Client; } +namespace shh { class WhisperHost; } + +namespace az +{ + +class Plugin; + +class MainFace: public QMainWindow, public Context +{ +public: + explicit MainFace(QWidget* _parent = nullptr): QMainWindow(_parent) {} + + void adoptPlugin(Plugin* _p) { m_plugins.insert(_p->name(), std::shared_ptr(_p)); } + void killPlugins(); + + // TODO: tidy - all should be references that throw if module unavailable. + // TODO: provide a set of available web3 modules. + virtual dev::web3::WebThreeDirect* web3() const = 0; + virtual dev::eth::Client* ethereum() const = 0; + virtual std::shared_ptr whisper() const = 0; + +private: + std::unordered_map> m_plugins; +}; + +class Plugin +{ +public: + Plugin(MainFace* _f, std::string const& _name); + virtual ~Plugin() {} + + std::string const& name() const { return m_name; } + + dev::web3::WebThreeDirect* web3() const { return m_main->web3(); } + dev::eth::Client* ethereum() const { return m_main->ethereum(); } + std::shared_ptr whisper() const { return m_main->whisper(); } + MainFace* main() { return m_main; } + QDockWidget* dock(Qt::DockWidgetArea _area = Qt::RightDockWidgetArea, QString _title = QString()); + void addToDock(Qt::DockWidgetArea _area, QDockWidget* _dockwidget, Qt::Orientation _orientation); + void addAction(QAction* _a); + +private: + MainFace* m_main; + std::string m_name; + QDockWidget* m_dock; +}; + +} + +} diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f7f0f0fa5..863190d9d 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -74,13 +74,15 @@ #include "DappHost.h" #include "WebPage.h" #include "ExportState.h" +#include "AllAccounts.h" #include "ui_Main.h" #include "ui_GetPassword.h" #include "ui_GasPricing.h" using namespace std; using namespace dev; -using namespace dev::p2p; -using namespace dev::eth; +using namespace az; +using namespace p2p; +using namespace eth; namespace js = json_spirit; string Main::fromRaw(h256 _n, unsigned* _inc) @@ -126,8 +128,8 @@ static QString filterOutTerminal(QString _s) return _s.replace(QRegExp("\x1b\\[(\\d;)?\\d+m"), ""); } -Main::Main(QWidget *parent) : - QMainWindow(parent), +Main::Main(QWidget* _parent): + MainFace(_parent), ui(new Ui::Main), m_transact(nullptr), m_dappLoader(nullptr), @@ -302,6 +304,8 @@ Main::Main(QWidget *parent) : s.setValue("splashMessage", false); } } + + new dev::az::AllAccounts(this); } Main::~Main() @@ -1283,35 +1287,6 @@ void Main::on_onlyNamed_toggled() ui->refreshAccounts->setEnabled(true); } -void Main::on_refreshAccounts_clicked() -{ - refreshAccounts(); -} - -void Main::refreshAccounts() -{ - DEV_TIMED_FUNCTION; -#if ETH_FATDB || !ETH_TRUE - cwatch << "refreshAccounts()"; - ui->accounts->clear(); - bool showContract = ui->showContracts->isChecked(); - bool showBasic = ui->showBasic->isChecked(); - bool onlyNamed = ui->onlyNamed->isChecked(); - for (auto const& i: ethereum()->addresses()) - { - bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); - if (!((showContract && isContract) || (showBasic && !isContract))) - continue; - string r = render(i); - if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE")) - continue; - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ui->accounts)) - ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); - } -#endif - ui->refreshAccounts->setEnabled(false); -} - void Main::refreshBlockCount() { auto d = ethereum()->blockChain().details(); @@ -1919,33 +1894,6 @@ void Main::debugDumpState(int _add) } } -void Main::on_accounts_currentItemChanged() -{ - ui->accountInfo->clear(); - if (auto item = ui->accounts->currentItem()) - { - auto hba = item->data(Qt::UserRole).toByteArray(); - assert(hba.size() == 20); - auto address = h160((byte const*)hba.data(), h160::ConstructFromPointer); - - stringstream s; - try - { - auto storage = ethereum()->storageAt(address); - for (auto const& i: storage) - s << "@" << showbase << hex << prettyU256(i.first) << "    " << showbase << hex << prettyU256(i.second) << "
"; - s << "

Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")

" << disassemble(ethereum()->codeAt(address)); - s << ETH_HTML_DIV(ETH_HTML_MONO) << toHex(ethereum()->codeAt(address)) << ""; - ui->accountInfo->appendHtml(QString::fromStdString(s.str())); - } - catch (dev::InvalidTrie) - { - ui->accountInfo->appendHtml("Corrupted trie."); - } - ui->accountInfo->moveCursor(QTextCursor::Start); - } -} - void Main::on_idealPeers_valueChanged(int) { m_webThree->setIdealPeerCount(ui->idealPeers->value()); @@ -1964,16 +1912,6 @@ void Main::on_ourAccounts_doubleClicked() m_logHistory.clear(); }*/ -void Main::on_accounts_doubleClicked() -{ - if (ui->accounts->count()) - { - auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); - auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); - qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); - } -} - static shh::Topics topicFromText(QString _s) { shh::BuildTopic ret; diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 307cc1533..4e13ad208 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -42,6 +42,7 @@ #include "Transact.h" #include "NatspecHandler.h" #include "Connect.h" +#include "MainFace.h" class QListWidgetItem; class QActionGroup; @@ -69,7 +70,7 @@ using WatchHandler = std::function; QString contentsOfQResource(std::string const& res); -class Main: public QMainWindow, public Context +class Main: public dev::az::MainFace { Q_OBJECT @@ -77,9 +78,9 @@ public: explicit Main(QWidget *parent = 0); ~Main(); - dev::WebThreeDirect* web3() const { return m_webThree.get(); } - dev::eth::Client* ethereum() const { return m_webThree->ethereum(); } - std::shared_ptr whisper() const { return m_webThree->whisper(); } + dev::WebThreeDirect* web3() const override { return m_webThree.get(); } + dev::eth::Client* ethereum() const override { return m_webThree->ethereum(); } + std::shared_ptr whisper() const override { return m_webThree->whisper(); } bool confirm() const; NatSpecFace* natSpec() { return &m_natSpecDB; } @@ -159,8 +160,6 @@ private slots: // Stuff concerning the blocks/transactions/accounts panels void on_ourAccounts_itemClicked(QListWidgetItem* _i); void on_ourAccounts_doubleClicked(); - void on_accounts_doubleClicked(); - void on_accounts_currentItemChanged(); void on_transactionQueue_currentItemChanged(); void on_blockChainFilter_textChanged(); void on_blocks_currentItemChanged(); From 602cc0458dd88f5f862274161fa305d6a393ce1e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 2 Aug 2015 13:38:01 +0100 Subject: [PATCH 2/5] Initial draft of AllAccounts plugin. --- alethzero/AllAccounts.cpp | 19 +++++++++++-------- alethzero/AllAccounts.h | 16 ++++++++++++---- alethzero/MainFace.cpp | 6 ++++++ alethzero/MainFace.h | 4 ++++ alethzero/MainWin.cpp | 24 +----------------------- alethzero/MainWin.h | 7 ------- 6 files changed, 34 insertions(+), 42 deletions(-) diff --git a/alethzero/AllAccounts.cpp b/alethzero/AllAccounts.cpp index 3e2d5234a..d93cd1322 100644 --- a/alethzero/AllAccounts.cpp +++ b/alethzero/AllAccounts.cpp @@ -36,16 +36,19 @@ AllAccounts::AllAccounts(MainFace* _m): m_ui(new Ui::AllAccounts) { m_ui->setupUi(dock()); - + installWatches(); refresh(); } AllAccounts::~AllAccounts() { - } -// TODO: Introduce interface for MainWin's refreshAccounts() and have it call refresh(). +void AllAccounts::installWatches() +{ + installWatch(ChainChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); + installWatch(PendingChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); +} void AllAccounts::refresh() { @@ -71,6 +74,11 @@ void AllAccounts::refresh() m_refreshAccounts->setEnabled(false); } +void AllAccounts::onAllChange() +{ + ui->refreshAccounts->setEnabled(true); +} + void AllAccounts::on_accounts_currentItemChanged() { m_ui->accountInfo->clear(); @@ -108,8 +116,3 @@ void AllAccounts::on_accounts_doubleClicked() } } -void AllAccounts::on_refreshAccounts_clicked() -{ - refreshAccounts(); -} - diff --git a/alethzero/AllAccounts.h b/alethzero/AllAccounts.h index 910c19344..e9ded1999 100644 --- a/alethzero/AllAccounts.h +++ b/alethzero/AllAccounts.h @@ -40,14 +40,22 @@ public: AllAccounts(MainFace* _m): Plugin(_m, "AllAccounts") {} ~AllAccounts(); - void refresh(); - -public slots: +private slots: void on_accounts_currentItemChanged(); void on_accounts_doubleClicked(); - void on_refreshAccounts_clicked(); + void on_refreshAccounts_clicked() { refresh(); } + + void on_accountsFilter_textChanged() { onAllChange(); } + void on_showBasic_toggled() { onAllChange(); } + void on_showContracts_toggled() { onAllChange(); } + void on_onlyNamed_toggled() { onAllChange(); } private: + void onAllChange(); + + void installWatches(); + void refresh(); + Ui::AllAccounts* m_ui; QAction* m_refreshAccounts; }; diff --git a/alethzero/MainFace.cpp b/alethzero/MainFace.cpp index a7ca1f1c7..97a615008 100644 --- a/alethzero/MainFace.cpp +++ b/alethzero/MainFace.cpp @@ -58,3 +58,9 @@ void MainFace::killPlugins() { m_plugins.clear(); } + +void MainFace::allChange() +{ + for (auto const& p: m_plugins) + p.second->onAllChange(); +} diff --git a/alethzero/MainFace.h b/alethzero/MainFace.h index 48ba25901..2104ea05b 100644 --- a/alethzero/MainFace.h +++ b/alethzero/MainFace.h @@ -49,6 +49,8 @@ public: void adoptPlugin(Plugin* _p) { m_plugins.insert(_p->name(), std::shared_ptr(_p)); } void killPlugins(); + void allChange(); + // TODO: tidy - all should be references that throw if module unavailable. // TODO: provide a set of available web3 modules. virtual dev::web3::WebThreeDirect* web3() const = 0; @@ -75,6 +77,8 @@ public: void addToDock(Qt::DockWidgetArea _area, QDockWidget* _dockwidget, Qt::Orientation _orientation); void addAction(QAction* _a); + virtual void onAllChange() {} + private: MainFace* m_main; std::string m_name; diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 863190d9d..72271bcef 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -526,7 +526,6 @@ void Main::onNewBlock() // update blockchain dependent views. refreshBlockCount(); refreshBlockChain(); - ui->refreshAccounts->setEnabled(true); // We must update balances since we can't filter updates to basic accounts. refreshBalances(); @@ -538,7 +537,6 @@ void Main::onNewPending() // update any pending-transaction dependent views. refreshPending(); - ui->refreshAccounts->setEnabled(true); } void Main::on_forceMining_triggered() @@ -1241,8 +1239,8 @@ void Main::refreshAll() refreshBlockChain(); refreshBlockCount(); refreshPending(); - ui->refreshAccounts->setEnabled(true); refreshBalances(); + allChange(); } void Main::refreshPending() @@ -1267,26 +1265,6 @@ void Main::refreshPending() } } -void Main::on_accountsFilter_textChanged() -{ - ui->refreshAccounts->setEnabled(true); -} - -void Main::on_showBasic_toggled() -{ - ui->refreshAccounts->setEnabled(true); -} - -void Main::on_showContracts_toggled() -{ - ui->refreshAccounts->setEnabled(true); -} - -void Main::on_onlyNamed_toggled() -{ - ui->refreshAccounts->setEnabled(true); -} - void Main::refreshBlockCount() { auto d = ethereum()->blockChain().details(); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 4e13ad208..f1e11cea6 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -145,13 +145,6 @@ private slots: void on_claimPresale_triggered(); void on_exportKey_triggered(); - // Account pane - void on_accountsFilter_textChanged(); - void on_showBasic_toggled(); - void on_showContracts_toggled(); - void on_onlyNamed_toggled(); - void on_refreshAccounts_clicked(); - // Tools void on_newTransaction_triggered(); void on_loadJS_triggered(); From 380b3a82049788a649336e8f391729c065237af2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 2 Aug 2015 13:54:57 +0100 Subject: [PATCH 3/5] Build fixes for plugin stuff. --- alethzero/AllAccounts.cpp | 17 +++++++++-------- alethzero/AllAccounts.h | 2 +- alethzero/MainFace.cpp | 10 +++++++--- alethzero/MainFace.h | 17 ++++++++++++----- alethzero/MainWin.cpp | 2 +- alethzero/MainWin.h | 6 ++---- 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/alethzero/AllAccounts.cpp b/alethzero/AllAccounts.cpp index d93cd1322..fcb673775 100644 --- a/alethzero/AllAccounts.cpp +++ b/alethzero/AllAccounts.cpp @@ -21,6 +21,7 @@ #include "AllAccounts.h" #include +#include #include #include #include @@ -46,8 +47,8 @@ AllAccounts::~AllAccounts() void AllAccounts::installWatches() { - installWatch(ChainChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); - installWatch(PendingChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); + main()->installWatch(ChainChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); + main()->installWatch(PendingChangedFilter, [=](LocalisedLogEntries const&){ onAllChange(); }); } void AllAccounts::refresh() @@ -64,10 +65,10 @@ void AllAccounts::refresh() bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); if (!((showContract && isContract) || (showBasic && !isContract))) continue; - string r = render(i); + string r = static_cast(main())->render(i); if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE")) continue; - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ui->accounts)) + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), m_ui->accounts)) ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); } #endif @@ -76,7 +77,7 @@ void AllAccounts::refresh() void AllAccounts::onAllChange() { - ui->refreshAccounts->setEnabled(true); + m_ui->refreshAccounts->setEnabled(true); } void AllAccounts::on_accounts_currentItemChanged() @@ -102,15 +103,15 @@ void AllAccounts::on_accounts_currentItemChanged() { m_ui->accountInfo->appendHtml("Corrupted trie."); } - ui->accountInfo->moveCursor(QTextCursor::Start); + m_ui->accountInfo->moveCursor(QTextCursor::Start); } } void AllAccounts::on_accounts_doubleClicked() { - if (ui->accounts->count()) + if (m_ui->accounts->count()) { - auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); + auto hba = m_ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); } diff --git a/alethzero/AllAccounts.h b/alethzero/AllAccounts.h index e9ded1999..72f97d882 100644 --- a/alethzero/AllAccounts.h +++ b/alethzero/AllAccounts.h @@ -37,7 +37,7 @@ namespace az class AllAccounts: public Plugin { public: - AllAccounts(MainFace* _m): Plugin(_m, "AllAccounts") {} + AllAccounts(MainFace* _m); ~AllAccounts(); private slots: diff --git a/alethzero/MainFace.cpp b/alethzero/MainFace.cpp index 97a615008..45669626b 100644 --- a/alethzero/MainFace.cpp +++ b/alethzero/MainFace.cpp @@ -20,7 +20,7 @@ */ #include "MainFace.h" - +using namespace std; using namespace dev; using namespace az; @@ -31,7 +31,6 @@ Plugin::Plugin(MainFace* _f, std::string const& _name): _f->adoptPlugin(this); } - QDockWidget* Plugin::dock(Qt::DockWidgetArea _area, QString _title) { if (_title.isEmpty()) @@ -46,7 +45,7 @@ QDockWidget* Plugin::dock(Qt::DockWidgetArea _area, QString _title) void Plugin::addToDock(Qt::DockWidgetArea _area, QDockWidget* _dockwidget, Qt::Orientation _orientation) { - m_main->addDockWidget(_area, m_dock, _orientation); + m_main->addDockWidget(_area, _dockwidget, _orientation); } void Plugin::addAction(QAction* _a) @@ -54,6 +53,11 @@ void Plugin::addAction(QAction* _a) m_main->addAction(_a); } +void MainFace::adoptPlugin(Plugin* _p) +{ + m_plugins[_p->name()] = shared_ptr(_p); +} + void MainFace::killPlugins() { m_plugins.clear(); diff --git a/alethzero/MainFace.h b/alethzero/MainFace.h index 2104ea05b..c5ea23798 100644 --- a/alethzero/MainFace.h +++ b/alethzero/MainFace.h @@ -24,16 +24,18 @@ #include #include #include +#include #include #include #include +#include #include "Context.h" namespace dev { -namespace web3 { class WebThreeDirect; } -namespace eth { class Client; } +class WebThreeDirect; +namespace eth { class Client; class LogFilter; } namespace shh { class WhisperHost; } namespace az @@ -41,22 +43,27 @@ namespace az class Plugin; +using WatchHandler = std::function; + class MainFace: public QMainWindow, public Context { public: explicit MainFace(QWidget* _parent = nullptr): QMainWindow(_parent) {} - void adoptPlugin(Plugin* _p) { m_plugins.insert(_p->name(), std::shared_ptr(_p)); } + void adoptPlugin(Plugin* _p); void killPlugins(); void allChange(); // TODO: tidy - all should be references that throw if module unavailable. // TODO: provide a set of available web3 modules. - virtual dev::web3::WebThreeDirect* web3() const = 0; + virtual dev::WebThreeDirect* web3() const = 0; virtual dev::eth::Client* ethereum() const = 0; virtual std::shared_ptr whisper() const = 0; + virtual unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f) = 0; + virtual unsigned installWatch(dev::h256 const& _tf, WatchHandler const& _f) = 0; + private: std::unordered_map> m_plugins; }; @@ -69,7 +76,7 @@ public: std::string const& name() const { return m_name; } - dev::web3::WebThreeDirect* web3() const { return m_main->web3(); } + dev::WebThreeDirect* web3() const { return m_main->web3(); } dev::eth::Client* ethereum() const { return m_main->ethereum(); } std::shared_ptr whisper() const { return m_main->whisper(); } MainFace* main() { return m_main; } diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 72271bcef..3b28cc7b3 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -418,7 +418,7 @@ unsigned Main::installWatch(LogFilter const& _tf, WatchHandler const& _f) return ret; } -unsigned Main::installWatch(dev::h256 _tf, WatchHandler const& _f) +unsigned Main::installWatch(h256 const& _tf, WatchHandler const& _f) { auto ret = ethereum()->installWatch(_tf, Reaping::Manual); m_handlers[ret] = _f; diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index f1e11cea6..74352ba9e 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -26,7 +26,6 @@ #endif #include - #include #include #include @@ -132,7 +131,6 @@ private slots: // View void on_refresh_triggered(); void on_showAll_triggered() { refreshBlockChain(); } - void on_showAllAccounts_triggered() { refreshAccounts(); } void on_preview_triggered(); // Account management @@ -221,8 +219,8 @@ private: void setPrivateChain(QString const& _private, bool _forceConfigure = false); - unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f); - unsigned installWatch(dev::h256 _tf, WatchHandler const& _f); + unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f) override; + unsigned installWatch(dev::h256 const& _tf, WatchHandler const& _f) override; void uninstallWatch(unsigned _w); void keysChanged(); From c4f3c3683f0c0a5e9a9be3234c95776b7a4ada44 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 2 Aug 2015 14:45:45 +0100 Subject: [PATCH 4/5] Final bugs squished for plugin system & AllAccounts. --- alethzero/AllAccounts.cpp | 13 +++++++++++-- alethzero/AllAccounts.h | 16 +++++----------- alethzero/MainFace.cpp | 1 + alethzero/MainFace.h | 4 ++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/alethzero/AllAccounts.cpp b/alethzero/AllAccounts.cpp index fcb673775..71c96cc62 100644 --- a/alethzero/AllAccounts.cpp +++ b/alethzero/AllAccounts.cpp @@ -36,9 +36,18 @@ AllAccounts::AllAccounts(MainFace* _m): Plugin(_m, "AllAccounts"), m_ui(new Ui::AllAccounts) { - m_ui->setupUi(dock()); + dock(Qt::RightDockWidgetArea, "All Accounts")->setWidget(new QWidget()); + m_ui->setupUi(dock()->widget()); installWatches(); refresh(); + + connect(m_ui->accounts, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(on_accounts_currentItemChanged())); + connect(m_ui->accounts, SIGNAL(doubleClicked(QModelIndex)), SLOT(on_accounts_doubleClicked())); + connect(m_ui->refreshAccounts, SIGNAL(clicked()), SLOT(refresh())); + connect(m_ui->accountsFilter, SIGNAL(textChanged(QString)), SLOT(onAllChange())); + connect(m_ui->showBasic, SIGNAL(toggled(bool)), SLOT(onAllChange())); + connect(m_ui->showContracts, SIGNAL(toggled(bool)), SLOT(onAllChange())); + connect(m_ui->onlyNamed, SIGNAL(toggled(bool)), SLOT(onAllChange())); } AllAccounts::~AllAccounts() @@ -72,7 +81,7 @@ void AllAccounts::refresh() ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); } #endif - m_refreshAccounts->setEnabled(false); + m_ui->refreshAccounts->setEnabled(false); } void AllAccounts::onAllChange() diff --git a/alethzero/AllAccounts.h b/alethzero/AllAccounts.h index 72f97d882..ee3f3a15d 100644 --- a/alethzero/AllAccounts.h +++ b/alethzero/AllAccounts.h @@ -34,8 +34,10 @@ namespace dev namespace az { -class AllAccounts: public Plugin +class AllAccounts: public QObject, public Plugin { + Q_OBJECT + public: AllAccounts(MainFace* _m); ~AllAccounts(); @@ -43,21 +45,13 @@ public: private slots: void on_accounts_currentItemChanged(); void on_accounts_doubleClicked(); - void on_refreshAccounts_clicked() { refresh(); } - - void on_accountsFilter_textChanged() { onAllChange(); } - void on_showBasic_toggled() { onAllChange(); } - void on_showContracts_toggled() { onAllChange(); } - void on_onlyNamed_toggled() { onAllChange(); } -private: void onAllChange(); - - void installWatches(); void refresh(); +private: + void installWatches(); Ui::AllAccounts* m_ui; - QAction* m_refreshAccounts; }; } diff --git a/alethzero/MainFace.cpp b/alethzero/MainFace.cpp index 45669626b..82c76563a 100644 --- a/alethzero/MainFace.cpp +++ b/alethzero/MainFace.cpp @@ -39,6 +39,7 @@ QDockWidget* Plugin::dock(Qt::DockWidgetArea _area, QString _title) { m_dock = new QDockWidget(_title, m_main); m_main->addDockWidget(_area, m_dock); + m_dock->setFeatures(QDockWidget::AllDockWidgetFeatures | QDockWidget::DockWidgetVerticalTitleBar); } return m_dock; } diff --git a/alethzero/MainFace.h b/alethzero/MainFace.h index c5ea23798..f6bf5b75a 100644 --- a/alethzero/MainFace.h +++ b/alethzero/MainFace.h @@ -87,9 +87,9 @@ public: virtual void onAllChange() {} private: - MainFace* m_main; + MainFace* m_main = nullptr; std::string m_name; - QDockWidget* m_dock; + QDockWidget* m_dock = nullptr; }; } From 88488dfdb4a92507a680bbd68605ce7875b08513 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 3 Aug 2015 18:27:33 +0200 Subject: [PATCH 5/5] Brace style, windows build fix. --- alethzero/AllAccounts.h | 3 ++- alethzero/MainWin.h | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/alethzero/AllAccounts.h b/alethzero/AllAccounts.h index ee3f3a15d..7104a6d70 100644 --- a/alethzero/AllAccounts.h +++ b/alethzero/AllAccounts.h @@ -25,7 +25,8 @@ #include #include "MainFace.h" -namespace Ui { +namespace Ui +{ class AllAccounts; } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 74352ba9e..918ff3ef4 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -65,8 +65,6 @@ class DappLoader; class DappHost; struct Dapp; -using WatchHandler = std::function; - QString contentsOfQResource(std::string const& res); class Main: public dev::az::MainFace @@ -219,8 +217,8 @@ private: void setPrivateChain(QString const& _private, bool _forceConfigure = false); - unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f) override; - unsigned installWatch(dev::h256 const& _tf, WatchHandler const& _f) override; + unsigned installWatch(dev::eth::LogFilter const& _tf, dev::az::WatchHandler const& _f) override; + unsigned installWatch(dev::h256 const& _tf, dev::az::WatchHandler const& _f) override; void uninstallWatch(unsigned _w); void keysChanged(); @@ -256,7 +254,7 @@ private: std::unique_ptr m_webThree; - std::map m_handlers; + std::map m_handlers; unsigned m_nameRegFilter = (unsigned)-1; unsigned m_currenciesFilter = (unsigned)-1; unsigned m_balancesFilter = (unsigned)-1;