Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
ecc2c609
Commit
ecc2c609
authored
Aug 20, 2014
by
obscuren
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented QML message filtering
parent
a8409b0a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
673 additions
and
464 deletions
+673
-464
filter.js
ethereal/assets/ext/filter.js
+23
-0
wallet.qml
ethereal/assets/qml/views/wallet.qml
+120
-18
wallet.qml
ethereal/assets/qml/wallet.qml
+451
-443
gui.go
ethereal/gui.go
+46
-2
ui_lib.go
ethereal/ui_lib.go
+33
-1
No files found.
ethereal/assets/ext/filter.js
0 → 100644
View file @
ecc2c609
var
Filter
=
function
(
eth
,
options
)
{
this
.
callbacks
=
{};
this
.
seed
=
Math
.
floor
(
Math
.
random
()
*
1000000
);
this
.
eth
=
eth
;
eth
.
registerFilter
(
options
,
this
.
seed
);
};
Filter
.
prototype
.
changed
=
function
(
callback
)
{
var
cbseed
=
Math
.
floor
(
Math
.
random
()
*
1000000
);
this
.
eth
.
registerFilterCallback
(
this
.
seed
,
cbseed
);
var
self
=
this
;
message
.
connect
(
function
(
messages
,
seed
,
callbackSeed
)
{
if
(
seed
==
self
.
seed
&&
callbackSeed
==
cbseed
)
{
callback
.
call
(
self
,
messages
);
}
});
};
Filter
.
prototype
.
uninstall
=
function
()
{
eth
.
uninstallFilter
(
this
.
seed
)
}
ethereal/assets/qml/views/wallet.qml
View file @
ecc2c609
...
@@ -17,43 +17,145 @@ Rectangle {
...
@@ -17,43 +17,145 @@ Rectangle {
function
onReady
()
{
function
onReady
()
{
menuItem
.
secondary
=
eth
.
numberToHuman
(
eth
.
balanceAt
(
eth
.
key
().
address
))
menuItem
.
secondary
=
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
{
ColumnLayout
{
spacing
:
10
spacing
:
10
y
:
40
y
:
40
anchors
{
anchors.fill
:
parent
left
:
parent
.
left
right
:
parent
.
right
}
Text
{
Text
{
id
:
balance
text
:
"<b>Balance</b>: "
+
eth
.
numberToHuman
(
eth
.
balanceAt
(
eth
.
key
().
address
))
text
:
"<b>Balance</b>: "
+
eth
.
numberToHuman
(
eth
.
balanceAt
(
eth
.
key
().
address
))
font.pixelSize
:
24
font.pixelSize
:
24
anchors
{
anchors
{
horizontalCenter
:
parent
.
horizontalCenter
horizontalCenter
:
parent
.
horizontalCenter
top
:
parent
.
top
topMargin
:
20
}
}
}
}
TableView
{
Rectangle
{
id
:
txTableView
id
:
newTxPane
color
:
"#ececec"
border.color
:
"#cccccc"
border.width
:
1
anchors
{
anchors
{
top
:
balance
.
bottom
topMargin
:
10
left
:
parent
.
left
left
:
parent
.
left
leftMargin
:
5
right
:
parent
.
right
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
}
}
}
TableViewColumn
{
role
:
"num"
;
title
:
"#"
;
width
:
30
}
TableViewColumn
{
role
:
"from"
;
title
:
"From"
;
width
:
280
}
RowLayout
{
TableViewColumn
{
role
:
"to"
;
title
:
"To"
;
width
:
280
}
id
:
toFields
TableViewColumn
{
role
:
"value"
;
title
:
"Amount"
;
width
:
100
}
spacing
:
10
anchors
{
model
:
ListModel
{
top
:
amountFields
.
bottom
id
:
txModel
topMargin
:
5
Component.onCompleted
:
{
left
:
parent
.
left
var
messages
=
JSON
.
parse
(
eth
.
messages
({
latest
:
-
1
,
from
:
"e6716f9544a56c530d868e4bfbacb172315bdead"
}))
leftMargin
:
20
for
(
var
i
=
0
;
i
<
messages
.
length
;
i
++
)
{
}
var
message
=
messages
[
i
];
this
.
insert
(
0
,
{
num
:
i
,
from
:
message
.
from
,
to
:
message
.
to
,
value
:
eth
.
numberToHuman
(
message
.
value
)})
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
(
eth
.
key
().
privateKey
,
txTo
.
text
,
value
,
"500"
,
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
messages
=
JSON
.
parse
(
eth
.
messages
({
latest
:
-
1
,
from
:
"e6716f9544a56c530d868e4bfbacb172315bdead"
}))
for
(
var
i
=
0
;
i
<
messages
.
length
;
i
++
)
{
var
message
=
messages
[
i
];
this
.
insert
(
0
,
{
num
:
i
,
from
:
message
.
from
,
to
:
message
.
to
,
value
:
eth
.
numberToHuman
(
message
.
value
)})
}
}
}
}
}
}
}
...
...
ethereal/assets/qml/wallet.qml
View file @
ecc2c609
...
@@ -6,17 +6,28 @@ import QtQuick.Window 2.1;
...
@@ -6,17 +6,28 @@ import QtQuick.Window 2.1;
import
QtQuick
.
Controls
.
Styles
1.1
import
QtQuick
.
Controls
.
Styles
1.1
import
Ethereum
1.0
import
Ethereum
1.0
import
"../ext/filter.js"
as
Eth
ApplicationWindow
{
ApplicationWindow
{
id
:
root
id
:
root
property
alias
miningButtonText
:
miningButton
.
text
property
alias
miningButtonText
:
miningButton
.
text
width
:
900
width
:
900
height
:
600
height
:
600
minimumHeight
:
300
minimumHeight
:
300
title
:
"Ethereal"
title
:
"Ether browser"
// This signal is used by the filter API. The filter API connects using this signal handler from
// the different QML files and plugins.
signal
message
(
var
callback
,
int
seed
,
int
seedCallback
);
function
invokeFilterCallback
(
data
,
receiverSeed
,
callbackSeed
)
{
var
messages
=
JSON
.
parse
(
data
)
// Signal handler
message
(
data
,
receiverSeed
,
callbackSeed
);
}
TextField
{
TextField
{
id
:
copyElementHax
id
:
copyElementHax
...
@@ -31,17 +42,17 @@ ApplicationWindow {
...
@@ -31,17 +42,17 @@ ApplicationWindow {
// Takes care of loading all default plugins
// Takes care of loading all default plugins
Component.onCompleted
:
{
Component.onCompleted
:
{
var
walletView
=
addPlugin
(
"./views/wallet.qml"
,
{
section
:
"ethereum"
})
var
walletView
=
addPlugin
(
"./views/wallet.qml"
,
{
noAdd
:
true
,
section
:
"ethereum"
,
active
:
true
})
var
historyView
=
addPlugin
(
"./views/history.qml"
,
{
noAdd
:
true
,
section
:
"legacy"
})
var
historyView
=
addPlugin
(
"./views/history.qml"
,
{
section
:
"legacy"
})
var
newTxView
=
addPlugin
(
"./views/transaction.qml"
,
{
noAdd
:
true
,
section
:
"legacy"
})
var
newTxView
=
addPlugin
(
"./views/transaction.qml"
,
{
section
:
"legacy"
})
var
chainView
=
addPlugin
(
"./views/chain.qml"
,
{
noAdd
:
true
,
section
:
"legacy"
})
var
chainView
=
addPlugin
(
"./views/chain.qml"
,
{
section
:
"legacy"
})
var
infoView
=
addPlugin
(
"./views/info.qml"
,
{
noAdd
:
true
,
section
:
"legacy"
})
var
infoView
=
addPlugin
(
"./views/info.qml"
,
{
section
:
"legacy"
})
var
pendingTxView
=
addPlugin
(
"./views/pending_tx.qml"
,
{
noAdd
:
true
,
section
:
"legacy"
})
var
pendingTxView
=
addPlugin
(
"./views/pending_tx.qml"
,
{
section
:
"legacy"
})
var
pendingTxView
=
addPlugin
(
"./views/javascript.qml"
,
{
noAdd
:
true
,
section
:
"legacy"
})
var
pendingTxView
=
addPlugin
(
"./views/javascript.qml"
,
{
section
:
"legacy"
})
// Call the ready handler
// Call the ready handler
gui
.
done
()
gui
.
done
()
}
}
function
addPlugin
(
path
,
options
)
{
function
addPlugin
(
path
,
options
)
{
...
@@ -50,10 +61,20 @@ ApplicationWindow {
...
@@ -50,10 +61,20 @@ ApplicationWindow {
if
(
component
.
status
==
Component
.
Error
)
{
if
(
component
.
status
==
Component
.
Error
)
{
console
.
debug
(
"Error:"
+
component
.
errorString
());
console
.
debug
(
"Error:"
+
component
.
errorString
());
}
}
return
return
}
}
return
mainSplit
.
addComponent
(
component
,
options
)
var
views
=
mainSplit
.
addComponent
(
component
,
options
)
views
.
menuItem
.
path
=
path
mainSplit
.
views
.
push
(
views
);
if
(
!
options
.
noAdd
)
{
gui
.
addPlugin
(
path
)
}
return
views
.
view
}
}
MenuBar
{
MenuBar
{
...
@@ -76,7 +97,7 @@ ApplicationWindow {
...
@@ -76,7 +97,7 @@ ApplicationWindow {
text
:
"Add plugin"
text
:
"Add plugin"
onTriggered
:
{
onTriggered
:
{
generalFileDialog
.
show
(
true
,
function
(
path
)
{
generalFileDialog
.
show
(
true
,
function
(
path
)
{
addPlugin
(
path
,
{
canClose
:
true
})
addPlugin
(
path
,
{
canClose
:
true
,
section
:
"apps"
})
})
})
}
}
}
}
...
@@ -268,454 +289,441 @@ ApplicationWindow {
...
@@ -268,454 +289,441 @@ ApplicationWindow {
function
addComponent
(
component
,
options
)
{
function
addComponent
(
component
,
options
)
{
var
view
=
mainView
.
createView
(
component
,
options
)
var
view
=
mainView
.
createView
(
component
,
options
)
view
.
visible
=
false
view
.
anchors
.
fill
=
mainView
if
(
!
view
.
hasOwnProperty
(
"iconFile"
)
)
{
if
(
!
view
.
hasOwnProperty
(
"iconFile"
)
)
{
console
.
log
(
"Could not load plugin. Property 'iconFile' not found on view."
);
console
.
log
(
"Could not load plugin. Property 'iconFile' not found on view."
);
return
;
return
;
}
}
var
menuItem
=
menu
.
createMenuItem
(
view
.
iconFile
,
view
,
options
);
var
menuItem
=
menu
.
createMenuItem
(
view
.
iconFile
,
view
,
options
);
if
(
view
.
hasOwnProperty
(
"menuItem"
)
)
{
if
(
view
.
hasOwnProperty
(
"menuItem"
)
)
{
view
.
menuItem
=
menuItem
;
view
.
menuItem
=
menuItem
;
}
}
mainSplit
.
views
.
push
({
view
:
view
,
menuItem
:
menuItem
});
if
(
view
.
hasOwnProperty
(
"onReady"
)
)
{
if
(
view
.
hasOwnProperty
(
"onReady"
)
)
{
view
.
onReady
.
call
(
view
)
view
.
onReady
.
call
(
view
)
}
}
return
view
if
(
options
.
active
)
{
}
setView
(
view
,
menuItem
)
/*********************
* Main menu.
********************/
Rectangle
{
id
:
menu
Layout.minimumWidth
:
180
Layout.maximumWidth
:
180
anchors.top
:
parent
.
top
color
:
"#ececec"
Component
{
id
:
menuItemTemplate
Rectangle
{
id
:
menuItem
property
var
view
;
property
alias
title
:
label
.
text
property
alias
icon
:
icon
.
source
property
alias
secondary
:
secondary
.
text
width
:
180
height
:
28
border.color
:
"#00000000"
border.width
:
1
radius
:
5
color
:
"#00000000"
anchors
{
left
:
parent
.
left
leftMargin
:
4
}
Image
{
id
:
icon
height
:
20
width
:
20
anchors
{
left
:
parent
.
left
verticalCenter
:
parent
.
verticalCenter
leftMargin
:
3
}
}
Text
{
id
:
label
anchors
{
left
:
icon
.
right
verticalCenter
:
parent
.
verticalCenter
leftMargin
:
3
}
//font.bold: true
color
:
"#0D0A01"
font.pixelSize
:
12
}
Text
{
id
:
secondary
anchors
{
right
:
parent
.
right
rightMargin
:
8
verticalCenter
:
parent
.
verticalCenter
}
color
:
"#AEADBE"
font.pixelSize
:
12
}
MouseArea
{
anchors.fill
:
parent
onClicked
:
{
mainSplit
.
setView
(
view
,
menuItem
)
}
}
}
}
}
function
createMenuItem
(
icon
,
view
,
options
)
{
if
(
options
===
undefined
)
{
options
=
{};
}
var
section
;
switch
(
options
.
section
)
{
case
"ethereum"
:
section
=
menuDefault
;
break
;
case
"legacy"
:
section
=
menuLegacy
;
break
;
default
:
section
=
menuApps
;
break
;
}
var
comp
=
menuItemTemplate
.
createObject
(
section
)
comp
.
view
=
view
comp
.
title
=
view
.
title
comp
.
icon
=
view
.
iconFile
/*
if(view.secondary !== undefined) {
comp.secondary = view.secondary
}
*/
return
comp
/*
if(options.canClose) {
//comp.closeButton.visible = options.canClose
}
*/
}
ColumnLayout
{
return
{
view
:
view
,
menuItem
:
menuItem
}
id
:
menuColumn
y
:
10
width
:
parent
.
width
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
spacing
:
3
Text
{
text
:
"ETHEREUM"
font.bold
:
true
anchors
{
left
:
parent
.
left
leftMargin
:
5
}
color
:
"#888888"
}
ColumnLayout
{
id
:
menuDefault
spacing
:
3
anchors
{
left
:
parent
.
left
right
:
parent
.
right
}
}
Text
{
text
:
"LEGACY"
font.bold
:
true
anchors
{
left
:
parent
.
left
leftMargin
:
5
}
color
:
"#888888"
}
ColumnLayout
{
id
:
menuLegacy
spacing
:
3
anchors
{
left
:
parent
.
left
right
:
parent
.
right
}
}
Text
{
text
:
"APPS"
font.bold
:
true
anchors
{
left
:
parent
.
left
leftMargin
:
5
}
color
:
"#888888"
}
/*
Rectangle {
width: 180
height: 28
border.color: "#CCCCCC"
border.width: 1
radius: 5
color: "#FFFFFF"
anchors {
left: parent.left
leftMargin: 4
}
Image {
id: icon
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
source: "../pick.png"
}
Text {
anchors {
left: icon.right
verticalCenter: parent.verticalCenter
}
text: "Wallet"
font.bold: true
color: "#0D0A01"
}
Text {
anchors {
right: parent.right
rightMargin: 8
verticalCenter: parent.verticalCenter
}
color: "#AEADBE"
text: "12e15 Ξ"
font.pixelSize: 12
}
}
*/
}
}
}
/*********************
/*********************
* Main
view
* Main
menu.
********************/
********************/
Rectangle
{
Rectangle
{
id
:
mainView
id
:
menu
color
:
"#00000000"
Layout.minimumWidth
:
180
Layout.maximumWidth
:
180
anchors.right
:
parent
.
right
anchors.top
:
parent
.
top
anchors.left
:
menu
.
right
color
:
"#ececec"
anchors.bottom
:
parent
.
bottom
anchors.top
:
parent
.
top
Component
{
id
:
menuItemTemplate
function
createView
(
component
)
{
Rectangle
{
var
view
=
component
.
createObject
(
mainView
)
id
:
menuItem
property
var
view
;
return
view
;
property
var
path
;
}
}
property
alias
title
:
label
.
text
property
alias
icon
:
icon
.
source
property
alias
secondary
:
secondary
.
text
}
width
:
180
height
:
28
/******************
border.color
:
"#00000000"
* Dialogs
border.width
:
1
*****************/
radius
:
5
FileDialog
{
color
:
"#00000000"
id
:
generalFileDialog
property
var
callback
;
anchors
{
onAccepted
:
{
left
:
parent
.
left
var
path
=
this
.
fileUrl
.
toString
();
leftMargin
:
4
callback
.
call
(
this
,
path
);
}
}
MouseArea
{
function
show
(
selectExisting
,
callback
)
{
anchors.fill
:
parent
generalFileDialog
.
callback
=
callback
;
onClicked
:
{
generalFileDialog
.
selectExisting
=
selectExisting
;
mainSplit
.
setView
(
view
,
menuItem
)
}
this
.
open
();
}
}
}
Image
{
id
:
icon
height
:
20
/******************
width
:
20
* Wallet functions
anchors
{
*****************/
left
:
parent
.
left
function
importApp
(
path
)
{
verticalCenter
:
parent
.
verticalCenter
var
ext
=
path
.
split
(
'.'
).
pop
()
leftMargin
:
3
if
(
ext
==
"html"
||
ext
==
"htm"
)
{
}
eth
.
openHtml
(
path
)
MouseArea
{
}
else
if
(
ext
==
"qml"
){
anchors.fill
:
parent
eth
.
openQml
(
path
)
onClicked
:
{
}
menuItem
.
closeApp
()
}
}
}
function
setWalletValue
(
value
)
{
}
walletValueLabel
.
text
=
value
}
Text
{
id
:
label
function
loadPlugin
(
name
)
{
anchors
{
console
.
log
(
"Loading plugin"
+
name
)
left
:
icon
.
right
mainView
.
addPlugin
(
name
)
verticalCenter
:
parent
.
verticalCenter
}
leftMargin
:
3
}
function
setPeers
(
text
)
{
peerLabel
.
text
=
text
color
:
"#0D0A01"
}
font.pixelSize
:
12
}
function
addPeer
(
peer
)
{
// We could just append the whole peer object but it cries if you try to alter them
Text
{
peerModel
.
append
({
ip
:
peer
.
ip
,
port
:
peer
.
port
,
lastResponse
:
timeAgo
(
peer
.
lastSend
),
latency
:
peer
.
latency
,
version
:
peer
.
version
})
id
:
secondary
}
anchors
{
right
:
parent
.
right
function
resetPeers
(){
rightMargin
:
8
peerModel
.
clear
()
verticalCenter
:
parent
.
verticalCenter
}
}
color
:
"#AEADBE"
function
timeAgo
(
unixTs
){
font.pixelSize
:
12
var
lapsed
=
(
Date
.
now
()
-
new
Date
(
unixTs
*
1000
))
/
1000
}
return
(
lapsed
+
" seconds ago"
)
}
function
closeApp
()
{
function
convertToPretty
(
unixTs
){
if
(
this
.
view
.
hasOwnProperty
(
"onDestroy"
))
{
var
a
=
new
Date
(
unixTs
*
1000
);
this
.
view
.
onDestroy
.
call
(
this
.
view
)
var
months
=
[
'Jan'
,
'Feb'
,
'Mar'
,
'Apr'
,
'May'
,
'Jun'
,
'Jul'
,
'Aug'
,
'Sep'
,
'Oct'
,
'Nov'
,
'Dec'
];
}
var
year
=
a
.
getFullYear
();
var
month
=
months
[
a
.
getMonth
()];
this
.
view
.
destroy
()
var
date
=
a
.
getDate
();
this
.
destroy
()
var
hour
=
a
.
getHours
();
gui
.
removePlugin
(
this
.
path
)
var
min
=
a
.
getMinutes
();
}
var
sec
=
a
.
getSeconds
();
}
var
time
=
date
+
' '
+
month
+
' '
+
year
+
' '
+
hour
+
':'
+
min
+
':'
+
sec
;
}
return
time
;
}
function
createMenuItem
(
icon
,
view
,
options
)
{
if
(
options
===
undefined
)
{
/**********************
options
=
{};
* Windows
}
*********************/
Window
{
var
section
;
id
:
peerWindow
switch
(
options
.
section
)
{
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
case
"ethereum"
:
height
:
200
section
=
menuDefault
;
width
:
700
break
;
Rectangle
{
case
"legacy"
:
anchors.fill
:
parent
section
=
menuLegacy
;
property
var
peerModel
:
ListModel
{
break
;
id
:
peerModel
default
:
}
section
=
menuApps
;
TableView
{
break
;
anchors.fill
:
parent
}
id
:
peerTable
model
:
peerModel
var
comp
=
menuItemTemplate
.
createObject
(
section
)
TableViewColumn
{
width
:
100
;
role
:
"ip"
;
title
:
"IP"
}
TableViewColumn
{
width
:
60
;
role
:
"port"
;
title
:
"Port"
}
comp
.
view
=
view
TableViewColumn
{
width
:
140
;
role
:
"lastResponse"
;
title
:
"Last event"
}
comp
.
title
=
view
.
title
TableViewColumn
{
width
:
100
;
role
:
"latency"
;
title
:
"Latency"
}
comp
.
icon
=
view
.
iconFile
TableViewColumn
{
width
:
260
;
role
:
"version"
;
title
:
"Version"
}
/*
}
if(view.secondary !== undefined) {
}
comp.secondary = view.secondary
}
}
*/
Window
{
id
:
aboutWin
return
comp
visible
:
false
title
:
"About"
/*
minimumWidth
:
350
if(options.canClose) {
maximumWidth
:
350
//comp.closeButton.visible = options.canClose
maximumHeight
:
200
}
minimumHeight
:
200
*/
}
Image
{
id
:
aboutIcon
ColumnLayout
{
height
:
150
id
:
menuColumn
width
:
150
y
:
10
fillMode
:
Image
.
PreserveAspectFit
width
:
parent
.
width
smooth
:
true
anchors.left
:
parent
.
left
source
:
"../facet.png"
anchors.right
:
parent
.
right
x
:
10
spacing
:
3
y
:
10
}
Text
{
text
:
"ETHEREUM"
Text
{
font.bold
:
true
anchors.left
:
aboutIcon
.
right
anchors
{
anchors.leftMargin
:
10
left
:
parent
.
left
font.pointSize
:
12
leftMargin
:
5
text
:
"<h2>Ethereal - Adrastea</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>"
}
}
color
:
"#888888"
}
}
Window
{
ColumnLayout
{
id
:
txImportDialog
id
:
menuDefault
minimumWidth
:
270
spacing
:
3
maximumWidth
:
270
anchors
{
maximumHeight
:
50
left
:
parent
.
left
minimumHeight
:
50
right
:
parent
.
right
TextField
{
}
id
:
txImportField
}
width
:
170
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
Text
{
anchors.leftMargin
:
10
text
:
"APPS"
onAccepted
:
{
font.bold
:
true
}
anchors
{
}
left
:
parent
.
left
Button
{
leftMargin
:
5
anchors.left
:
txImportField
.
right
}
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
"#888888"
anchors.leftMargin
:
5
}
text
:
"Import"
onClicked
:
{
ColumnLayout
{
eth
.
importTx
(
txImportField
.
text
)
id
:
menuApps
txImportField
.
visible
=
false
spacing
:
3
}
anchors
{
}
left
:
parent
.
left
Component.onCompleted
:
{
right
:
parent
.
right
addrField
.
focus
=
true
}
}
}
}
Text
{
Window
{
text
:
"DEBUG"
id
:
addPeerWin
font.bold
:
true
visible
:
false
anchors
{
minimumWidth
:
230
left
:
parent
.
left
maximumWidth
:
230
leftMargin
:
5
maximumHeight
:
50
}
minimumHeight
:
50
color
:
"#888888"
}
TextField
{
id
:
addrField
ColumnLayout
{
anchors.verticalCenter
:
parent
.
verticalCenter
id
:
menuLegacy
anchors.left
:
parent
.
left
spacing
:
3
anchors.leftMargin
:
10
anchors
{
placeholderText
:
"address:port"
left
:
parent
.
left
onAccepted
:
{
right
:
parent
.
right
eth
.
connectToPeer
(
addrField
.
text
)
}
addPeerWin
.
visible
=
false
}
}
}
}
}
Button
{
anchors.left
:
addrField
.
right
/*********************
anchors.verticalCenter
:
parent
.
verticalCenter
* Main view
anchors.leftMargin
:
5
********************/
text
:
"Add"
Rectangle
{
onClicked
:
{
id
:
mainView
eth
.
connectToPeer
(
addrField
.
text
)
color
:
"#00000000"
addPeerWin
.
visible
=
false
}
anchors.right
:
parent
.
right
}
anchors.left
:
menu
.
right
Component.onCompleted
:
{
anchors.bottom
:
parent
.
bottom
addrField
.
focus
=
true
anchors.top
:
parent
.
top
}
}
function
createView
(
component
)
{
}
var
view
=
component
.
createObject
(
mainView
)
return
view
;
}
}
}
/******************
* Dialogs
*****************/
FileDialog
{
id
:
generalFileDialog
property
var
callback
;
onAccepted
:
{
var
path
=
this
.
fileUrl
.
toString
();
callback
.
call
(
this
,
path
);
}
function
show
(
selectExisting
,
callback
)
{
generalFileDialog
.
callback
=
callback
;
generalFileDialog
.
selectExisting
=
selectExisting
;
this
.
open
();
}
}
/******************
* Wallet functions
*****************/
function
importApp
(
path
)
{
var
ext
=
path
.
split
(
'.'
).
pop
()
if
(
ext
==
"html"
||
ext
==
"htm"
)
{
eth
.
openHtml
(
path
)
}
else
if
(
ext
==
"qml"
){
addPlugin
(
path
,
{
canClose
:
true
,
section
:
"apps"
})
}
}
function
setWalletValue
(
value
)
{
walletValueLabel
.
text
=
value
}
function
loadPlugin
(
name
)
{
console
.
log
(
"Loading plugin"
+
name
)
var
view
=
mainView
.
addPlugin
(
name
)
}
function
setPeers
(
text
)
{
peerLabel
.
text
=
text
}
function
addPeer
(
peer
)
{
// We could just append the whole peer object but it cries if you try to alter them
peerModel
.
append
({
ip
:
peer
.
ip
,
port
:
peer
.
port
,
lastResponse
:
timeAgo
(
peer
.
lastSend
),
latency
:
peer
.
latency
,
version
:
peer
.
version
})
}
function
resetPeers
(){
peerModel
.
clear
()
}
function
timeAgo
(
unixTs
){
var
lapsed
=
(
Date
.
now
()
-
new
Date
(
unixTs
*
1000
))
/
1000
return
(
lapsed
+
" seconds ago"
)
}
function
convertToPretty
(
unixTs
){
var
a
=
new
Date
(
unixTs
*
1000
);
var
months
=
[
'Jan'
,
'Feb'
,
'Mar'
,
'Apr'
,
'May'
,
'Jun'
,
'Jul'
,
'Aug'
,
'Sep'
,
'Oct'
,
'Nov'
,
'Dec'
];
var
year
=
a
.
getFullYear
();
var
month
=
months
[
a
.
getMonth
()];
var
date
=
a
.
getDate
();
var
hour
=
a
.
getHours
();
var
min
=
a
.
getMinutes
();
var
sec
=
a
.
getSeconds
();
var
time
=
date
+
' '
+
month
+
' '
+
year
+
' '
+
hour
+
':'
+
min
+
':'
+
sec
;
return
time
;
}
/**********************
* Windows
*********************/
Window
{
id
:
peerWindow
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
height
:
200
width
:
700
Rectangle
{
anchors.fill
:
parent
property
var
peerModel
:
ListModel
{
id
:
peerModel
}
TableView
{
anchors.fill
:
parent
id
:
peerTable
model
:
peerModel
TableViewColumn
{
width
:
100
;
role
:
"ip"
;
title
:
"IP"
}
TableViewColumn
{
width
:
60
;
role
:
"port"
;
title
:
"Port"
}
TableViewColumn
{
width
:
140
;
role
:
"lastResponse"
;
title
:
"Last event"
}
TableViewColumn
{
width
:
100
;
role
:
"latency"
;
title
:
"Latency"
}
TableViewColumn
{
width
:
260
;
role
:
"version"
;
title
:
"Version"
}
}
}
}
Window
{
id
:
aboutWin
visible
:
false
title
:
"About"
minimumWidth
:
350
maximumWidth
:
350
maximumHeight
:
200
minimumHeight
:
200
Image
{
id
:
aboutIcon
height
:
150
width
:
150
fillMode
:
Image
.
PreserveAspectFit
smooth
:
true
source
:
"../facet.png"
x
:
10
y
:
10
}
Text
{
anchors.left
:
aboutIcon
.
right
anchors.leftMargin
:
10
font.pointSize
:
12
text
:
"<h2>Ethereal - Adrastea</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>"
}
}
Window
{
id
:
txImportDialog
minimumWidth
:
270
maximumWidth
:
270
maximumHeight
:
50
minimumHeight
:
50
TextField
{
id
:
txImportField
width
:
170
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
10
onAccepted
:
{
}
}
Button
{
anchors.left
:
txImportField
.
right
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.leftMargin
:
5
text
:
"Import"
onClicked
:
{
eth
.
importTx
(
txImportField
.
text
)
txImportField
.
visible
=
false
}
}
Component.onCompleted
:
{
addrField
.
focus
=
true
}
}
Window
{
id
:
addPeerWin
visible
:
false
minimumWidth
:
230
maximumWidth
:
230
maximumHeight
:
50
minimumHeight
:
50
TextField
{
id
:
addrField
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
10
placeholderText
:
"address:port"
onAccepted
:
{
eth
.
connectToPeer
(
addrField
.
text
)
addPeerWin
.
visible
=
false
}
}
Button
{
anchors.left
:
addrField
.
right
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.leftMargin
:
5
text
:
"Add"
onClicked
:
{
eth
.
connectToPeer
(
addrField
.
text
)
addPeerWin
.
visible
=
false
}
}
Component.onCompleted
:
{
addrField
.
focus
=
true
}
}
}
ethereal/gui.go
View file @
ecc2c609
...
@@ -2,6 +2,7 @@ package main
...
@@ -2,6 +2,7 @@ package main
import
(
import
(
"bytes"
"bytes"
"encoding/json"
"fmt"
"fmt"
"math/big"
"math/big"
"os"
"os"
...
@@ -24,6 +25,11 @@ import (
...
@@ -24,6 +25,11 @@ import (
var
logger
=
ethlog
.
NewLogger
(
"GUI"
)
var
logger
=
ethlog
.
NewLogger
(
"GUI"
)
type
plugin
struct
{
Name
string
`json:"name"`
Path
string
`json:"path"`
}
type
Gui
struct
{
type
Gui
struct
{
// The main application window
// The main application window
win
*
qml
.
Window
win
*
qml
.
Window
...
@@ -48,6 +54,8 @@ type Gui struct {
...
@@ -48,6 +54,8 @@ type Gui struct {
clientIdentity
*
ethwire
.
SimpleClientIdentity
clientIdentity
*
ethwire
.
SimpleClientIdentity
config
*
ethutil
.
ConfigManager
config
*
ethutil
.
ConfigManager
plugins
map
[
string
]
plugin
miner
*
ethminer
.
Miner
miner
*
ethminer
.
Miner
}
}
...
@@ -59,8 +67,16 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden
...
@@ -59,8 +67,16 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden
}
}
pipe
:=
ethpipe
.
NewJSPipe
(
ethereum
)
pipe
:=
ethpipe
.
NewJSPipe
(
ethereum
)
gui
:=
&
Gui
{
eth
:
ethereum
,
txDb
:
db
,
pipe
:
pipe
,
logLevel
:
ethlog
.
LogLevel
(
logLevel
),
Session
:
session
,
open
:
false
,
clientIdentity
:
clientIdentity
,
config
:
config
,
plugins
:
make
(
map
[
string
]
plugin
)}
data
,
err
:=
ethutil
.
ReadAllFile
(
ethutil
.
Config
.
ExecPath
+
"/plugins.json"
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
}
fmt
.
Println
(
string
(
data
))
return
&
Gui
{
eth
:
ethereum
,
txDb
:
db
,
pipe
:
pipe
,
logLevel
:
ethlog
.
LogLevel
(
logLevel
),
Session
:
session
,
open
:
false
,
clientIdentity
:
clientIdentity
,
config
:
config
}
json
.
Unmarshal
([]
byte
(
data
),
&
gui
.
plugins
)
return
gui
}
}
func
(
gui
*
Gui
)
Start
(
assetPath
string
)
{
func
(
gui
*
Gui
)
Start
(
assetPath
string
)
{
...
@@ -193,6 +209,7 @@ func (self *Gui) DumpState(hash, path string) {
...
@@ -193,6 +209,7 @@ func (self *Gui) DumpState(hash, path string) {
// The done handler will be called by QML when all views have been loaded
// The done handler will be called by QML when all views have been loaded
func
(
gui
*
Gui
)
Done
()
{
func
(
gui
*
Gui
)
Done
()
{
gui
.
qmlDone
=
true
gui
.
qmlDone
=
true
}
}
func
(
gui
*
Gui
)
ImportKey
(
filePath
string
)
{
func
(
gui
*
Gui
)
ImportKey
(
filePath
string
)
{
...
@@ -375,6 +392,10 @@ func (gui *Gui) update() {
...
@@ -375,6 +392,10 @@ func (gui *Gui) update() {
gui
.
readPreviousTransactions
()
gui
.
readPreviousTransactions
()
}()
}()
for
_
,
plugin
:=
range
gui
.
plugins
{
gui
.
win
.
Root
()
.
Call
(
"addPlugin"
,
plugin
.
Path
,
""
)
}
var
(
var
(
blockChan
=
make
(
chan
ethreact
.
Event
,
100
)
blockChan
=
make
(
chan
ethreact
.
Event
,
100
)
txChan
=
make
(
chan
ethreact
.
Event
,
100
)
txChan
=
make
(
chan
ethreact
.
Event
,
100
)
...
@@ -504,7 +525,16 @@ func (gui *Gui) address() []byte {
...
@@ -504,7 +525,16 @@ func (gui *Gui) address() []byte {
}
}
func
(
gui
*
Gui
)
Transact
(
recipient
,
value
,
gas
,
gasPrice
,
d
string
)
(
*
ethpipe
.
JSReceipt
,
error
)
{
func
(
gui
*
Gui
)
Transact
(
recipient
,
value
,
gas
,
gasPrice
,
d
string
)
(
*
ethpipe
.
JSReceipt
,
error
)
{
data
:=
ethutil
.
Bytes2Hex
(
utils
.
FormatTransactionData
(
d
))
var
data
string
if
len
(
recipient
)
==
0
{
code
,
err
:=
ethutil
.
Compile
(
d
,
false
)
if
err
!=
nil
{
return
nil
,
err
}
data
=
ethutil
.
Bytes2Hex
(
code
)
}
else
{
data
=
ethutil
.
Bytes2Hex
(
utils
.
FormatTransactionData
(
d
))
}
return
gui
.
pipe
.
Transact
(
gui
.
privateKey
(),
recipient
,
value
,
gas
,
gasPrice
,
data
)
return
gui
.
pipe
.
Transact
(
gui
.
privateKey
(),
recipient
,
value
,
gas
,
gasPrice
,
data
)
}
}
...
@@ -528,6 +558,20 @@ func (gui *Gui) GetLogLevel() ethlog.LogLevel {
...
@@ -528,6 +558,20 @@ func (gui *Gui) GetLogLevel() ethlog.LogLevel {
return
gui
.
logLevel
return
gui
.
logLevel
}
}
func
(
self
*
Gui
)
AddPlugin
(
pluginPath
string
)
{
self
.
plugins
[
pluginPath
]
=
plugin
{
Name
:
"SomeName"
,
Path
:
pluginPath
}
json
,
_
:=
json
.
MarshalIndent
(
self
.
plugins
,
""
,
" "
)
ethutil
.
WriteFile
(
ethutil
.
Config
.
ExecPath
+
"/plugins.json"
,
json
)
}
func
(
self
*
Gui
)
RemovePlugin
(
pluginPath
string
)
{
delete
(
self
.
plugins
,
pluginPath
)
json
,
_
:=
json
.
MarshalIndent
(
self
.
plugins
,
""
,
" "
)
ethutil
.
WriteFile
(
ethutil
.
Config
.
ExecPath
+
"/plugins.json"
,
json
)
}
// this extra function needed to give int typecast value to gui widget
// this extra function needed to give int typecast value to gui widget
// that sets initial loglevel to default
// that sets initial loglevel to default
func
(
gui
*
Gui
)
GetLogLevelInt
()
int
{
func
(
gui
*
Gui
)
GetLogLevelInt
()
int
{
...
...
ethereal/ui_lib.go
View file @
ecc2c609
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethcrypto"
"github.com/ethereum/eth-go/ethpipe"
"github.com/ethereum/eth-go/ethpipe"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/javascript"
"gopkg.in/qml.v1"
"gopkg.in/qml.v1"
...
@@ -34,10 +35,13 @@ type UiLib struct {
...
@@ -34,10 +35,13 @@ type UiLib struct {
DbWindow
*
DebuggerWindow
DbWindow
*
DebuggerWindow
jsEngine
*
javascript
.
JSRE
jsEngine
*
javascript
.
JSRE
filterCallbacks
map
[
int
][]
int
filters
map
[
int
]
*
GuiFilter
}
}
func
NewUiLib
(
engine
*
qml
.
Engine
,
eth
*
eth
.
Ethereum
,
assetPath
string
)
*
UiLib
{
func
NewUiLib
(
engine
*
qml
.
Engine
,
eth
*
eth
.
Ethereum
,
assetPath
string
)
*
UiLib
{
return
&
UiLib
{
JSPipe
:
ethpipe
.
NewJSPipe
(
eth
),
engine
:
engine
,
eth
:
eth
,
assetPath
:
assetPath
,
jsEngine
:
javascript
.
NewJSRE
(
eth
)}
return
&
UiLib
{
JSPipe
:
ethpipe
.
NewJSPipe
(
eth
),
engine
:
engine
,
eth
:
eth
,
assetPath
:
assetPath
,
jsEngine
:
javascript
.
NewJSRE
(
eth
)
,
filterCallbacks
:
make
(
map
[
int
][]
int
),
filters
:
make
(
map
[
int
]
*
GuiFilter
)
}
}
}
func
(
self
*
UiLib
)
LookupDomain
(
domain
string
)
string
{
func
(
self
*
UiLib
)
LookupDomain
(
domain
string
)
string
{
...
@@ -155,3 +159,31 @@ func (self *UiLib) StartDebugger() {
...
@@ -155,3 +159,31 @@ func (self *UiLib) StartDebugger() {
dbWindow
.
Show
()
dbWindow
.
Show
()
}
}
func
(
self
*
UiLib
)
RegisterFilter
(
object
map
[
string
]
interface
{},
seed
int
)
{
filter
:=
&
GuiFilter
{
ethpipe
.
NewJSFilterFromMap
(
object
,
self
.
eth
),
seed
}
self
.
filters
[
seed
]
=
filter
filter
.
MessageCallback
=
func
(
messages
ethstate
.
Messages
)
{
for
_
,
callbackSeed
:=
range
self
.
filterCallbacks
[
seed
]
{
self
.
win
.
Root
()
.
Call
(
"invokeFilterCallback"
,
filter
.
MessagesToJson
(
messages
),
seed
,
callbackSeed
)
}
}
}
func
(
self
*
UiLib
)
RegisterFilterCallback
(
seed
,
cbSeed
int
)
{
self
.
filterCallbacks
[
seed
]
=
append
(
self
.
filterCallbacks
[
seed
],
cbSeed
)
}
func
(
self
*
UiLib
)
UninstallFilter
(
seed
int
)
{
filter
:=
self
.
filters
[
seed
]
if
filter
!=
nil
{
filter
.
Uninstall
()
delete
(
self
.
filters
,
seed
)
}
}
type
GuiFilter
struct
{
*
ethpipe
.
JSFilter
seed
int
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment