|
|
@ -18,15 +18,27 @@ ColumnLayout { |
|
|
|
property int previousWidth |
|
|
|
property variant debugTrRequested: [] |
|
|
|
signal chainChanged |
|
|
|
signal chainReloaded |
|
|
|
|
|
|
|
Connections |
|
|
|
{ |
|
|
|
target: codeModel |
|
|
|
onContractRenamed: { |
|
|
|
rebuild.startBlinking() |
|
|
|
} |
|
|
|
onNewContractCompiled: { |
|
|
|
rebuild.startBlinking() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
onChainChanged: { |
|
|
|
reBuildNeeded.start() |
|
|
|
rebuild.startBlinking() |
|
|
|
} |
|
|
|
|
|
|
|
onWidthChanged: |
|
|
|
{ |
|
|
|
|
|
|
|
if (width <= 630 || previousWidth <= 630) |
|
|
|
var minWidth = scenarioMinWidth - 20 // margin |
|
|
|
if (width <= minWidth || previousWidth <= minWidth) |
|
|
|
{ |
|
|
|
fromWidth = 100 |
|
|
|
toWidth = 100 |
|
|
@ -47,7 +59,7 @@ ColumnLayout { |
|
|
|
if (!scenario) |
|
|
|
return; |
|
|
|
if (model) |
|
|
|
chainChanged() |
|
|
|
rebuild.startBlinking() |
|
|
|
model = scenario |
|
|
|
blockModel.clear() |
|
|
|
for (var b in model.blocks) |
|
|
@ -56,11 +68,11 @@ ColumnLayout { |
|
|
|
} |
|
|
|
|
|
|
|
property int statusWidth: 30 |
|
|
|
property int fromWidth: 100 |
|
|
|
property int fromWidth: 150 |
|
|
|
property int toWidth: 100 |
|
|
|
property int valueWidth: 200 |
|
|
|
property int logsWidth: 50 |
|
|
|
property int debugActionWidth: 50 |
|
|
|
property int logsWidth: 40 |
|
|
|
property int debugActionWidth: 40 |
|
|
|
property int horizontalMargin: 10 |
|
|
|
property int cellSpacing: 10 |
|
|
|
|
|
|
@ -68,23 +80,30 @@ ColumnLayout { |
|
|
|
{ |
|
|
|
id: header |
|
|
|
spacing: 0 |
|
|
|
Layout.preferredHeight: 25 |
|
|
|
Image { |
|
|
|
id: debugImage |
|
|
|
source: "qrc:/qml/img/recycleicon@2x.png" |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
Rectangle |
|
|
|
{ |
|
|
|
Layout.preferredWidth: statusWidth |
|
|
|
Layout.preferredHeight: 25 |
|
|
|
fillMode: Image.PreserveAspectFit |
|
|
|
Layout.preferredHeight: parent.height |
|
|
|
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 |
|
|
|
} |
|
|
|
} |
|
|
|
Rectangle |
|
|
|
{ |
|
|
|
Layout.preferredWidth: fromWidth + cellSpacing |
|
|
|
Layout.preferredWidth: fromWidth |
|
|
|
Label |
|
|
|
{ |
|
|
|
anchors.verticalCenter: parent.verticalCenter |
|
|
|
text: "From" |
|
|
|
anchors.left: parent.left |
|
|
|
anchors.leftMargin: horizontalMargin + 5 |
|
|
|
anchors.leftMargin: horizontalMargin |
|
|
|
} |
|
|
|
} |
|
|
|
Label |
|
|
@ -120,12 +139,25 @@ ColumnLayout { |
|
|
|
{ |
|
|
|
id: blockChainScrollView |
|
|
|
anchors.fill: parent |
|
|
|
anchors.topMargin: 10 |
|
|
|
anchors.topMargin: 8 |
|
|
|
ColumnLayout |
|
|
|
{ |
|
|
|
id: blockChainLayout |
|
|
|
width: parent.width |
|
|
|
spacing: 10 |
|
|
|
spacing: 20 |
|
|
|
|
|
|
|
Block |
|
|
|
{ |
|
|
|
scenario: blockChainPanel.model |
|
|
|
Layout.preferredWidth: blockChainScrollView.width |
|
|
|
Layout.preferredHeight: 60 |
|
|
|
blockIndex: -1 |
|
|
|
transactions: [] |
|
|
|
status: "" |
|
|
|
number: -2 |
|
|
|
trHeight: 60 |
|
|
|
} |
|
|
|
|
|
|
|
Repeater // List of blocks |
|
|
|
{ |
|
|
|
id: blockChainRepeater |
|
|
@ -218,158 +250,171 @@ ColumnLayout { |
|
|
|
Layout.preferredWidth: parent.width |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
width: 4 * 100 |
|
|
|
anchors.horizontalCenter: parent.horizontalCenter |
|
|
|
anchors.top: parent.top |
|
|
|
anchors.topMargin: 10 |
|
|
|
spacing: 0 |
|
|
|
ScenarioButton { |
|
|
|
id: rebuild |
|
|
|
text: qsTr("Rebuild") |
|
|
|
onClicked: |
|
|
|
{ |
|
|
|
if (ensureNotFuturetime.running) |
|
|
|
return; |
|
|
|
reBuildNeeded.stop() |
|
|
|
var retBlocks = []; |
|
|
|
var bAdded = 0; |
|
|
|
for (var j = 0; j < model.blocks.length; j++) |
|
|
|
spacing: 20 |
|
|
|
|
|
|
|
Rectangle { |
|
|
|
Layout.preferredWidth: 100 |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
|
|
|
|
ScenarioButton { |
|
|
|
id: rebuild |
|
|
|
text: qsTr("Rebuild") |
|
|
|
width: 100 |
|
|
|
height: 30 |
|
|
|
roundLeft: true |
|
|
|
roundRight: true |
|
|
|
onClicked: |
|
|
|
{ |
|
|
|
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 (ensureNotFuturetime.running) |
|
|
|
return; |
|
|
|
stopBlinking() |
|
|
|
var retBlocks = []; |
|
|
|
var bAdded = 0; |
|
|
|
for (var j = 0; j < model.blocks.length; j++) |
|
|
|
{ |
|
|
|
if (blockModel.get(j).transactions.get(k).saveStatus) |
|
|
|
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++) |
|
|
|
{ |
|
|
|
var tr = model.blocks[j].transactions[k] |
|
|
|
tr.saveStatus = true |
|
|
|
block.transactions.push(tr); |
|
|
|
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) |
|
|
|
{ |
|
|
|
bAdded++ |
|
|
|
block.number = bAdded |
|
|
|
block.status = "mined" |
|
|
|
retBlocks.push(block) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (block.transactions.length > 0) |
|
|
|
if (retBlocks.length === 0) |
|
|
|
retBlocks.push(projectModel.stateListModel.createEmptyBlock()) |
|
|
|
else |
|
|
|
{ |
|
|
|
bAdded++ |
|
|
|
block.number = bAdded |
|
|
|
block.status = "mined" |
|
|
|
retBlocks.push(block) |
|
|
|
var last = retBlocks[retBlocks.length - 1] |
|
|
|
last.number = -1 |
|
|
|
last.status = "pending" |
|
|
|
} |
|
|
|
|
|
|
|
model.blocks = retBlocks |
|
|
|
blockModel.clear() |
|
|
|
for (var j = 0; j < model.blocks.length; j++) |
|
|
|
blockModel.append(model.blocks[j]) |
|
|
|
|
|
|
|
ensureNotFuturetime.start() |
|
|
|
clientModel.setupScenario(model); |
|
|
|
} |
|
|
|
if (retBlocks.length === 0) |
|
|
|
retBlocks.push(projectModel.stateListModel.createEmptyBlock()) |
|
|
|
else |
|
|
|
{ |
|
|
|
var last = retBlocks[retBlocks.length - 1] |
|
|
|
last.number = -1 |
|
|
|
last.status = "pending" |
|
|
|
} |
|
|
|
buttonShortcut: "" |
|
|
|
sourceImg: "qrc:/qml/img/recycleicon@2x.png" |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
model.blocks = retBlocks |
|
|
|
blockModel.clear() |
|
|
|
for (var j = 0; j < model.blocks.length; j++) |
|
|
|
blockModel.append(model.blocks[j]) |
|
|
|
|
|
|
|
ensureNotFuturetime.start() |
|
|
|
clientModel.setupScenario(model); |
|
|
|
Rectangle |
|
|
|
{ |
|
|
|
Layout.preferredWidth: 200 |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
color: "transparent" |
|
|
|
|
|
|
|
ScenarioButton { |
|
|
|
id: addTransaction |
|
|
|
text: qsTr("Add Tx") |
|
|
|
onClicked: |
|
|
|
{ |
|
|
|
var lastBlock = model.blocks[model.blocks.length - 1]; |
|
|
|
if (lastBlock.status === "mined") |
|
|
|
{ |
|
|
|
var newblock = projectModel.stateListModel.createEmptyBlock() |
|
|
|
blockModel.appendBlock(newblock) |
|
|
|
model.blocks.push(newblock); |
|
|
|
} |
|
|
|
|
|
|
|
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 |
|
|
|
} |
|
|
|
|
|
|
|
Layout.preferredWidth: 100 |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
buttonShortcut: "" |
|
|
|
sourceImg: "qrc:/qml/img/recycleicon@2x.png" |
|
|
|
Timer |
|
|
|
{ |
|
|
|
id: reBuildNeeded |
|
|
|
repeat: true |
|
|
|
id: ensureNotFuturetime |
|
|
|
interval: 1000 |
|
|
|
repeat: false |
|
|
|
running: false |
|
|
|
onTriggered: { |
|
|
|
if (!parent.fillColor || parent.fillColor === "white") |
|
|
|
parent.fillColor = "orange" |
|
|
|
else |
|
|
|
parent.fillColor = "white" |
|
|
|
} |
|
|
|
onRunningChanged: { |
|
|
|
if (!running) |
|
|
|
parent.fillColor = "white" |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ScenarioButton { |
|
|
|
id: addTransaction |
|
|
|
text: qsTr("Add Transaction") |
|
|
|
onClicked: |
|
|
|
Rectangle |
|
|
|
{ |
|
|
|
var lastBlock = model.blocks[model.blocks.length - 1]; |
|
|
|
if (lastBlock.status === "mined") |
|
|
|
{ |
|
|
|
var newblock = projectModel.stateListModel.createEmptyBlock() |
|
|
|
blockModel.appendBlock(newblock) |
|
|
|
model.blocks.push(newblock); |
|
|
|
} |
|
|
|
|
|
|
|
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: 1 |
|
|
|
height: parent.height |
|
|
|
anchors.right: addBlockBtn.left |
|
|
|
color: "#ededed" |
|
|
|
} |
|
|
|
Layout.preferredWidth: 100 |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
buttonShortcut: "" |
|
|
|
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png" |
|
|
|
} |
|
|
|
|
|
|
|
Timer |
|
|
|
{ |
|
|
|
id: ensureNotFuturetime |
|
|
|
interval: 1000 |
|
|
|
repeat: false |
|
|
|
running: false |
|
|
|
} |
|
|
|
|
|
|
|
ScenarioButton { |
|
|
|
id: addBlockBtn |
|
|
|
text: qsTr("Add Block") |
|
|
|
onClicked: |
|
|
|
{ |
|
|
|
if (ensureNotFuturetime.running) |
|
|
|
return |
|
|
|
if (clientModel.mining || clientModel.running) |
|
|
|
return |
|
|
|
if (model.blocks.length > 0) |
|
|
|
ScenarioButton { |
|
|
|
id: addBlockBtn |
|
|
|
text: qsTr("Add Block..") |
|
|
|
anchors.left: addTransaction.right |
|
|
|
roundLeft: false |
|
|
|
roundRight: true |
|
|
|
onClicked: |
|
|
|
{ |
|
|
|
var lastBlock = model.blocks[model.blocks.length - 1] |
|
|
|
if (lastBlock.status === "pending") |
|
|
|
if (ensureNotFuturetime.running) |
|
|
|
return |
|
|
|
if (clientModel.mining || clientModel.running) |
|
|
|
return |
|
|
|
if (model.blocks.length > 0) |
|
|
|
{ |
|
|
|
ensureNotFuturetime.start() |
|
|
|
clientModel.mine() |
|
|
|
var lastBlock = model.blocks[model.blocks.length - 1] |
|
|
|
if (lastBlock.status === "pending") |
|
|
|
{ |
|
|
|
ensureNotFuturetime.start() |
|
|
|
clientModel.mine() |
|
|
|
} |
|
|
|
else |
|
|
|
addNewBlock() |
|
|
|
} |
|
|
|
else |
|
|
|
addNewBlock() |
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
addNewBlock() |
|
|
|
|
|
|
|
} |
|
|
|
function addNewBlock() |
|
|
|
{ |
|
|
|
var block = projectModel.stateListModel.createEmptyBlock() |
|
|
|
model.blocks.push(block) |
|
|
|
blockModel.appendBlock(block) |
|
|
|
} |
|
|
|
width: 100 |
|
|
|
height: 30 |
|
|
|
|
|
|
|
function addNewBlock() |
|
|
|
{ |
|
|
|
var block = projectModel.stateListModel.createEmptyBlock() |
|
|
|
model.blocks.push(block) |
|
|
|
blockModel.appendBlock(block) |
|
|
|
buttonShortcut: "" |
|
|
|
sourceImg: "qrc:/qml/img/addblock@2x.png" |
|
|
|
} |
|
|
|
Layout.preferredWidth: 100 |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
buttonShortcut: "" |
|
|
|
sourceImg: "qrc:/qml/img/addblock@2x.png" |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Connections |
|
|
|
{ |
|
|
|
target: clientModel |
|
|
@ -412,7 +457,6 @@ ColumnLayout { |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// tr is not in the list. |
|
|
|
var itemTr = TransactionHelper.defaultTransaction() |
|
|
|
itemTr.saveStatus = false |
|
|
@ -438,7 +482,7 @@ ColumnLayout { |
|
|
|
|
|
|
|
ScenarioButton { |
|
|
|
id: newAccount |
|
|
|
text: qsTr("New Account") |
|
|
|
text: qsTr("New Account..") |
|
|
|
onClicked: { |
|
|
|
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether)) |
|
|
|
} |
|
|
@ -446,6 +490,8 @@ ColumnLayout { |
|
|
|
Layout.preferredHeight: 30 |
|
|
|
buttonShortcut: "" |
|
|
|
sourceImg: "qrc:/qml/img/newaccounticon@2x.png" |
|
|
|
roundLeft: true |
|
|
|
roundRight: true |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|