|
|
@ -1,6 +1,6 @@ |
|
|
|
import QtQuick 2.2 |
|
|
|
import QtQuick.Controls 1.1 |
|
|
|
import QtQuick.Dialogs 1.1 |
|
|
|
import QtQuick.Dialogs 1.2 |
|
|
|
import QtQuick.Layouts 1.1 |
|
|
|
import QtQuick.Window 2.0 |
|
|
|
import QtQuick.Controls.Styles 1.3 |
|
|
@ -9,7 +9,7 @@ import "js/QEtherHelper.js" as QEtherHelper |
|
|
|
import "js/TransactionHelper.js" as TransactionHelper |
|
|
|
import "." |
|
|
|
|
|
|
|
Window { |
|
|
|
Dialog { |
|
|
|
id: modalStateDialog |
|
|
|
modality: Qt.ApplicationModal |
|
|
|
|
|
|
@ -17,7 +17,6 @@ Window { |
|
|
|
height: 480 |
|
|
|
title: qsTr("Edit State") |
|
|
|
visible: false |
|
|
|
color: stateDialogStyle.generic.backgroundColor |
|
|
|
|
|
|
|
property alias stateTitle: titleField.text |
|
|
|
property alias isDefault: defaultCheckBox.checked |
|
|
@ -28,6 +27,10 @@ Window { |
|
|
|
property var stateAccounts: [] |
|
|
|
signal accepted |
|
|
|
|
|
|
|
StateDialogStyle { |
|
|
|
id: stateDialogStyle |
|
|
|
} |
|
|
|
|
|
|
|
function open(index, item, setDefault) { |
|
|
|
stateIndex = index; |
|
|
|
stateTitle = item.title; |
|
|
@ -48,9 +51,6 @@ Window { |
|
|
|
stateAccounts.push(item.accounts[k]); |
|
|
|
} |
|
|
|
|
|
|
|
modalStateDialog.setX((Screen.width - width) / 2); |
|
|
|
modalStateDialog.setY((Screen.height - height) / 2); |
|
|
|
|
|
|
|
visible = true; |
|
|
|
isDefault = setDefault; |
|
|
|
titleField.focus = true; |
|
|
@ -77,338 +77,334 @@ Window { |
|
|
|
item.accounts = stateAccounts; |
|
|
|
return item; |
|
|
|
} |
|
|
|
|
|
|
|
StateDialogStyle { |
|
|
|
id: stateDialogStyle |
|
|
|
} |
|
|
|
|
|
|
|
ColumnLayout { |
|
|
|
anchors.fill: parent |
|
|
|
anchors.margins: 10 |
|
|
|
contentItem: Rectangle { |
|
|
|
color: stateDialogStyle.generic.backgroundColor |
|
|
|
ColumnLayout { |
|
|
|
id: dialogContent |
|
|
|
anchors.top: parent.top |
|
|
|
|
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
DefaultLabel { |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
text: qsTr("Title") |
|
|
|
} |
|
|
|
DefaultTextField |
|
|
|
{ |
|
|
|
id: titleField |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
|
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
|
|
|
|
Rectangle |
|
|
|
{ |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
DefaultLabel { |
|
|
|
id: accountsLabel |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
text: qsTr("Accounts") |
|
|
|
anchors.fill: parent |
|
|
|
ColumnLayout { |
|
|
|
anchors.fill: parent |
|
|
|
anchors.margins: 10 |
|
|
|
ColumnLayout { |
|
|
|
id: dialogContent |
|
|
|
anchors.top: parent.top |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
DefaultLabel { |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
text: qsTr("Title") |
|
|
|
} |
|
|
|
DefaultTextField |
|
|
|
{ |
|
|
|
id: titleField |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Button |
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
anchors.top: accountsLabel.bottom |
|
|
|
anchors.topMargin: 10 |
|
|
|
iconSource: "qrc:/qml/img/plus.png" |
|
|
|
action: newAccountAction |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
|
|
|
|
Action { |
|
|
|
id: newAccountAction |
|
|
|
tooltip: qsTr("Add new Account") |
|
|
|
onTriggered: |
|
|
|
{ |
|
|
|
var account = stateListModel.newAccount("1000000", QEther.Ether); |
|
|
|
stateAccounts.push(account); |
|
|
|
accountsModel.append(account); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
|
|
|
|
MessageDialog |
|
|
|
{ |
|
|
|
id: alertAlreadyUsed |
|
|
|
text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.") |
|
|
|
icon: StandardIcon.Warning |
|
|
|
standardButtons: StandardButton.Ok |
|
|
|
} |
|
|
|
Rectangle |
|
|
|
{ |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
DefaultLabel { |
|
|
|
id: accountsLabel |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
text: qsTr("Accounts") |
|
|
|
} |
|
|
|
|
|
|
|
TableView |
|
|
|
{ |
|
|
|
id: accountsView |
|
|
|
Layout.fillWidth: true |
|
|
|
model: accountsModel |
|
|
|
headerVisible: false |
|
|
|
TableViewColumn { |
|
|
|
role: "name" |
|
|
|
title: qsTr("Name") |
|
|
|
width: 150 |
|
|
|
delegate: Item { |
|
|
|
RowLayout |
|
|
|
Button |
|
|
|
{ |
|
|
|
height: 25 |
|
|
|
width: parent.width |
|
|
|
Button |
|
|
|
anchors.top: accountsLabel.bottom |
|
|
|
anchors.topMargin: 10 |
|
|
|
iconSource: "qrc:/qml/img/plus.png" |
|
|
|
action: newAccountAction |
|
|
|
} |
|
|
|
|
|
|
|
Action { |
|
|
|
id: newAccountAction |
|
|
|
tooltip: qsTr("Add new Account") |
|
|
|
onTriggered: |
|
|
|
{ |
|
|
|
iconSource: "qrc:/qml/img/delete_sign.png" |
|
|
|
action: deleteAccountAction |
|
|
|
var account = stateListModel.newAccount("1000000", QEther.Ether); |
|
|
|
stateAccounts.push(account); |
|
|
|
accountsModel.append(account); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Action { |
|
|
|
id: deleteAccountAction |
|
|
|
tooltip: qsTr("Delete Account") |
|
|
|
onTriggered: |
|
|
|
MessageDialog |
|
|
|
{ |
|
|
|
id: alertAlreadyUsed |
|
|
|
text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.") |
|
|
|
icon: StandardIcon.Warning |
|
|
|
standardButtons: StandardButton.Ok |
|
|
|
} |
|
|
|
|
|
|
|
TableView |
|
|
|
{ |
|
|
|
id: accountsView |
|
|
|
Layout.fillWidth: true |
|
|
|
model: accountsModel |
|
|
|
headerVisible: false |
|
|
|
TableViewColumn { |
|
|
|
role: "name" |
|
|
|
title: qsTr("Name") |
|
|
|
width: 150 |
|
|
|
delegate: Item { |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
if (transactionsModel.isUsed(stateAccounts[styleData.row].secret)) |
|
|
|
alertAlreadyUsed.open(); |
|
|
|
else |
|
|
|
height: 25 |
|
|
|
width: parent.width |
|
|
|
Button |
|
|
|
{ |
|
|
|
stateAccounts.splice(styleData.row, 1); |
|
|
|
accountsModel.remove(styleData.row); |
|
|
|
iconSource: "qrc:/qml/img/delete_sign.png" |
|
|
|
action: deleteAccountAction |
|
|
|
} |
|
|
|
|
|
|
|
Action { |
|
|
|
id: deleteAccountAction |
|
|
|
tooltip: qsTr("Delete Account") |
|
|
|
onTriggered: |
|
|
|
{ |
|
|
|
if (transactionsModel.isUsed(stateAccounts[styleData.row].secret)) |
|
|
|
alertAlreadyUsed.open(); |
|
|
|
else |
|
|
|
{ |
|
|
|
stateAccounts.splice(styleData.row, 1); |
|
|
|
accountsModel.remove(styleData.row); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
DefaultTextField { |
|
|
|
anchors.verticalCenter: parent.verticalCenter |
|
|
|
onTextChanged: { |
|
|
|
if (styleData.row > -1) |
|
|
|
stateAccounts[styleData.row].name = text; |
|
|
|
} |
|
|
|
text: { |
|
|
|
return styleData.value |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
DefaultTextField { |
|
|
|
anchors.verticalCenter: parent.verticalCenter |
|
|
|
onTextChanged: { |
|
|
|
if (styleData.row > -1) |
|
|
|
stateAccounts[styleData.row].name = text; |
|
|
|
} |
|
|
|
text: { |
|
|
|
return styleData.value |
|
|
|
TableViewColumn { |
|
|
|
role: "balance" |
|
|
|
title: qsTr("Balance") |
|
|
|
width: 200 |
|
|
|
delegate: Item { |
|
|
|
Ether { |
|
|
|
id: balanceField |
|
|
|
edit: true |
|
|
|
displayFormattedValue: false |
|
|
|
value: styleData.value |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
rowDelegate: |
|
|
|
Rectangle { |
|
|
|
color: styleData.alternate ? "transparent" : "#f0f0f0" |
|
|
|
height: 30; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
TableViewColumn { |
|
|
|
role: "balance" |
|
|
|
title: qsTr("Balance") |
|
|
|
width: 200 |
|
|
|
delegate: Item { |
|
|
|
Ether { |
|
|
|
id: balanceField |
|
|
|
edit: true |
|
|
|
displayFormattedValue: false |
|
|
|
value: styleData.value |
|
|
|
} |
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
|
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
DefaultLabel { |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
text: qsTr("Default") |
|
|
|
} |
|
|
|
CheckBox { |
|
|
|
id: defaultCheckBox |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
rowDelegate: |
|
|
|
Rectangle { |
|
|
|
color: styleData.alternate ? "transparent" : "#f0f0f0" |
|
|
|
height: 30; |
|
|
|
|
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
ColumnLayout { |
|
|
|
anchors.top: dialogContent.bottom |
|
|
|
anchors.topMargin: 5 |
|
|
|
spacing: 0 |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.preferredWidth: 150 |
|
|
|
DefaultLabel { |
|
|
|
text: qsTr("Transactions: ") |
|
|
|
} |
|
|
|
|
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
DefaultLabel { |
|
|
|
Layout.preferredWidth: 75 |
|
|
|
text: qsTr("Default") |
|
|
|
} |
|
|
|
CheckBox { |
|
|
|
id: defaultCheckBox |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
Button |
|
|
|
{ |
|
|
|
iconSource: "qrc:/qml/img/plus.png" |
|
|
|
action: newTrAction |
|
|
|
width: 10 |
|
|
|
height: 10 |
|
|
|
anchors.right: parent.right |
|
|
|
} |
|
|
|
|
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
Action { |
|
|
|
id: newTrAction |
|
|
|
tooltip: qsTr("Create a new transaction") |
|
|
|
onTriggered: transactionsModel.addTransaction() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ColumnLayout { |
|
|
|
anchors.top: dialogContent.bottom |
|
|
|
anchors.topMargin: 5 |
|
|
|
spacing: 0 |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
Layout.preferredWidth: 150 |
|
|
|
DefaultLabel { |
|
|
|
text: qsTr("Transactions: ") |
|
|
|
ScrollView |
|
|
|
{ |
|
|
|
Layout.fillHeight: true |
|
|
|
Layout.preferredWidth: 300 |
|
|
|
Column |
|
|
|
{ |
|
|
|
Layout.fillHeight: true |
|
|
|
Repeater |
|
|
|
{ |
|
|
|
id: trRepeater |
|
|
|
model: transactionsModel |
|
|
|
delegate: transactionRenderDelegate |
|
|
|
visible: transactionsModel.count > 0 |
|
|
|
height: 20 * transactionsModel.count |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Button |
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
iconSource: "qrc:/qml/img/plus.png" |
|
|
|
action: newTrAction |
|
|
|
width: 10 |
|
|
|
height: 10 |
|
|
|
anchors.right: parent.right |
|
|
|
anchors.bottom: parent.bottom |
|
|
|
anchors.right: parent.right; |
|
|
|
|
|
|
|
Button { |
|
|
|
text: qsTr("OK"); |
|
|
|
onClicked: { |
|
|
|
close(); |
|
|
|
accepted(); |
|
|
|
} |
|
|
|
} |
|
|
|
Button { |
|
|
|
text: qsTr("Cancel"); |
|
|
|
onClicked: close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Action { |
|
|
|
id: newTrAction |
|
|
|
tooltip: qsTr("Create a new transaction") |
|
|
|
onTriggered: transactionsModel.addTransaction() |
|
|
|
} |
|
|
|
} |
|
|
|
ListModel { |
|
|
|
id: accountsModel |
|
|
|
|
|
|
|
ScrollView |
|
|
|
{ |
|
|
|
Layout.fillHeight: true |
|
|
|
Layout.preferredWidth: 300 |
|
|
|
Column |
|
|
|
{ |
|
|
|
Layout.fillHeight: true |
|
|
|
Repeater |
|
|
|
function removeAccount(_i) |
|
|
|
{ |
|
|
|
id: trRepeater |
|
|
|
model: transactionsModel |
|
|
|
delegate: transactionRenderDelegate |
|
|
|
visible: transactionsModel.count > 0 |
|
|
|
height: 20 * transactionsModel.count |
|
|
|
accountsModel.remove(_i); |
|
|
|
stateAccounts.splice(_i, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
CommonSeparator |
|
|
|
{ |
|
|
|
Layout.fillWidth: true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
RowLayout |
|
|
|
{ |
|
|
|
anchors.bottom: parent.bottom |
|
|
|
anchors.right: parent.right; |
|
|
|
|
|
|
|
Button { |
|
|
|
text: qsTr("OK"); |
|
|
|
onClicked: { |
|
|
|
acceptAndClose(); |
|
|
|
} |
|
|
|
} |
|
|
|
Button { |
|
|
|
text: qsTr("Cancel"); |
|
|
|
onClicked: close(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ListModel { |
|
|
|
id: accountsModel |
|
|
|
|
|
|
|
function removeAccount(_i) |
|
|
|
{ |
|
|
|
accountsModel.remove(_i); |
|
|
|
stateAccounts.splice(_i, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
ListModel { |
|
|
|
id: transactionsModel |
|
|
|
|
|
|
|
ListModel { |
|
|
|
id: transactionsModel |
|
|
|
function editTransaction(index) { |
|
|
|
transactionDialog.stateAccounts = stateAccounts; |
|
|
|
transactionDialog.open(index, transactionsModel.get(index)); |
|
|
|
} |
|
|
|
|
|
|
|
function editTransaction(index) { |
|
|
|
transactionDialog.stateAccounts = stateAccounts; |
|
|
|
transactionDialog.open(index, transactionsModel.get(index)); |
|
|
|
} |
|
|
|
function addTransaction() { |
|
|
|
|
|
|
|
function addTransaction() { |
|
|
|
// Set next id here to work around Qt bug |
|
|
|
// https://bugreports.qt-project.org/browse/QTBUG-41327 |
|
|
|
// Second call to signal handler would just edit the item that was just created, no harm done |
|
|
|
var item = TransactionHelper.defaultTransaction(); |
|
|
|
transactionDialog.stateAccounts = stateAccounts; |
|
|
|
transactionDialog.open(transactionsModel.count, item); |
|
|
|
} |
|
|
|
|
|
|
|
// Set next id here to work around Qt bug |
|
|
|
// https://bugreports.qt-project.org/browse/QTBUG-41327 |
|
|
|
// Second call to signal handler would just edit the item that was just created, no harm done |
|
|
|
var item = TransactionHelper.defaultTransaction(); |
|
|
|
transactionDialog.stateAccounts = stateAccounts; |
|
|
|
transactionDialog.open(transactionsModel.count, item); |
|
|
|
} |
|
|
|
function deleteTransaction(index) { |
|
|
|
stateTransactions.splice(index, 1); |
|
|
|
transactionsModel.remove(index); |
|
|
|
} |
|
|
|
|
|
|
|
function deleteTransaction(index) { |
|
|
|
stateTransactions.splice(index, 1); |
|
|
|
transactionsModel.remove(index); |
|
|
|
} |
|
|
|
function isUsed(secret) |
|
|
|
{ |
|
|
|
for (var i in stateTransactions) |
|
|
|
{ |
|
|
|
if (stateTransactions[i].sender === secret) |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function isUsed(secret) |
|
|
|
{ |
|
|
|
for (var i in stateTransactions) |
|
|
|
{ |
|
|
|
if (stateTransactions[i].sender === secret) |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
Component { |
|
|
|
id: transactionRenderDelegate |
|
|
|
RowLayout { |
|
|
|
DefaultLabel { |
|
|
|
Layout.preferredWidth: 150 |
|
|
|
text: functionId |
|
|
|
} |
|
|
|
|
|
|
|
Component { |
|
|
|
id: transactionRenderDelegate |
|
|
|
RowLayout { |
|
|
|
DefaultLabel { |
|
|
|
Layout.preferredWidth: 150 |
|
|
|
text: functionId |
|
|
|
} |
|
|
|
Button |
|
|
|
{ |
|
|
|
id: deleteBtn |
|
|
|
iconSource: "qrc:/qml/img/delete_sign.png" |
|
|
|
action: deleteAction |
|
|
|
width: 10 |
|
|
|
height: 10 |
|
|
|
Action { |
|
|
|
id: deleteAction |
|
|
|
tooltip: qsTr("Delete") |
|
|
|
onTriggered: transactionsModel.deleteTransaction(index) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Button |
|
|
|
{ |
|
|
|
id: deleteBtn |
|
|
|
iconSource: "qrc:/qml/img/delete_sign.png" |
|
|
|
action: deleteAction |
|
|
|
width: 10 |
|
|
|
height: 10 |
|
|
|
Action { |
|
|
|
id: deleteAction |
|
|
|
tooltip: qsTr("Delete") |
|
|
|
onTriggered: transactionsModel.deleteTransaction(index) |
|
|
|
Button |
|
|
|
{ |
|
|
|
iconSource: "qrc:/qml/img/edit.png" |
|
|
|
action: editAction |
|
|
|
visible: stdContract === false |
|
|
|
width: 10 |
|
|
|
height: 10 |
|
|
|
Action { |
|
|
|
id: editAction |
|
|
|
tooltip: qsTr("Edit") |
|
|
|
onTriggered: transactionsModel.editTransaction(index) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Button |
|
|
|
{ |
|
|
|
iconSource: "qrc:/qml/img/edit.png" |
|
|
|
action: editAction |
|
|
|
visible: stdContract === false |
|
|
|
width: 10 |
|
|
|
height: 10 |
|
|
|
Action { |
|
|
|
id: editAction |
|
|
|
tooltip: qsTr("Edit") |
|
|
|
onTriggered: transactionsModel.editTransaction(index) |
|
|
|
TransactionDialog |
|
|
|
{ |
|
|
|
id: transactionDialog |
|
|
|
onAccepted: |
|
|
|
{ |
|
|
|
var item = transactionDialog.getItem(); |
|
|
|
|
|
|
|
if (transactionDialog.transactionIndex < transactionsModel.count) { |
|
|
|
transactionsModel.set(transactionDialog.transactionIndex, item); |
|
|
|
stateTransactions[transactionDialog.transactionIndex] = item; |
|
|
|
} else { |
|
|
|
transactionsModel.append(item); |
|
|
|
stateTransactions.push(item); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
TransactionDialog |
|
|
|
{ |
|
|
|
id: transactionDialog |
|
|
|
onAccepted: |
|
|
|
{ |
|
|
|
var item = transactionDialog.getItem(); |
|
|
|
|
|
|
|
if (transactionDialog.transactionIndex < transactionsModel.count) { |
|
|
|
transactionsModel.set(transactionDialog.transactionIndex, item); |
|
|
|
stateTransactions[transactionDialog.transactionIndex] = item; |
|
|
|
} else { |
|
|
|
transactionsModel.append(item); |
|
|
|
stateTransactions.push(item); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|