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.

440 lines
11 KiB

10 years ago
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
10 years ago
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.2
10 years ago
import QtQuick.Layouts 1.1
import org.ethereum.qml.QEther 1.0
import "js/QEtherHelper.js" as QEtherHelper
import "js/TransactionHelper.js" as TransactionHelper
10 years ago
Item {
property alias model: stateListModel
property var stateList: []
10 years ago
property alias stateDialog: stateDialog
10 years ago
property string defaultAccount: "cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074" //support for old project
10 years ago
function fromPlainStateItem(s) {
10 years ago
if (!s.accounts)
10 years ago
s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project
if (!s.contracts)
s.contracts = [];
10 years ago
var ret = {};
ret.title = s.title;
ret.transactions = s.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem); //support old projects by filtering std contracts
if (s.blocks)
ret.blocks = s.blocks.map(fromPlainBlockItem);
ret.accounts = s.accounts.map(fromPlainAccountItem);
ret.contracts = s.contracts.map(fromPlainAccountItem);
ret.miner = s.miner;
// support old projects
if (!ret.blocks)
{
ret.blocks = [{
hash: "",
number: -1,
transactions: [],
status: "pending"
}]
for (var j in ret.transactions)
ret.blocks[0].transactions.push(fromPlainTransactionItem(toPlainTransactionItem(ret.transactions[j])))
}
return ret;
}
function fromPlainAccountItem(t)
{
return {
name: t.name,
address: t.address,
secret: t.secret,
balance: QEtherHelper.createEther(t.balance.value, t.balance.unit),
storage: t.storage,
code: t.code,
10 years ago
};
}
function fromPlainTransactionItem(t) {
if (!t.sender)
10 years ago
t.sender = defaultAccount; //support for old project
10 years ago
var r = {
type: t.type,
contractId: t.contractId,
10 years ago
functionId: t.functionId,
10 years ago
url: t.url,
10 years ago
value: QEtherHelper.createEther(t.value.value, t.value.unit),
gas: QEtherHelper.createBigInt(t.gas.value),
10 years ago
gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit),
gasAuto: t.gasAuto,
parameters: {},
sender: t.sender,
10 years ago
isContractCreation: t.isContractCreation,
label: t.label,
10 years ago
isFunctionCall: t.isFunctionCall,
saveStatus: t.saveStatus
10 years ago
};
10 years ago
10 years ago
if (r.saveStatus === undefined)
r.saveStatus = true
if (r.isFunctionCall === undefined)
r.isFunctionCall = true;
10 years ago
if (!r.label)
10 years ago
r.label = r.contractId + " - " + r.functionId;
10 years ago
10 years ago
if (r.isContractCreation === undefined)
r.isContractCreation = r.functionId === r.contractId;
for (var key in t.parameters)
10 years ago
r.parameters[key] = t.parameters[key];
10 years ago
return r;
10 years ago
}
10 years ago
function fromPlainBlockItem(b)
{
var r = {
hash: b.hash,
number: b.number,
transactions: b.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem), //support old projects by filtering std contracts
status: b.status
}
return r;
}
10 years ago
function toPlainStateItem(s) {
return {
title: s.title,
10 years ago
blocks: s.blocks.map(toPlainBlockItem),
transactions: s.transactions.map(toPlainTransactionItem),
accounts: s.accounts.map(toPlainAccountItem),
contracts: s.contracts.map(toPlainAccountItem),
miner: s.miner
10 years ago
};
}
function getParamType(param, params)
{
for (var k in params)
{
if (params[k].declaration.name === param)
return params[k].declaration.type;
}
return '';
}
10 years ago
function toPlainBlockItem(b)
{
var r = {
hash: b.hash,
number: b.number,
transactions: b.transactions.map(toPlainTransactionItem),
status: b.status
}
return r;
}
function toPlainAccountItem(t)
{
return {
name: t.name,
secret: t.secret,
balance: {
value: t.balance.value,
unit: t.balance.unit
},
address: t.address,
storage: t.storage,
code: t.code,
};
}
10 years ago
function toPlainTransactionItem(t) {
10 years ago
var r = {
type: t.type,
contractId: t.contractId,
10 years ago
functionId: t.functionId,
10 years ago
url: t.url,
10 years ago
value: { value: t.value.value, unit: t.value.unit },
gas: { value: t.gas.value() },
gasAuto: t.gasAuto,
10 years ago
gasPrice: { value: t.gasPrice.value, unit: t.gasPrice.unit },
sender: t.sender,
parameters: {},
10 years ago
isContractCreation: t.isContractCreation,
label: t.label,
10 years ago
isFunctionCall: t.isFunctionCall,
saveStatus: t.saveStatus
10 years ago
};
10 years ago
for (var key in t.parameters)
10 years ago
r.parameters[key] = t.parameters[key];
10 years ago
return r;
10 years ago
}
Connections {
target: projectModel
onProjectClosed: {
stateListModel.clear();
stateList = [];
codeModel.reset();
10 years ago
}
onProjectLoading: stateListModel.loadStatesFromProject(projectData);
onProjectFileSaving: {
10 years ago
projectData.states = []
for(var i = 0; i < stateListModel.count; i++) {
projectData.states.push(toPlainStateItem(stateList[i]));
}
projectData.defaultStateIndex = stateListModel.defaultStateIndex;
10 years ago
stateListModel.data = projectData
10 years ago
}
10 years ago
onNewProject: {
10 years ago
var state = toPlainStateItem(stateListModel.createDefaultState());
10 years ago
state.title = qsTr("Default");
projectData.states = [ state ];
projectData.defaultStateIndex = 0;
10 years ago
stateListModel.loadStatesFromProject(projectData);
}
10 years ago
}
Connections {
target: codeModel
onNewContractCompiled: {
stateListModel.addNewContracts();
}
onContractRenamed: {
stateListModel.renameContracts(_oldName, _newName);
}
}
10 years ago
StateDialog {
id: stateDialog
onAccepted: {
var item = stateDialog.getItem();
10 years ago
saveState(item);
10 years ago
}
10 years ago
function saveState(item)
{
if (stateDialog.stateIndex < stateListModel.count) {
if (stateDialog.isDefault)
stateListModel.defaultStateIndex = stateIndex;
stateList[stateDialog.stateIndex] = item;
stateListModel.set(stateDialog.stateIndex, item);
} else {
if (stateDialog.isDefault)
stateListModel.defaultStateIndex = 0;
stateList.push(item);
stateListModel.append(item);
}
if (stateDialog.isDefault)
stateListModel.defaultStateChanged();
stateListModel.save();
}
10 years ago
}
ListModel {
id: stateListModel
property int defaultStateIndex: 0
10 years ago
property variant data
signal defaultStateChanged;
signal stateListModelReady;
signal stateRun(int index)
10 years ago
signal stateDeleted(int index)
10 years ago
function defaultTransactionItem() {
return TransactionHelper.defaultTransaction();
10 years ago
}
10 years ago
function newAccount(_balance, _unit, _secret)
{
if (!_secret)
_secret = clientModel.newSecret();
var address = clientModel.address(_secret);
var name = qsTr("Account") + "-" + address.substring(0, 4);
return { name: name, secret: _secret, balance: QEtherHelper.createEther(_balance, _unit), address: address };
}
10 years ago
function duplicateState(index)
{
var state = stateList[index]
var item = fromPlainStateItem(toPlainStateItem(state))
item.title = qsTr("Copy of") + " " + state.title
appendState(item)
save()
}
function createEmptyBlock()
{
return {
hash: "",
number: -1,
transactions: [],
status: "pending"
}
}
10 years ago
function createDefaultState() {
var item = {
title: "",
transactions: [],
accounts: [],
10 years ago
contracts: [],
blocks: [{ status: "pending", number: -1, hash: "", transactions: []}]
};
10 years ago
10 years ago
var account = newAccount("1000000", QEther.Ether, defaultAccount)
item.accounts.push(account);
item.miner = account;
//add constructors, //TODO: order by dependencies
for(var c in codeModel.contracts) {
var ctorTr = defaultTransactionItem();
ctorTr.functionId = c;
ctorTr.contractId = c;
10 years ago
ctorTr.label = qsTr("Deploy") + " " + ctorTr.contractId;
ctorTr.sender = item.accounts[0].secret;
item.transactions.push(ctorTr);
10 years ago
item.blocks[0].transactions.push(ctorTr)
}
10 years ago
return item;
}
function renameContracts(oldName, newName) {
var changed = false;
for(var c in codeModel.contracts) {
for (var s = 0; s < stateListModel.count; s++) {
var state = stateList[s];
for (var t = 0; t < state.transactions.length; t++) {
var transaction = state.transactions[t];
if (transaction.contractId === oldName) {
transaction.contractId = newName;
if (transaction.functionId === oldName)
transaction.functionId = newName;
changed = true;
state.transactions[t] = transaction;
}
}
stateListModel.set(s, state);
stateList[s] = state;
}
}
if (changed)
save();
}
function addNewContracts() {
10 years ago
//add new contracts to empty states
var changed = false;
for (var c in codeModel.contracts) {
for (var s = 0; s < stateListModel.count; s++) {
var state = stateList[s];
10 years ago
if (state.transactions.length === 0) {
//append this contract
var ctorTr = defaultTransactionItem();
ctorTr.functionId = c;
ctorTr.contractId = c;
10 years ago
ctorTr.label = qsTr("Deploy") + " " + ctorTr.contractId;
ctorTr.sender = state.accounts[0].secret;
state.transactions.push(ctorTr);
changed = true;
stateListModel.set(s, state);
stateList[s] = state;
}
}
}
if (changed)
save();
}
10 years ago
function addState() {
var item = createDefaultState();
stateDialog.open(stateListModel.count, item, false);
10 years ago
}
10 years ago
function appendState(item)
{
stateListModel.append(item);
stateList.push(item);
}
10 years ago
function editState(index) {
stateDialog.open(index, stateList[index], defaultStateIndex === index);
10 years ago
}
10 years ago
function getState(index) {
return stateList[index];
}
10 years ago
function debugDefaultState() {
10 years ago
if (defaultStateIndex >= 0 && defaultStateIndex < stateList.length)
10 years ago
runState(defaultStateIndex);
}
10 years ago
function runState(index) {
var item = stateList[index];
10 years ago
clientModel.setupScenario(item);
stateRun(index);
10 years ago
}
function deleteState(index) {
stateListModel.remove(index);
stateList.splice(index, 1);
if (index === defaultStateIndex)
{
defaultStateIndex = 0;
defaultStateChanged();
}
10 years ago
else if (defaultStateIndex > index)
defaultStateIndex--;
10 years ago
save();
10 years ago
stateDeleted(index);
10 years ago
}
function save() {
projectModel.saveProject();
}
function defaultStateName()
{
return stateList[defaultStateIndex].title;
}
10 years ago
function reloadStateFromFromProject(index)
{
if (data)
{
var item = fromPlainStateItem(data.states[index])
stateListModel.set(index, item)
stateList[index] = item
return item
}
}
function loadStatesFromProject(projectData)
{
10 years ago
data = projectData
if (!projectData.states)
projectData.states = [];
if (projectData.defaultStateIndex !== undefined)
defaultStateIndex = projectData.defaultStateIndex;
else
defaultStateIndex = 0;
var items = projectData.states;
stateListModel.clear();
stateList = [];
for(var i = 0; i < items.length; i++) {
var item = fromPlainStateItem(items[i]);
stateListModel.append(item);
stateList.push(item);
}
stateListModelReady();
}
10 years ago
}
}