diff --git a/ethereal/assets/ext/ethereum.js b/ethereal/assets/ext/ethereum.js index fb8bd23a74..697a404a34 100644 --- a/ethereal/assets/ext/ethereum.js +++ b/ethereal/assets/ext/ethereum.js @@ -6,7 +6,8 @@ window.eth = { test: function() { var t = undefined; - navigator.qt.onmessage = function(d) { t = d; } + postData({call: "test"}) + navigator.qt.onmessage = function(d) {console.log("onmessage called"); t = d; } for(;;) { if(t !== undefined) { return t @@ -14,7 +15,8 @@ window.eth = { } }, - mutan: function(code) { + mutan: function(code, cb) { + postData({call: "mutan", args: [code]}, cb) }, toHex: function(str) { @@ -281,3 +283,13 @@ navigator.qt.onmessage = function(ev) { } } } + +eth.on("chain:changed", function() { +}) + +eth.on("messages", { /* filters */}, function(messages){ +}) + +eth.on("pending:changed", function() { +}) + diff --git a/ethereal/assets/ext/test.html b/ethereal/assets/ext/test.html index 629e98377e..4bac7d36fa 100644 --- a/ethereal/assets/ext/test.html +++ b/ethereal/assets/ext/test.html @@ -32,6 +32,10 @@ function test() { eth.getBlock("f70097659f329a09642a27f11338d9269de64f1d4485786e36bfc410832148cd", function(block) { console.log(block) }) + + eth.mutan("var a = 10", function(code) { + console.log("code", code) + }); } diff --git a/ethereal/assets/qml/views/chain.qml b/ethereal/assets/qml/views/chain.qml index 2b968d56cf..0f5604a9f7 100644 --- a/ethereal/assets/qml/views/chain.qml +++ b/ethereal/assets/qml/views/chain.qml @@ -25,9 +25,57 @@ Rectangle { model: blockModel - onDoubleClicked: { - popup.visible = true - popup.setDetails(blockModel.get(row)) + itemDelegate: Item { + Text { + anchors { + left: parent.left + right: parent.right + leftMargin: 10 + verticalCenter: parent.verticalCenter + } + color: styleData.textColor + elide: styleData.elideMode + text: styleData.value + font.pixelSize: 11 + MouseArea { + acceptedButtons: Qt.RightButton + propagateComposedEvents: true + anchors.fill: parent + onClicked: { + blockTable.selection.clear() + blockTable.selection.select(styleData.row) + + contextMenu.row = styleData.row; + contextMenu.popup() + } + } + } + + } + + Menu { + id: contextMenu + property var row; + MenuItem { + text: "Details" + onTriggered: { + popup.visible = true + popup.setDetails(blockModel.get(this.row)) + } + } + + MenuSeparator{} + + MenuItem { + text: "Dump State" + onTriggered: { + generalFileDialog.show(false, function(path) { + var hash = blockModel.get(this.row).hash; + + gui.dumpState(hash, path); + }); + } + } } } diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index b35500209c..30e1071f7e 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -49,8 +49,7 @@ ApplicationWindow { text: "Import App" shortcut: "Ctrl+o" onTriggered: { - generalFileDialog.callback = importApp; - generalFileDialog.open() + generalFileDialog.show(true, importApp) } } @@ -62,10 +61,9 @@ ApplicationWindow { MenuItem { text: "Add plugin" onTriggered: { - generalFileDialog.callback = function(path) { + generalFileDialog.show(true, function(path) { addPlugin(path, {canClose: true}) - } - generalFileDialog.open() + }) } } @@ -75,10 +73,9 @@ ApplicationWindow { text: "Import key" shortcut: "Ctrl+i" onTriggered: { - generalFileDialog.callback = function(path) { - ui.importKey(path) - } - generalFileDialog.open() + generalFileDialog.show(true, function(path) { + gui.importKey(path) + }) } } @@ -86,9 +83,8 @@ ApplicationWindow { text: "Export keys" shortcut: "Ctrl+e" onTriggered: { - generalFileDialog.callback = function(path) { - } - generalFileDialog.open() + generalFileDialog.show(false, function(path) { + }) } } } @@ -111,10 +107,19 @@ ApplicationWindow { MenuItem { text: "Run JS file" onTriggered: { - generalFileDialog.callback = function(path) { + generalFileDialog.show(true, function(path) { eth.evalJavascriptFile(path) - } - generalFileDialog.open() + }) + } + } + + MenuItem { + text: "Dump state" + onTriggered: { + generalFileDialog.show(false, function(path) { + // Empty hash for latest + gui.dumpState("", path) + }) } } } @@ -396,8 +401,15 @@ ApplicationWindow { id: generalFileDialog property var callback; onAccepted: { - var path = this.fileUrl.toString() - callback.call(this, path) + var path = this.fileUrl.toString(); + callback.call(this, path); + } + + function show(selectExisting, callback) { + generalFileDialog.callback = callback; + generalFileDialog.selectExisting = selectExisting; + + this.open(); } } diff --git a/ethereal/assets/qml/webapp.qml b/ethereal/assets/qml/webapp.qml index e6d0f5c14f..22e404cc81 100644 --- a/ethereal/assets/qml/webapp.qml +++ b/ethereal/assets/qml/webapp.qml @@ -78,6 +78,7 @@ ApplicationWindow { } } + WebView { objectName: "webView" id: webview @@ -127,6 +128,8 @@ ApplicationWindow { this.cleanPath = false; } } + + experimental.preferences.javascriptEnabled: true experimental.preferences.navigatorQtObjectEnabled: true experimental.preferences.developerExtrasEnabled: true @@ -251,9 +254,13 @@ ApplicationWindow { break - case "debug": - console.log(data.args[0]); - break; + case "mutan": + require(1) + + var code = eth.compileMutan(data.args[0]) + postData(data._seed, "0x"+code) + + break; } } catch(e) { console.log(data.call + ": " + e) @@ -262,6 +269,11 @@ ApplicationWindow { } } + function post(seed, data) { + console.log("data", data) + postData(data._seed, data) + } + function require(args, num) { if(args.length < num) { throw("required argument count of "+num+" got "+args.length); diff --git a/ethereal/ext_app.go b/ethereal/ext_app.go index 5543b0083f..514084c974 100644 --- a/ethereal/ext_app.go +++ b/ethereal/ext_app.go @@ -21,6 +21,7 @@ type AppContainer interface { NewBlock(*ethchain.Block) NewWatcher(chan bool) Messages(ethstate.Messages, string) + Post(string, int) } type ExtApplication struct { diff --git a/ethereal/gui.go b/ethereal/gui.go index 066db48b90..6149b39b77 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "math/big" + "os" "strconv" "strings" "time" @@ -155,6 +156,40 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) { return gui.win, nil } +func (self *Gui) DumpState(hash, path string) { + var stateDump []byte + + if len(hash) == 0 { + stateDump = self.eth.StateManager().CurrentState().Dump() + } else { + var block *ethchain.Block + if hash[0] == '#' { + i, _ := strconv.Atoi(hash[1:]) + block = self.eth.BlockChain().GetBlockByNumber(uint64(i)) + } else { + block = self.eth.BlockChain().GetBlock(ethutil.Hex2Bytes(hash)) + } + + if block == nil { + logger.Infof("block err: not found %s\n", hash) + return + } + + stateDump = block.State().Dump() + } + + file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm) + if err != nil { + logger.Infoln("dump err: ", err) + return + } + defer file.Close() + + logger.Infof("dumped state (%s) to %s\n", hash, path) + + file.Write(stateDump) +} + // The done handler will be called by QML when all views have been loaded func (gui *Gui) Done() { gui.qmlDone = true diff --git a/ethereal/html_container.go b/ethereal/html_container.go index e682dc3eb3..69edea5703 100644 --- a/ethereal/html_container.go +++ b/ethereal/html_container.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "errors" + "fmt" "io/ioutil" "net/url" "os" @@ -139,3 +140,8 @@ func (self *HtmlApplication) Messages(messages ethstate.Messages, id string) { func (app *HtmlApplication) Destroy() { app.engine.Destroy() } + +func (app *HtmlApplication) Post(data string, seed int) { + fmt.Println("about to call 'post'") + app.webView.Call("post", seed, data) +} diff --git a/ethereal/qml_container.go b/ethereal/qml_container.go index 8c9ea0a8f6..85bd7c6995 100644 --- a/ethereal/qml_container.go +++ b/ethereal/qml_container.go @@ -64,3 +64,5 @@ func (app *QmlApplication) Engine() *qml.Engine { func (app *QmlApplication) Window() *qml.Window { return app.win } + +func (app *QmlApplication) Post(data string, s int) {} diff --git a/ethereum/main.go b/ethereum/main.go index 6c5c71bf3a..070d3c201c 100644 --- a/ethereum/main.go +++ b/ethereum/main.go @@ -71,7 +71,7 @@ func main() { } // Leave the Println. This needs clean output for piping - fmt.Println(block.State().Dump()) + fmt.Printf("%s\n", block.State().Dump()) os.Exit(0) }