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.
 
 
 
 
 

416 lines
9.1 KiB

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import org.ethereum.qml.QEther 1.0
import "js/TransactionHelper.js" as TransactionHelper
Window {
id: modalTransactionDialog
modality: Qt.WindowModal
width:640
height:640
visible: false
property int transactionIndex
property alias transactionParams: paramsModel;
property alias gas: gasField.value;
property alias gasPrice: gasPriceField.value;
property alias transactionValue: valueField.value;
property alias functionId: functionComboBox.currentText;
property var itemParams;
property bool isConstructorTransaction;
property bool useTransactionDefaultValue: false
property var qType;
signal accepted;
function open(index, item) {
qType = [];
rowFunction.visible = !useTransactionDefaultValue;
rowValue.visible = !useTransactionDefaultValue;
rowGas.visible = !useTransactionDefaultValue;
rowGasPrice.visible = !useTransactionDefaultValue;
transactionIndex = index;
gasField.value = item.gas;
gasPriceField.value = item.gasPrice;
valueField.value = item.value;
var functionId = item.functionId;
isConstructorTransaction = item.executeConstructor;
rowFunction.visible = !item.executeConstructor;
itemParams = item.parameters !== undefined ? item.parameters : {};
functionsModel.clear();
var functionIndex = -1;
var functions = codeModel.code.contract.functions;
for (var f = 0; f < functions.length; f++) {
functionsModel.append({ text: functions[f].name });
if (functions[f].name === item.functionId)
functionIndex = f;
}
if (functionIndex == -1 && functionsModel.count > 0)
functionIndex = 0; //@todo suggest unused function
functionComboBox.currentIndex = functionIndex;
paramsModel.clear();
if (!item.executeConstructor)
loadParameters();
else
{
var parameters = codeModel.code.contract.constructor.parameters;
for (var p = 0; p < parameters.length; p++) {
var pname = parameters[p].name;
paramsModel.append({ name: pname, type: parameters[p].type, value: itemParams[pname] !== undefined ? itemParams[pname].value() : "" });
}
}
visible = true;
valueField.focus = true;
}
function loadParameters() {
paramsModel.clear();
if (!paramsModel)
return;
if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) {
var func = codeModel.code.contract.functions[functionComboBox.currentIndex];
var parameters = func.parameters;
for (var p = 0; p < parameters.length; p++) {
var pname = parameters[p].name;
var varComponent;
var type = parameters[p].type;
if (type.indexOf("int") !== -1)
varComponent = Qt.createComponent("qrc:/qml/QIntType.qml");
else if (type.indexOf("real") !== -1)
varComponent = Qt.createComponent("qrc:/qml/QRealType.qml");
else if (type.indexOf("string") !== -1 || type.indexOf("text") !== -1)
varComponent = Qt.createComponent("qrc:/qml/QStringType.qml");
else if (type.indexOf("hash") !== -1 || type.indexOf("address") !== -1)
varComponent = Qt.createComponent("qrc:/qml/QHashType.qml");
else if (type.indexOf("bool") !== -1)
varComponent = Qt.createComponent("qrc:/qml/QBoolType.qml");
var param = varComponent.createObject(modalTransactionDialog);
var value = itemParams[pname] !== undefined ? itemParams[pname] : "";
param.setValue(value);
param.setDeclaration(parameters[p]);
qType.push({ name: pname, value: param });
paramsModel.append({ name: pname, type: parameters[p].type, value: value });
}
}
}
function close()
{
visible = false;
}
function qTypeParam(name)
{
for (var k in qType)
{
if (qType[k].name === name)
return qType[k].value;
}
}
function getItem()
{
var item;
if (!useTransactionDefaultValue)
{
item = {
functionId: transactionDialog.functionId,
gas: transactionDialog.gas,
gasPrice: transactionDialog.gasPrice,
value: transactionDialog.transactionValue,
parameters: {},
executeConstructor: isConstructorTransaction
};
}
else
{
item = TransactionHelper.defaultTransaction();
item.functionId = transactionDialog.functionId;
item.executeConstructor = isConstructorTransaction;
}
if (isConstructorTransaction)
item.functionId = qsTr("Constructor");
var orderedQType = [];
for (var p = 0; p < transactionDialog.transactionParams.count; p++) {
var parameter = transactionDialog.transactionParams.get(p);
var qtypeParam = qTypeParam(parameter.name);
qtypeParam.setValue(parameter.value);
orderedQType.push(qtypeParam);
item.parameters[parameter.name] = parameter.value;
}
item.qType = orderedQType;
return item;
}
ColumnLayout {
id: dialogContent
width: parent.width
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 10
spacing: 30
RowLayout
{
id: rowFunction
Layout.fillWidth: true
height: 150
Label {
Layout.preferredWidth: 75
text: qsTr("Function")
}
ComboBox {
id: functionComboBox
Layout.fillWidth: true
currentIndex: -1
textRole: "text"
editable: false
model: ListModel {
id: functionsModel
}
onCurrentIndexChanged: {
loadParameters();
}
}
}
RowLayout
{
id: rowValue
Layout.fillWidth: true
Label {
Layout.preferredWidth: 75
text: qsTr("Value")
}
Rectangle
{
Layout.fillWidth: true
Ether {
id: valueField
edit: true
displayFormattedValue: true
}
}
}
RowLayout
{
id: rowGas
Layout.fillWidth: true
Label {
Layout.preferredWidth: 75
text: qsTr("Gas")
}
Rectangle
{
Layout.fillWidth: true
Ether {
id: gasField
edit: true
displayFormattedValue: true
}
}
}
RowLayout
{
id: rowGasPrice
Layout.fillWidth: true
Label {
Layout.preferredWidth: 75
text: qsTr("Gas Price")
}
Rectangle
{
Layout.fillWidth: true
Ether {
id: gasPriceField
edit: true
displayFormattedValue: true
}
}
}
RowLayout
{
Layout.fillWidth: true
Label {
text: qsTr("Parameters")
Layout.preferredWidth: 75
}
TableView {
model: paramsModel
Layout.preferredWidth: 120 * 2 + 240
Layout.minimumHeight: 150
Layout.preferredHeight: 400
Layout.maximumHeight: 600
TableViewColumn {
role: "name"
title: qsTr("Name")
width: 120
}
TableViewColumn {
role: "type"
title: qsTr("Type")
width: 120
}
TableViewColumn {
role: "value"
title: qsTr("Value")
width: 240
}
rowDelegate: rowDelegate
itemDelegate: editableDelegate
}
}
}
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
Button {
text: qsTr("OK");
onClicked: {
close();
accepted();
}
}
Button {
text: qsTr("Cancel");
onClicked: close();
}
}
ListModel {
id: paramsModel
}
Component {
id: rowDelegate
Item {
height: 100
}
}
Component {
id: editableDelegate
Item {
Loader {
id: loaderEditor
anchors.fill: parent
anchors.margins: 4
Connections {
target: loaderEditor.item
onTextChanged: {
if (styleData.role === "value" && styleData.row < paramsModel.count)
loaderEditor.updateValue(styleData.row, styleData.role, loaderEditor.item.text);
}
}
function updateValue(row, role, value)
{
paramsModel.setProperty(styleData.row, styleData.role, value);
}
sourceComponent:
{
if (styleData.role === "value")
{
if (paramsModel.get(styleData.row) === undefined)
return null;
if (paramsModel.get(styleData.row).type.indexOf("int") !== -1)
return intViewComp;
else if (paramsModel.get(styleData.row).type.indexOf("bool") !== -1)
return boolViewComp;
else if (paramsModel.get(styleData.row).type.indexOf("string") !== -1)
return stringViewComp;
else if (paramsModel.get(styleData.row).type.indexOf("hash") !== -1)
return hashViewComp;
}
else
return editor;
}
Component
{
id: intViewComp
QIntTypeView
{
id: intView
text: styleData.value
}
}
Component
{
id: boolViewComp
QBoolTypeView
{
id: boolView
defaultValue: "1"
Component.onCompleted:
{
loaderEditor.updateValue(styleData.row, styleData.role,
(paramsModel.get(styleData.row).value === "" ? defaultValue :
paramsModel.get(styleData.row).value));
text = (paramsModel.get(styleData.row).value === "" ? defaultValue : paramsModel.get(styleData.row).value);
}
}
}
Component
{
id: stringViewComp
QStringTypeView
{
id: stringView
text: styleData.value
}
}
Component
{
id: hashViewComp
QHashTypeView
{
id: hashView
text: styleData.value
}
}
Component {
id: editor
TextInput {
id: textinput
readOnly: true
color: styleData.textColor
text: styleData.value
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: textinput.forceActiveFocus()
}
}
}
}
}
}
}