aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/mist/assets/qml/views
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/mist/assets/qml/views')
-rw-r--r--cmd/mist/assets/qml/views/chain.qml253
-rw-r--r--cmd/mist/assets/qml/views/history.qml51
-rw-r--r--cmd/mist/assets/qml/views/info.qml196
-rw-r--r--cmd/mist/assets/qml/views/jeffcoin/jeff.pngbin0 -> 84076 bytes
-rw-r--r--cmd/mist/assets/qml/views/jeffcoin/jeffcoin.qml190
-rw-r--r--cmd/mist/assets/qml/views/pending_tx.qml44
-rw-r--r--cmd/mist/assets/qml/views/transaction.qml216
-rw-r--r--cmd/mist/assets/qml/views/wallet.qml173
8 files changed, 1123 insertions, 0 deletions
diff --git a/cmd/mist/assets/qml/views/chain.qml b/cmd/mist/assets/qml/views/chain.qml
new file mode 100644
index 000000000..c4ceecfc0
--- /dev/null
+++ b/cmd/mist/assets/qml/views/chain.qml
@@ -0,0 +1,253 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ id: root
+ property var title: "Block Chain"
+ property var menuItem
+
+ objectName: "chainView"
+ visible: false
+ anchors.fill: parent
+
+ TableView {
+ id: blockTable
+ width: parent.width
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ TableViewColumn{ role: "number" ; title: "#" ; width: 100 }
+ TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 }
+ TableViewColumn{ role: "txAmount" ; title: "Tx amount" ; width: 100 }
+
+ model: blockModel
+
+ 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.LeftButton | Qt.RightButton
+ propagateComposedEvents: true
+ anchors.fill: parent
+ onClicked: {
+ blockTable.selection.clear()
+ blockTable.selection.select(styleData.row)
+
+ if(mouse.button == Qt.RightButton) {
+ contextMenu.row = styleData.row;
+ contextMenu.popup()
+ }
+ }
+
+ onDoubleClicked: {
+ popup.visible = true
+ popup.setDetails(blockModel.get(styleData.row))
+ }
+ }
+ }
+
+ }
+
+ Menu {
+ id: contextMenu
+ property var row
+ MenuItem {
+ text: "Details"
+ onTriggered: {
+ popup.visible = true
+ popup.setDetails(blockModel.get(contextMenu.row))
+ }
+ }
+
+ MenuSeparator{}
+
+ MenuItem {
+ text: "Copy"
+ onTriggered: {
+ copyToClipboard(blockModel.get(contextMenu.row).hash)
+ }
+ }
+
+ MenuItem {
+ text: "Dump State"
+ onTriggered: {
+ generalFileDialog.show(false, function(path) {
+ var hash = blockModel.get(contextMenu.row).hash;
+
+ gui.dumpState(hash, path);
+ });
+ }
+ }
+ }
+ }
+
+
+
+ function addBlock(block, initial) {
+ if(initial == undefined){
+ initial = false
+ }
+
+ var amount = block.transactions.length;
+ var txs = [];
+ for(var i = 0; i < block.transactions.length; i++) {
+ var tx = JSON.parse(block.transactions.getAsJson(i));
+ txs.push(tx);
+ }
+
+ if(initial){
+ blockModel.append({size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
+ } else {
+ blockModel.insert(0, {size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)})
+ }
+ }
+
+ Window {
+ id: popup
+ visible: false
+ //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
+ property var block
+ width: root.width
+ height: 300
+ Component{
+ id: blockDetailsDelegate
+ Rectangle {
+ color: "#252525"
+ width: popup.width
+ height: 150
+ Column {
+ anchors.leftMargin: 10
+ anchors.topMargin: 5
+ anchors.top: parent.top
+ anchors.left: parent.left
+ Text { text: '<h3>Block details</h3>'; color: "#F2F2F2"}
+ Text { text: '<b>Block number:</b> ' + number + " (Size: " + size + ")"; color: "#F2F2F2"}
+ Text { text: '<b>Hash:</b> ' + hash; color: "#F2F2F2"}
+ Text { text: '<b>Coinbase:</b> &lt;' + name + '&gt; ' + coinbase; color: "#F2F2F2"}
+ Text { text: '<b>Block found at:</b> ' + prettyTime; color: "#F2F2F2"}
+ Text { text: '<b>Gas used:</b> ' + gasUsed + " / " + gasLimit; color: "#F2F2F2"}
+ }
+ }
+ }
+ ListView {
+ model: singleBlock
+ delegate: blockDetailsDelegate
+ anchors.top: parent.top
+ height: 100
+ anchors.leftMargin: 20
+ id: listViewThing
+ Layout.maximumHeight: 40
+ }
+ TableView {
+ id: txView
+ anchors.top: listViewThing.bottom
+ anchors.topMargin: 50
+ width: parent.width
+
+ TableViewColumn{width: 90; role: "value" ; title: "Value" }
+ TableViewColumn{width: 200; role: "hash" ; title: "Hash" }
+ TableViewColumn{width: 200; role: "sender" ; title: "Sender" }
+ TableViewColumn{width: 200;role: "address" ; title: "Receiver" }
+ TableViewColumn{width: 60; role: "gas" ; title: "Gas" }
+ TableViewColumn{width: 60; role: "gasPrice" ; title: "Gas Price" }
+ TableViewColumn{width: 60; role: "isContract" ; title: "Contract" }
+
+ model: transactionModel
+ onClicked: {
+ var tx = transactionModel.get(row)
+ if(tx.data) {
+ popup.showContractData(tx)
+ }else{
+ popup.height = 440
+ }
+ }
+ }
+
+ function showContractData(tx) {
+ txDetailsDebugButton.tx = tx
+ if(tx.createsContract) {
+ contractData.text = tx.data
+ contractLabel.text = "<h4> Transaction created contract " + tx.address + "</h4>"
+ }else{
+ contractLabel.text = "<h4> Transaction ran contract " + tx.address + "</h4>"
+ contractData.text = tx.rawData
+ }
+ popup.height = 540
+ }
+
+ Rectangle {
+ id: txDetails
+ width: popup.width
+ height: 300
+ anchors.left: listViewThing.left
+ anchors.top: txView.bottom
+ Label {
+ text: "<h4>Contract data</h4>"
+ anchors.top: parent.top
+ anchors.left: parent.left
+ id: contractLabel
+ anchors.leftMargin: 10
+ }
+ Button {
+ property var tx
+ id: txDetailsDebugButton
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ anchors.top: parent.top
+ anchors.topMargin: 10
+ text: "Debug contract"
+ onClicked: {
+ if(tx && tx.createsContract){
+ eth.startDbWithCode(tx.rawData)
+ }else {
+ eth.startDbWithContractAndData(tx.address, tx.rawData)
+ }
+ }
+ }
+ TextArea {
+ id: contractData
+ text: "Contract"
+ anchors.top: contractLabel.bottom
+ anchors.left: parent.left
+ anchors.bottom: popup.bottom
+ wrapMode: Text.Wrap
+ width: parent.width - 30
+ height: 80
+ anchors.leftMargin: 10
+ }
+ }
+ property var transactionModel: ListModel {
+ id: transactionModel
+ }
+ property var singleBlock: ListModel {
+ id: singleBlock
+ }
+ function setDetails(bl){
+ singleBlock.set(0, bl)
+ popup.height = 300
+ transactionModel.clear()
+ if(bl.txs !== undefined){
+ for(var i = 0; i < bl.txs.count; i++) {
+ transactionModel.insert(0, bl.txs.get(i))
+ }
+ if(bl.txs.count > 0 && bl.txs.get(0).data){
+ popup.showContractData(bl.txs.get(0))
+ }
+ }
+ txView.forceActiveFocus()
+ }
+ }
+}
diff --git a/cmd/mist/assets/qml/views/history.qml b/cmd/mist/assets/qml/views/history.qml
new file mode 100644
index 000000000..c72f8f3ae
--- /dev/null
+++ b/cmd/mist/assets/qml/views/history.qml
@@ -0,0 +1,51 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ property var title: "Transactions"
+ property var menuItem
+
+
+ id: historyView
+ visible: false
+ anchors.fill: parent
+ objectName: "transactionView"
+
+ property var txModel: ListModel {
+ id: txModel
+ }
+ TableView {
+ id: txTableView
+ anchors.fill: parent
+ TableViewColumn{ role: "inout" ; title: "" ; width: 40 }
+ TableViewColumn{ role: "value" ; title: "Value" ; width: 100 }
+ TableViewColumn{ role: "address" ; title: "Address" ; width: 430 }
+ TableViewColumn{ role: "contract" ; title: "Contract" ; width: 100 }
+
+ model: txModel
+ }
+
+ function addTx(tx, inout) {
+ var isContract
+ if (tx.contract == true){
+ isContract = "Yes"
+ }else{
+ isContract = "No"
+ }
+
+
+ var address;
+ if(inout == "recv") {
+ address = tx.sender;
+ } else {
+ address = tx.address;
+ }
+
+ txModel.insert(0, {inout: inout, hash: tx.hash, address: address, value: tx.value, contract: isContract})
+ }
+}
diff --git a/cmd/mist/assets/qml/views/info.qml b/cmd/mist/assets/qml/views/info.qml
new file mode 100644
index 000000000..3ff551b05
--- /dev/null
+++ b/cmd/mist/assets/qml/views/info.qml
@@ -0,0 +1,196 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ property var title: "Debug Info"
+ property var menuItem
+
+ objectName: "infoView"
+ visible: false
+ anchors.fill: parent
+
+ color: "#00000000"
+
+ Column {
+ id: info
+ spacing: 3
+ anchors.fill: parent
+ anchors.topMargin: 5
+ anchors.leftMargin: 5
+
+ Label {
+ id: addressLabel
+ text: "Address"
+ }
+ TextField {
+ text: eth.key().address
+ width: 500
+ }
+
+ Label {
+ text: "Client ID"
+ }
+ TextField {
+ text: gui.getCustomIdentifier()
+ width: 500
+ placeholderText: "Anonymous"
+ onTextChanged: {
+ gui.setCustomIdentifier(text)
+ }
+ }
+
+ TextArea {
+ objectName: "statsPane"
+ width: parent.width
+ height: 200
+ selectByMouse: true
+ readOnly: true
+ font.family: "Courier"
+ }
+ }
+
+ RowLayout {
+ id: logLayout
+ width: parent.width
+ height: 200
+ anchors.bottom: parent.bottom
+
+ TableView {
+ id: addressView
+ width: parent.width
+ height: 200
+ anchors {
+ left: parent.left
+ right: logLevelSlider.left
+ bottom: parent.bottom
+ top: parent.top
+ }
+ TableViewColumn{ role: "name"; title: "name" }
+ TableViewColumn{ role: "address"; title: "address"; width: 300}
+
+ property var addressModel: ListModel {
+ id: addressModel
+ }
+
+ model: addressModel
+ 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.LeftButton | Qt.RightButton
+ propagateComposedEvents: true
+ anchors.fill: parent
+ onClicked: {
+ addressView.selection.clear()
+ addressView.selection.select(styleData.row)
+
+ if(mouse.button == Qt.RightButton) {
+ contextMenu.row = styleData.row;
+ contextMenu.popup()
+ }
+ }
+ }
+ }
+ }
+
+ Menu {
+ id: contextMenu
+ property var row;
+
+ MenuItem {
+ text: "Copy"
+ onTriggered: {
+ copyToClipboard(addressModel.get(this.row).address)
+ }
+ }
+ }
+ }
+
+ /*
+ TableView {
+ id: logView
+ headerVisible: false
+ anchors {
+ right: logLevelSlider.left
+ left: parent.left
+ bottom: parent.bottom
+ top: parent.top
+ }
+
+ TableViewColumn{ role: "description" ; title: "log" }
+
+ model: logModel
+ }
+ */
+
+ Slider {
+ id: logLevelSlider
+ value: gui.getLogLevelInt()
+ anchors {
+ right: parent.right
+ top: parent.top
+ bottom: parent.bottom
+
+ rightMargin: 5
+ leftMargin: 5
+ topMargin: 5
+ bottomMargin: 5
+ }
+
+ orientation: Qt.Vertical
+ maximumValue: 5
+ stepSize: 1
+
+ onValueChanged: {
+ gui.setLogLevel(value)
+ }
+ }
+ }
+
+ property var logModel: ListModel {
+ id: logModel
+ }
+
+ function addDebugMessage(message){
+ debuggerLog.append({value: message})
+ }
+
+ function addAddress(address) {
+ addressModel.append({name: address.name, address: address.address})
+ }
+
+ function clearAddress() {
+ addressModel.clear()
+ }
+
+ function addLog(str) {
+ // Remove first item once we've reached max log items
+ if(logModel.count > 250) {
+ logModel.remove(0)
+ }
+
+ if(str.len != 0) {
+ if(logView.flickableItem.atYEnd) {
+ logModel.append({description: str})
+ logView.positionViewAtRow(logView.rowCount - 1, ListView.Contain)
+ } else {
+ logModel.append({description: str})
+ }
+ }
+
+ }
+}
diff --git a/cmd/mist/assets/qml/views/jeffcoin/jeff.png b/cmd/mist/assets/qml/views/jeffcoin/jeff.png
new file mode 100644
index 000000000..2b9c6651a
--- /dev/null
+++ b/cmd/mist/assets/qml/views/jeffcoin/jeff.png
Binary files differ
diff --git a/cmd/mist/assets/qml/views/jeffcoin/jeffcoin.qml b/cmd/mist/assets/qml/views/jeffcoin/jeffcoin.qml
new file mode 100644
index 000000000..23502d334
--- /dev/null
+++ b/cmd/mist/assets/qml/views/jeffcoin/jeffcoin.qml
@@ -0,0 +1,190 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+
+Rectangle {
+ id: root
+ property var title: "JeffCoin"
+ property var iconSource: "./views/jeffcoin/jeff.png"
+ property var menuItem
+ property var filter
+ property var address: "fc0a9436890478bb9b1c6ed7455c2535366f4a99"
+
+ function insertTx(message, blockNumber) {
+ if(!message) return;
+
+ var from = message.from
+ var to = message.input.substr(24, 40)
+ var value = eth.fromNumber(message.input.substr(64, 64))
+
+ var me = eth.key().address;
+ if((to == me|| from == me) && message.input.length == 128) {
+ var to = eth.lookupName(to)
+ var from = eth.lookupName(from)
+ txModel.insert(0, {confirmations: blockNumber - message.number, from: from, to: to, value: value})
+ }
+ }
+
+ function setBalance() {
+ var jeffCoinAmount = eth.fromNumber(eth.storageAt(address, eth.key().address)) + " JΞF"
+ menuItem.secondaryTitle = jeffCoinAmount
+
+ balance.text = "<b>Balance</b>: " + jeffCoinAmount;
+ }
+
+ function onReady() {
+ setBalance()
+
+ filter = new ethx.watch({latest: -1, to: address})
+ filter.changed(function(messages) {
+ setBalance()
+
+ var blockNumber = eth.block(-1).number;
+ for(var i = 0; i < messages.length; i++) {
+ insertTx(messages.get(i), blockNumber);
+ }
+ });
+
+ var blockNumber = eth.block(-1).number;
+ var msgs = filter.messages()
+ for(var i = msgs.length-1; i >= 0; i--) {
+ var message = JSON.parse(msgs.getAsJson(i))
+
+ insertTx(message, blockNumber)
+ }
+
+ var chainChanged = ethx.watch("chain")
+ chainChanged.changed(function() {
+ for(var i = 0; i < txModel.count; i++) {
+ var entry = txModel.get(i);
+ entry.confirmations++;
+ }
+ });
+ }
+
+ function onDestroy() {
+ filter.uninstall()
+ }
+
+ ColumnLayout {
+ spacing: 10
+ y: 40
+ anchors.fill: parent
+
+ Text {
+ id: balance
+ text: "<b>Balance</b>: " + eth.fromNumber(eth.storageAt(address, eth.key().address)) + " JΞF"
+ font.pixelSize: 24
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ topMargin: 20
+ }
+ }
+
+ Rectangle {
+ id: newTxPane
+ color: "#ececec"
+ border.color: "#cccccc"
+ border.width: 1
+ anchors {
+ top: balance.bottom
+ topMargin: 10
+ left: parent.left
+ leftMargin: 5
+ right: parent.right
+ rightMargin: 5
+ }
+ height: 100
+
+ RowLayout {
+ id: amountFields
+ spacing: 10
+ anchors {
+ top: parent.top
+ topMargin: 20
+ left: parent.left
+ leftMargin: 20
+ }
+
+ Text {
+ text: "JΞF "
+ }
+
+ // There's something off with the row layout where textfields won't listen to the width setting
+ Rectangle {
+ width: 50
+ height: 20
+ TextField {
+ id: txValue
+ width: parent.width
+ placeholderText: "0.00"
+ }
+ }
+ }
+
+ RowLayout {
+ id: toFields
+ spacing: 10
+ anchors {
+ top: amountFields.bottom
+ topMargin: 5
+ left: parent.left
+ leftMargin: 20
+ }
+
+ Text {
+ text: "To"
+ }
+
+ Rectangle {
+ width: 200
+ height: 20
+ TextField {
+ id: txTo
+ width: parent.width
+ placeholderText: "Address or name"
+ }
+ }
+
+ Button {
+ text: "Send"
+ onClicked: {
+ var lookup = eth.lookupAddress(address)
+ if(lookup.length == 0)
+ lookup = address
+
+ eth.transact({from: eth.key().privateKey, to:lookup, gas: "9000", gasPrice: "10000000000000", data: ["0x"+txTo.text, txValue.text]})
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: newTxPane.bottom
+ topMargin: 10
+ bottom: parent.bottom
+ }
+ TableView {
+ id: txTableView
+ anchors.fill : parent
+ TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 }
+ TableViewColumn{ role: "from" ; title: "From" ; width: 280 }
+ TableViewColumn{ role: "to" ; title: "To" ; width: 280 }
+ TableViewColumn{ role: "confirmations" ; title: "Confirmations" ; width: 100 }
+
+ model: ListModel {
+ id: txModel
+ Component.onCompleted: {
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/cmd/mist/assets/qml/views/pending_tx.qml b/cmd/mist/assets/qml/views/pending_tx.qml
new file mode 100644
index 000000000..4442a69db
--- /dev/null
+++ b/cmd/mist/assets/qml/views/pending_tx.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ property var title: "Pending Transactions"
+ property var menuItem
+
+ objectName: "pendingTxView"
+ anchors.fill: parent
+ visible: false
+ id: pendingTxView
+
+ property var pendingTxModel: ListModel {
+ id: pendingTxModel
+ }
+
+ TableView {
+ id: pendingTxTableView
+ anchors.fill: parent
+ TableViewColumn{ role: "value" ; title: "Value" ; width: 100 }
+ TableViewColumn{ role: "from" ; title: "sender" ; width: 230 }
+ TableViewColumn{ role: "to" ; title: "Reciever" ; width: 230 }
+ TableViewColumn{ role: "contract" ; title: "Contract" ; width: 100 }
+
+ model: pendingTxModel
+ }
+
+ function addTx(tx, inout) {
+ var isContract
+ if (tx.contract == true){
+ isContract = "Yes"
+ }else{
+ isContract = "No"
+ }
+
+
+ pendingTxModel.insert(0, {hash: tx.hash, to: tx.address, from: tx.sender, value: tx.value, contract: isContract})
+ }
+}
diff --git a/cmd/mist/assets/qml/views/transaction.qml b/cmd/mist/assets/qml/views/transaction.qml
new file mode 100644
index 000000000..8792e31eb
--- /dev/null
+++ b/cmd/mist/assets/qml/views/transaction.qml
@@ -0,0 +1,216 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ property var title: "New Transaction"
+ property var menuItem
+
+ objectName: "newTxView"
+ visible: false
+ anchors.fill: parent
+ color: "#00000000"
+
+ Column {
+ id: mainContractColumn
+ anchors.fill: parent
+
+
+ states: [
+ State{
+ name: "ERROR"
+
+ PropertyChanges { target: txResult; visible:true}
+ PropertyChanges { target: codeView; visible:true}
+ },
+ State {
+ name: "DONE"
+
+ PropertyChanges { target: txValue; visible:false}
+ PropertyChanges { target: txGas; visible:false}
+ PropertyChanges { target: txGasPrice; visible:false}
+ PropertyChanges { target: codeView; visible:false}
+ PropertyChanges { target: txButton; visible:false}
+ PropertyChanges { target: txDataLabel; visible:false}
+ PropertyChanges { target: atLabel; visible:false}
+ PropertyChanges { target: txFuelRecipient; visible:false}
+ PropertyChanges { target: valueDenom; visible:false}
+ PropertyChanges { target: gasDenom; visible:false}
+
+ PropertyChanges { target: txResult; visible:true}
+ PropertyChanges { target: txOutput; visible:true}
+ PropertyChanges { target: newTxButton; visible:true}
+ },
+ State {
+ name: "SETUP"
+
+ PropertyChanges { target: txValue; visible:true; text: ""}
+ PropertyChanges { target: txGas; visible:true;}
+ PropertyChanges { target: txGasPrice; visible:true;}
+ PropertyChanges { target: codeView; visible:true; text: ""}
+ PropertyChanges { target: txButton; visible:true}
+ PropertyChanges { target: txDataLabel; visible:true}
+ PropertyChanges { target: valueDenom; visible:true}
+ PropertyChanges { target: gasDenom; visible:true}
+
+ PropertyChanges { target: txResult; visible:false}
+ PropertyChanges { target: txOutput; visible:false}
+ PropertyChanges { target: newTxButton; visible:false}
+ }
+ ]
+ width: 400
+ spacing: 5
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.leftMargin: 5
+ anchors.topMargin: 5
+
+ ListModel {
+ id: denomModel
+ ListElement { text: "Wei" ; zeros: "" }
+ ListElement { text: "Ada" ; zeros: "000" }
+ ListElement { text: "Babbage" ; zeros: "000000" }
+ ListElement { text: "Shannon" ; zeros: "000000000" }
+ ListElement { text: "Szabo" ; zeros: "000000000000" }
+ ListElement { text: "Finney" ; zeros: "000000000000000" }
+ ListElement { text: "Ether" ; zeros: "000000000000000000" }
+ ListElement { text: "Einstein" ;zeros: "000000000000000000000" }
+ ListElement { text: "Douglas" ; zeros: "000000000000000000000000000000000000000000" }
+ }
+
+
+ TextField {
+ id: txFuelRecipient
+ placeholderText: "Address / Name or empty for contract"
+ //validator: RegExpValidator { regExp: /[a-f0-9]{40}/ }
+ width: 400
+ }
+
+ RowLayout {
+ TextField {
+ id: txValue
+ width: 222
+ placeholderText: "Amount"
+ validator: RegExpValidator { regExp: /\d*/ }
+ onTextChanged: {
+ contractFormReady()
+ }
+ }
+
+ ComboBox {
+ id: valueDenom
+ currentIndex: 6
+ model: denomModel
+ }
+ }
+
+ RowLayout {
+ TextField {
+ id: txGas
+ width: 50
+ validator: RegExpValidator { regExp: /\d*/ }
+ placeholderText: "Gas"
+ text: "500"
+ }
+ Label {
+ id: atLabel
+ text: "@"
+ }
+
+ TextField {
+ id: txGasPrice
+ width: 200
+ placeholderText: "Gas price"
+ text: "10"
+ validator: RegExpValidator { regExp: /\d*/ }
+ }
+
+ ComboBox {
+ id: gasDenom
+ currentIndex: 4
+ model: denomModel
+ }
+ }
+
+ Label {
+ id: txDataLabel
+ text: "Data"
+ }
+
+ TextArea {
+ id: codeView
+ height: 300
+ anchors.topMargin: 5
+ width: 400
+ onTextChanged: {
+ contractFormReady()
+ }
+ }
+
+
+ Button {
+ id: txButton
+ /* enabled: false */
+ states: [
+ State {
+ name: "READY"
+ PropertyChanges { target: txButton; /*enabled: true*/}
+ },
+ State {
+ name: "NOTREADY"
+ PropertyChanges { target: txButton; /*enabled:false*/}
+ }
+ ]
+ text: "Send"
+ onClicked: {
+ var value = txValue.text + denomModel.get(valueDenom.currentIndex).zeros;
+ var gasPrice = txGasPrice.text + denomModel.get(gasDenom.currentIndex).zeros;
+ var res = gui.transact(txFuelRecipient.text, value, txGas.text, gasPrice, codeView.text)
+ if(res[1]) {
+ txResult.text = "Your contract <b>could not</b> be sent over the network:\n<b>"
+ txResult.text += res[1].error()
+ txResult.text += "</b>"
+ mainContractColumn.state = "ERROR"
+ } else {
+ txResult.text = "Your transaction has been submitted:\n"
+ txOutput.text = res[0].address
+ mainContractColumn.state = "DONE"
+
+ console.log(res)
+ }
+ }
+ }
+ Text {
+ id: txResult
+ visible: false
+ }
+ TextField {
+ id: txOutput
+ visible: false
+ width: 530
+ }
+ Button {
+ id: newTxButton
+ visible: false
+ text: "Create a new transaction"
+ onClicked: {
+ this.visible = false
+ txResult.text = ""
+ txOutput.text = ""
+ mainContractColumn.state = "SETUP"
+ }
+ }
+ }
+
+ function contractFormReady(){
+ if(codeView.text.length > 0 && txValue.text.length > 0 && txGas.text.length > 0 && txGasPrice.length > 0) {
+ txButton.state = "READY"
+ }else{
+ txButton.state = "NOTREADY"
+ }
+ }
+}
diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml
new file mode 100644
index 000000000..a57e7869a
--- /dev/null
+++ b/cmd/mist/assets/qml/views/wallet.qml
@@ -0,0 +1,173 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.0;
+import QtQuick.Layouts 1.0;
+import QtQuick.Dialogs 1.0;
+import QtQuick.Window 2.1;
+import QtQuick.Controls.Styles 1.1
+import Ethereum 1.0
+
+Rectangle {
+ id: root
+ property var title: "Wallet"
+ property var iconSource: "../facet.png"
+ property var menuItem
+
+ objectName: "walletView"
+ anchors.fill: parent
+
+ function onReady() {
+ menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address))
+ }
+
+ ListModel {
+ id: denomModel
+ ListElement { text: "Wei" ; zeros: "" }
+ ListElement { text: "Ada" ; zeros: "000" }
+ ListElement { text: "Babbage" ; zeros: "000000" }
+ ListElement { text: "Shannon" ; zeros: "000000000" }
+ ListElement { text: "Szabo" ; zeros: "000000000000" }
+ ListElement { text: "Finney" ; zeros: "000000000000000" }
+ ListElement { text: "Ether" ; zeros: "000000000000000000" }
+ ListElement { text: "Einstein" ;zeros: "000000000000000000000" }
+ ListElement { text: "Douglas" ; zeros: "000000000000000000000000000000000000000000" }
+ }
+
+ ColumnLayout {
+ spacing: 10
+ y: 40
+ anchors.fill: parent
+
+ Text {
+ id: balance
+ text: "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address))
+ font.pixelSize: 24
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ topMargin: 20
+ }
+ }
+
+ Rectangle {
+ id: newTxPane
+ color: "#ececec"
+ border.color: "#cccccc"
+ border.width: 1
+ anchors {
+ top: balance.bottom
+ topMargin: 10
+ left: parent.left
+ leftMargin: 5
+ right: parent.right
+ rightMargin: 5
+ }
+ height: 100
+
+ RowLayout {
+ id: amountFields
+ spacing: 10
+ anchors {
+ top: parent.top
+ topMargin: 20
+ left: parent.left
+ leftMargin: 20
+ }
+
+ Text {
+ text: "Ξ "
+ }
+
+ // There's something off with the row layout where textfields won't listen to the width setting
+ Rectangle {
+ width: 50
+ height: 20
+ TextField {
+ id: txValue
+ width: parent.width
+ placeholderText: "0.00"
+ }
+ }
+
+ ComboBox {
+ id: valueDenom
+ currentIndex: 6
+ model: denomModel
+ }
+
+ }
+
+ RowLayout {
+ id: toFields
+ spacing: 10
+ anchors {
+ top: amountFields.bottom
+ topMargin: 5
+ left: parent.left
+ leftMargin: 20
+ }
+
+ Text {
+ text: "To"
+ }
+
+ Rectangle {
+ width: 200
+ height: 20
+ TextField {
+ id: txTo
+ width: parent.width
+ placeholderText: "Address or name"
+ }
+ }
+
+ Button {
+ text: "Send"
+ onClicked: {
+ var value = txValue.text + denomModel.get(valueDenom.currentIndex).zeros;
+ var gasPrice = "10000000000000"
+ var res = eth.transact({from: eth.key().privateKey, to: txTo.text, value: value, gas: "500", gasPrice: gasPrice})
+ console.log(res)
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: newTxPane.bottom
+ topMargin: 10
+ bottom: parent.bottom
+ }
+ TableView {
+ id: txTableView
+ anchors.fill : parent
+ TableViewColumn{ role: "num" ; title: "#" ; width: 30 }
+ TableViewColumn{ role: "from" ; title: "From" ; width: 280 }
+ TableViewColumn{ role: "to" ; title: "To" ; width: 280 }
+ TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 }
+
+ model: ListModel {
+ id: txModel
+ Component.onCompleted: {
+ var filter = ethx.watch({latest: -1, from: eth.key().address});
+ filter.changed(addTxs)
+
+ addTxs(filter.messages())
+ }
+
+ function addTxs(messages) {
+ for(var i = 0; i < messages.length; i++) {
+ var message = messages.get(i);
+ var to = eth.lookupName(message.to);
+ var from = eth.lookupName(message.from);
+ txModel.insert(0, {num: txModel.count, from: from, to: to, value: eth.numberToHuman(message.value)})
+ }
+ }
+ }
+ }
+ }
+
+ }
+}