You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

527 lines
11 KiB

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1
import Qt.labs.settings 1.0
import org.ethereum.qml.QEther 1.0
import "js/Debugger.js" as Debugger
import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "js/TransactionHelper.js" as TransactionHelper
import "js/QEtherHelper.js" as QEtherHelper
import "."
ColumnLayout {
10 years ago
id: blockChainPanel
property variant model
spacing: 0
property int previousWidth
property variant debugTrRequested: []
signal chainChanged
signal chainReloaded
Connections
{
target: codeModel
onContractRenamed: {
rebuild.startBlinking()
}
onNewContractCompiled: {
rebuild.startBlinking()
}
}
10 years ago
onChainChanged: {
rebuild.startBlinking()
10 years ago
}
onWidthChanged:
{
if (width <= 630 || previousWidth <= 630)
{
10 years ago
fromWidth = 150
10 years ago
toWidth = 100
10 years ago
valueWidth = 200
10 years ago
}
else
{
var diff = (width - previousWidth) / 3;
10 years ago
fromWidth = fromWidth + diff < 150 ? 150 : fromWidth + diff
10 years ago
toWidth = toWidth + diff < 100 ? 100 : toWidth + diff
10 years ago
valueWidth = valueWidth + diff < 200 ? 200 : valueWidth + diff
10 years ago
}
previousWidth = width
}
function load(scenario)
{
if (!scenario)
return;
if (model)
rebuild.startBlinking()
10 years ago
model = scenario
blockModel.clear()
for (var b in model.blocks)
blockModel.append(model.blocks[b])
previousWidth = width
}
10 years ago
property int statusWidth: 30
10 years ago
property int fromWidth: 150
10 years ago
property int toWidth: 100
10 years ago
property int valueWidth: 200
property int logsWidth: 40
property int debugActionWidth: 40
10 years ago
property int horizontalMargin: 10
property int cellSpacing: 10
RowLayout
{
id: header
spacing: 0
10 years ago
Layout.preferredHeight: 30
Rectangle
{
10 years ago
Layout.preferredWidth: statusWidth
Layout.preferredHeight: parent.height
10 years ago
color: "transparent"
Image {
id: debugImage
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
source: "qrc:/qml/img/recycleicon@2x.png"
width: statusWidth + 20
fillMode: Image.PreserveAspectFit
}
10 years ago
}
Rectangle
{
Layout.preferredWidth: fromWidth + cellSpacing
Label
{
anchors.verticalCenter: parent.verticalCenter
text: "From"
anchors.left: parent.left
10 years ago
anchors.leftMargin: horizontalMargin
10 years ago
}
}
Label
{
text: "To"
Layout.preferredWidth: toWidth + cellSpacing
}
Label
{
text: "Value"
Layout.preferredWidth: valueWidth + cellSpacing
}
Label
{
text: "Logs"
Layout.preferredWidth: logsWidth + cellSpacing
}
Label
{
text: ""
Layout.preferredWidth: debugActionWidth
}
}
Rectangle
{
Layout.preferredHeight: 500
Layout.preferredWidth: parent.width
border.color: "#cccccc"
border.width: 2
color: "white"
ScrollView
{
id: blockChainScrollView
anchors.fill: parent
anchors.topMargin: 10
ColumnLayout
{
id: blockChainLayout
width: parent.width
spacing: 10
Block
{
scenario: blockChainPanel.model
Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight: 60
blockIndex: -1
transactions: []
status: ""
number: -2
trHeight: 60
}
10 years ago
Repeater // List of blocks
{
id: blockChainRepeater
model: blockModel
Block
{
scenario: blockChainPanel.model
Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight:
{
return calculateHeight()
}
blockIndex: index
transactions:
{
if (index >= 0)
return blockModel.get(index).transactions
else
return []
}
status:
{
if (index >= 0)
return blockModel.get(index).status
else
return ""
}
number:
{
if (index >= 0)
return blockModel.get(index).number
else
return 0
}
}
}
}
}
}
ListModel
{
id: blockModel
function appendBlock(block)
{
blockModel.append(block);
}
function appendTransaction(tr)
{
blockModel.get(blockModel.count - 1).transactions.append(tr)
}
function removeTransaction(blockIndex, trIndex)
{
blockModel.get(blockIndex).transactions.remove(trIndex)
}
function removeLastBlock()
{
blockModel.remove(blockModel.count - 1)
}
function removeBlock(index)
{
blockModel.remove(index)
}
function getTransaction(block, tr)
{
return blockModel.get(block).transactions.get(tr)
}
function setTransaction(blockIndex, trIndex, tr)
{
blockModel.get(blockIndex).transactions.set(trIndex, tr)
}
function setTransactionProperty(blockIndex, trIndex, propertyName, value)
{
blockModel.get(blockIndex).transactions.set(trIndex, { propertyName: value })
}
}
Rectangle
{
Layout.preferredWidth: parent.width
RowLayout
{
10 years ago
anchors.horizontalCenter: parent.horizontalCenter
10 years ago
anchors.top: parent.top
anchors.topMargin: 10
10 years ago
spacing: 20
Rectangle {
Layout.preferredWidth: 100
Layout.preferredHeight: 30
ScenarioButton {
id: rebuild
text: qsTr("Rebuild")
width: 100
height: 30
roundLeft: true
roundRight: true
onClicked:
10 years ago
{
10 years ago
if (ensureNotFuturetime.running)
return;
stopBlinking()
var retBlocks = [];
var bAdded = 0;
for (var j = 0; j < model.blocks.length; j++)
10 years ago
{
10 years ago
var b = model.blocks[j];
var block = {
hash: b.hash,
number: b.number,
transactions: [],
status: b.status
}
for (var k = 0; k < model.blocks[j].transactions.length; k++)
{
if (blockModel.get(j).transactions.get(k).saveStatus)
{
var tr = model.blocks[j].transactions[k]
tr.saveStatus = true
block.transactions.push(tr);
}
}
if (block.transactions.length > 0)
10 years ago
{
10 years ago
bAdded++
block.number = bAdded
block.status = "mined"
retBlocks.push(block)
10 years ago
}
}
10 years ago
if (retBlocks.length === 0)
retBlocks.push(projectModel.stateListModel.createEmptyBlock())
else
10 years ago
{
10 years ago
var last = retBlocks[retBlocks.length - 1]
last.number = -1
last.status = "pending"
10 years ago
}
10 years ago
model.blocks = retBlocks
blockModel.clear()
for (var j = 0; j < model.blocks.length; j++)
blockModel.append(model.blocks[j])
10 years ago
10 years ago
ensureNotFuturetime.start()
clientModel.setupScenario(model);
}
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycleicon@2x.png"
10 years ago
}
10 years ago
}
10 years ago
Rectangle
{
Layout.preferredWidth: 200
Layout.preferredHeight: 30
color: "transparent"
10 years ago
10 years ago
ScenarioButton {
id: addTransaction
text: qsTr("Add Tx")
onClicked:
10 years ago
{
10 years ago
var lastBlock = model.blocks[model.blocks.length - 1];
if (lastBlock.status === "mined")
{
var newblock = projectModel.stateListModel.createEmptyBlock()
blockModel.appendBlock(newblock)
model.blocks.push(newblock);
}
10 years ago
10 years ago
var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = model.accounts
transactionDialog.execute = true
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png"
roundLeft: true
roundRight: false
10 years ago
}
10 years ago
Timer
{
id: ensureNotFuturetime
interval: 1000
repeat: false
running: false
}
10 years ago
10 years ago
Rectangle
10 years ago
{
10 years ago
width: 1
height: parent.height
anchors.right: addBlockBtn.left
color: "#ededed"
}
ScenarioButton {
id: addBlockBtn
text: qsTr("Add Block..")
anchors.left: addTransaction.right
roundLeft: false
roundRight: true
onClicked:
10 years ago
{
10 years ago
if (ensureNotFuturetime.running)
return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
10 years ago
{
10 years ago
var lastBlock = model.blocks[model.blocks.length - 1]
if (lastBlock.status === "pending")
{
ensureNotFuturetime.start()
clientModel.mine()
}
else
addNewBlock()
10 years ago
}
else
addNewBlock()
10 years ago
10 years ago
}
10 years ago
function addNewBlock()
{
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
}
width: 100
height: 30
10 years ago
10 years ago
buttonShortcut: ""
sourceImg: "qrc:/qml/img/addblock@2x.png"
10 years ago
}
}
10 years ago
10 years ago
Connections
{
target: clientModel
onNewBlock:
{
if (!clientModel.running)
{
var lastBlock = model.blocks[model.blocks.length - 1]
lastBlock.status = "mined"
lastBlock.number = model.blocks.length
var lastB = blockModel.get(model.blocks.length - 1)
lastB.status = "mined"
lastB.number = model.blocks.length
addBlockBtn.addNewBlock()
}
}
onStateCleared:
{
}
onNewRecord:
{
var blockIndex = parseInt(_r.transactionIndex.split(":")[0]) - 1
var trIndex = parseInt(_r.transactionIndex.split(":")[1])
if (blockIndex <= model.blocks.length - 1)
{
var item = model.blocks[blockIndex]
if (trIndex <= item.transactions.length - 1)
{
var tr = item.transactions[trIndex]
tr.returned = _r.returned
tr.recordIndex = _r.recordIndex
tr.logs = _r.logs
tr.sender = _r.sender
var trModel = blockModel.getTransaction(blockIndex, trIndex)
trModel.returned = _r.returned
trModel.recordIndex = _r.recordIndex
trModel.logs = _r.logs
trModel.sender = _r.sender
blockModel.setTransaction(blockIndex, trIndex, trModel)
return;
}
}
// tr is not in the list.
var itemTr = TransactionHelper.defaultTransaction()
itemTr.saveStatus = false
itemTr.functionId = _r.function
itemTr.contractId = _r.contract
itemTr.gasAuto = true
itemTr.parameters = _r.parameters
itemTr.isContractCreation = itemTr.functionId === itemTr.contractId
itemTr.label = _r.label
itemTr.isFunctionCall = itemTr.functionId !== ""
itemTr.returned = _r.returned
itemTr.value = QEtherHelper.createEther(_r.value, QEther.Wei)
itemTr.sender = _r.sender
itemTr.recordIndex = _r.recordIndex
itemTr.logs = _r.logs
model.blocks[model.blocks.length - 1].transactions.push(itemTr)
blockModel.appendTransaction(itemTr)
}
onMiningComplete:
{
}
}
ScenarioButton {
id: newAccount
10 years ago
text: qsTr("New Account..")
10 years ago
onClicked: {
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether))
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/newaccounticon@2x.png"
10 years ago
roundLeft: true
roundRight: true
10 years ago
}
}
}
TransactionDialog {
id: transactionDialog
property bool execute
onAccepted: {
var item = transactionDialog.getItem()
if (execute)
{
var lastBlock = model.blocks[model.blocks.length - 1];
if (lastBlock.status === "mined")
{
var newBlock = projectModel.stateListModel.createEmptyBlock();
model.blocks.push(newBlock);
blockModel.appendBlock(newBlock)
}
if (!clientModel.running)
clientModel.executeTr(item)
}
else {
model.blocks[blockIndex].transactions[transactionIndex] = item
blockModel.setTransaction(blockIndex, transactionIndex, item)
chainChanged()
}
}
}
}