yann300
10 years ago
22 changed files with 996 additions and 262 deletions
@ -0,0 +1,145 @@ |
|||
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 "js/Debugger.js" as Debugger |
|||
import "js/ErrorLocationFormater.js" as ErrorLocationFormater |
|||
import "." |
|||
|
|||
ColumnLayout |
|||
{ |
|||
property variant transactions |
|||
property string status |
|||
property int number |
|||
Rectangle |
|||
{ |
|||
width: parent.width |
|||
height: 50 |
|||
anchors.left: parent.left |
|||
anchors.leftMargin: statusWidth |
|||
Label { |
|||
text: |
|||
{ |
|||
if (status === "mined") |
|||
return qsTr("BLOCK") + " " + number |
|||
else |
|||
return qsTr("BLOCK") + " pending" |
|||
} |
|||
|
|||
anchors.left: parent.left |
|||
} |
|||
} |
|||
|
|||
Repeater // List of transactions |
|||
{ |
|||
id: transactionRepeater |
|||
model: transactions |
|||
Row |
|||
{ |
|||
height: 50 |
|||
Rectangle |
|||
{ |
|||
id: trSaveStatus |
|||
color: "transparent" |
|||
CheckBox |
|||
{ |
|||
id: saveStatus |
|||
checked: { |
|||
if (index >= 0) |
|||
return transactions.get(index).saveStatus |
|||
else |
|||
return true |
|||
} |
|||
onCheckedChanged: |
|||
{ |
|||
if (index >= 0) |
|||
transactions.get(index).saveStatus = checked |
|||
} |
|||
} |
|||
} |
|||
|
|||
Rectangle |
|||
{ |
|||
width: parent.width |
|||
height: 50 |
|||
color: "#cccccc" |
|||
radius: 4 |
|||
Row |
|||
{ |
|||
Label |
|||
{ |
|||
id: status |
|||
width: statusWidth |
|||
} |
|||
Label |
|||
{ |
|||
id: hash |
|||
width: fromWidth |
|||
text: { |
|||
if (index >= 0) |
|||
return transactions.get(index).sender |
|||
else |
|||
return "" |
|||
} |
|||
|
|||
clip: true |
|||
} |
|||
Label |
|||
{ |
|||
id: func |
|||
text: { |
|||
if (index >= 0) |
|||
parent.userFrienldyToken(transactions.get(index).label) |
|||
else |
|||
return "" |
|||
} |
|||
|
|||
width: toWidth |
|||
clip: true |
|||
} |
|||
|
|||
function userFrienldyToken(value) |
|||
{ |
|||
if (value && value.indexOf("<") === 0) |
|||
return value.split(" - ")[0].replace("<", "") + "." + value.split("> ")[1] + "()"; |
|||
else |
|||
return value |
|||
} |
|||
|
|||
Label |
|||
{ |
|||
id: returnValue |
|||
width: valueWidth |
|||
text: { |
|||
if (index >= 0 && transactions.get(index).returned) |
|||
return transactions.get(index).returned |
|||
else |
|||
return "" |
|||
} |
|||
clip: true |
|||
} |
|||
|
|||
Button |
|||
{ |
|||
id: debug |
|||
width: logsWidth |
|||
text: "debug" |
|||
onClicked: |
|||
{ |
|||
clientModel.debugRecord(transactions.get(index).recordIndex); |
|||
} |
|||
} |
|||
|
|||
Label |
|||
{ |
|||
id: logs |
|||
width: logsWidth |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,306 @@ |
|||
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 "." |
|||
|
|||
Column { |
|||
id: blockChainPanel |
|||
property variant model |
|||
spacing: 5 |
|||
|
|||
function load(scenario) |
|||
{ |
|||
|
|||
if (!scenario) |
|||
return; |
|||
model = scenario |
|||
blockModel.clear() |
|||
for (var b in model.blocks) |
|||
blockModel.append(model.blocks[b]) |
|||
} |
|||
|
|||
property int statusWidth: 50 |
|||
property int fromWidth: 100 |
|||
property int toWidth: 250 |
|||
property int valueWidth: 100 |
|||
property int logsWidth: 50 |
|||
|
|||
Row |
|||
{ |
|||
id: header |
|||
width: parent.width |
|||
Label |
|||
{ |
|||
text: "Status" |
|||
width: statusWidth |
|||
} |
|||
Label |
|||
{ |
|||
text: "From" |
|||
width: fromWidth |
|||
} |
|||
Label |
|||
{ |
|||
text: "To" |
|||
width: toWidth |
|||
} |
|||
Label |
|||
{ |
|||
text: "Value" |
|||
width: valueWidth |
|||
} |
|||
Label |
|||
{ |
|||
text: "Logs" |
|||
width: logsWidth |
|||
} |
|||
} |
|||
|
|||
Rectangle |
|||
{ |
|||
width: parent.width |
|||
height: 500 |
|||
border.color: "#cccccc" |
|||
border.width: 2 |
|||
color: "white" |
|||
ScrollView |
|||
{ |
|||
width: parent.width |
|||
height: parent.height |
|||
ColumnLayout |
|||
{ |
|||
Repeater // List of blocks |
|||
{ |
|||
id: blockChainRepeater |
|||
width: parent.width |
|||
model: blockModel |
|||
Block |
|||
{ |
|||
height: |
|||
{ |
|||
if (index >= 0) |
|||
return 50 + 50 * blockModel.get(index).transactions.length |
|||
else |
|||
return 0 |
|||
} |
|||
|
|||
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) |
|||
{ |
|||
console.log(blockIndex) |
|||
console.log(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 - 1).transactions.get(tr) |
|||
} |
|||
} |
|||
|
|||
RowLayout |
|||
{ |
|||
width: parent.width |
|||
Button { |
|||
id: rebuild |
|||
text: qsTr("Rebuild") |
|||
onClicked: |
|||
{ |
|||
for (var j = 0; j < model.blocks.length; j++) |
|||
{ |
|||
for (var k = 0; k < model.blocks[j].transactions.length; k++) |
|||
{ |
|||
if (!blockModel.get(j).transactions.get(k).saveStatus) |
|||
{ |
|||
model.blocks[j].transactions.splice(k, 1) |
|||
blockModel.removeTransaction(j, k) |
|||
if (model.blocks[j].transactions.length === 0) |
|||
{ |
|||
model.blocks[j].splice(j, 1); |
|||
blockModel.removeBlock(j); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
clientModel.setupScenario(model); |
|||
} |
|||
} |
|||
|
|||
Button { |
|||
id: addTransaction |
|||
text: qsTr("Add Transaction") |
|||
onClicked: |
|||
{ |
|||
var lastBlock = model.blocks[model.blocks.length - 1]; |
|||
if (lastBlock.status === "mined") |
|||
model.blocks.push(projectModel.stateListModel.createEmptyBlock()); |
|||
var item = TransactionHelper.defaultTransaction() |
|||
transactionDialog.stateAccounts = model.accounts |
|||
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item) |
|||
} |
|||
} |
|||
|
|||
Button { |
|||
id: addBlockBtn |
|||
text: qsTr("Add Block") |
|||
onClicked: |
|||
{ |
|||
var lastBlock = model.blocks[model.blocks.length - 1] |
|||
if (lastBlock.status === "pending") |
|||
clientModel.mine() |
|||
else |
|||
addNewBlock() |
|||
} |
|||
|
|||
function addNewBlock() |
|||
{ |
|||
var block = projectModel.stateListModel.createEmptyBlock() |
|||
model.blocks.push(block) |
|||
blockModel.appendBlock(block) |
|||
} |
|||
} |
|||
|
|||
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 = _r.transactionIndex.split(":")[0] |
|||
var trIndex = _r.transactionIndex.split(":")[1] |
|||
if (parseInt(blockIndex) <= model.blocks.length) |
|||
{ |
|||
var item = model.blocks[parseInt(blockIndex) - 1]; |
|||
if (parseInt(trIndex) <= item.transactions.length) |
|||
{ |
|||
var tr = item.transactions[parseInt(trIndex)]; |
|||
tr.returned = _r.returned; |
|||
blockModel.getTransaction(blockIndex, trIndex).returned = _r.returned; |
|||
tr.recordIndex = _r.recordIndex; |
|||
blockModel.getTransaction(blockIndex, trIndex).recordIndex = _r.recordIndex; |
|||
return; |
|||
} |
|||
} |
|||
|
|||
// tr is not in the list. coming from JavaScript |
|||
var itemTr = TransactionHelper.defaultTransaction() |
|||
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 |
|||
|
|||
model.blocks[model.blocks.length - 1].transactions.push(itemTr) |
|||
blockModel.appendTransaction(itemTr) |
|||
} |
|||
onMiningComplete: |
|||
{ |
|||
} |
|||
} |
|||
|
|||
Button { |
|||
id: newAccount |
|||
text: qsTr("New Account") |
|||
onClicked: { |
|||
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether)) |
|||
} |
|||
} |
|||
} |
|||
|
|||
TransactionDialog { |
|||
id: transactionDialog |
|||
onAccepted: { |
|||
var item = transactionDialog.getItem() |
|||
var lastBlock = model.blocks[model.blocks.length - 1]; |
|||
if (lastBlock.status === "mined") |
|||
model.blocks.push(projectModel.stateListModel.createEmptyBlock()); |
|||
model.blocks[model.blocks.length - 1].transactions.push(item) |
|||
blockModel.appendTransaction(item) |
|||
if (!clientModel.running) |
|||
clientModel.executeTr(item) |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
@ -0,0 +1,57 @@ |
|||
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 "js/Debugger.js" as Debugger |
|||
import "js/ErrorLocationFormater.js" as ErrorLocationFormater |
|||
import "." |
|||
|
|||
Rectangle { |
|||
|
|||
border.color: "red" |
|||
border.width: 1 |
|||
|
|||
Connections |
|||
{ |
|||
target: projectModel |
|||
onProjectLoaded: { |
|||
loader.init() |
|||
} |
|||
|
|||
} |
|||
|
|||
Column |
|||
{ |
|||
anchors.margins: 10 |
|||
anchors.fill: parent |
|||
spacing: 5 |
|||
ScenarioLoader |
|||
{ |
|||
width: parent.width |
|||
id: loader |
|||
} |
|||
|
|||
Rectangle |
|||
{ |
|||
width: parent.width |
|||
height: 1 |
|||
color: "#cccccc" |
|||
} |
|||
|
|||
Connections |
|||
{ |
|||
target: loader |
|||
onLoaded: { |
|||
blockChain.load(scenario) |
|||
} |
|||
} |
|||
|
|||
BlockChain |
|||
{ |
|||
id: blockChain |
|||
width: parent.width |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,77 @@ |
|||
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 "js/Debugger.js" as Debugger |
|||
import "js/ErrorLocationFormater.js" as ErrorLocationFormater |
|||
import "." |
|||
|
|||
RowLayout |
|||
{ |
|||
signal restored(variant scenario) |
|||
signal saved(variant scenario) |
|||
signal duplicated(variant scenario) |
|||
signal loaded(variant scenario) |
|||
|
|||
function init() |
|||
{ |
|||
scenarioList.load() |
|||
} |
|||
|
|||
id: blockChainSelector |
|||
ComboBox |
|||
{ |
|||
id: scenarioList |
|||
model: projectModel.stateListModel |
|||
textRole: "title" |
|||
onCurrentIndexChanged: |
|||
{ |
|||
restoreScenario.restore() |
|||
} |
|||
|
|||
function load() |
|||
{ |
|||
var state = projectModel.stateListModel.getState(currentIndex) |
|||
loaded(state) |
|||
} |
|||
} |
|||
Button |
|||
{ |
|||
id: restoreScenario |
|||
text: qsTr("Restore") |
|||
onClicked: { |
|||
restore() |
|||
} |
|||
|
|||
function restore() |
|||
{ |
|||
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex) |
|||
restored(state) |
|||
loaded(state) |
|||
} |
|||
|
|||
} |
|||
Button |
|||
{ |
|||
id: saveScenario |
|||
text: qsTr("Save") |
|||
onClicked: { |
|||
projectModel.saveProjectFile() |
|||
saved(state) |
|||
} |
|||
} |
|||
Button |
|||
{ |
|||
id: duplicateScenario |
|||
text: qsTr("Duplicate") |
|||
onClicked: { |
|||
var state = JSON.parse(JSON.stringify(projectModel.stateListModel.getState(scenarioList.currentIndex))) |
|||
state.title = qsTr("Copy of ") + state.title; |
|||
projectModel.stateListModel.appendState(state) |
|||
projectModel.stateListModel.save() |
|||
duplicated(state) |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue