Gav Wood
10 years ago
56 changed files with 4361 additions and 582 deletions
@ -1 +1 @@ |
|||
Subproject commit 66d5a2b5cdf1361dcf0205b191dd12be090ed224 |
|||
Subproject commit 3df5a125fa0baa579528abce80402118cad803fd |
@ -0,0 +1,171 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file AssemblyDebuggerControl.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* display opcode debugging. |
|||
*/ |
|||
|
|||
#include <QtConcurrent/QtConcurrent> |
|||
#include <QDebug> |
|||
#include <QVariableDefinition.h> |
|||
#include <QQmlContext> |
|||
#include <QModelIndex> |
|||
#include <libdevcore/CommonJS.h> |
|||
#include <libethereum/Transaction.h> |
|||
#include "AssemblyDebuggerModel.h" |
|||
#include "AssemblyDebuggerControl.h" |
|||
#include "KeyEventManager.h" |
|||
#include "AppContext.h" |
|||
#include "DebuggingStateWrapper.h" |
|||
#include "TransactionListModel.h" |
|||
#include "QContractDefinition.h" |
|||
#include "QVariableDeclaration.h" |
|||
#include "ContractCallDataEncoder.h" |
|||
using namespace dev::eth; |
|||
using namespace dev::mix; |
|||
|
|||
AssemblyDebuggerControl::AssemblyDebuggerControl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) |
|||
{ |
|||
qRegisterMetaType<QVariableDefinition*>("QVariableDefinition*"); |
|||
qRegisterMetaType<QVariableDefinitionList*>("QVariableDefinitionList*"); |
|||
qRegisterMetaType<QList<QVariableDefinition*>>("QList<QVariableDefinition*>"); |
|||
qRegisterMetaType<QList<QVariableDeclaration*>>("QList<QVariableDeclaration*>"); |
|||
qRegisterMetaType<QVariableDeclaration*>("QVariableDeclaration*"); |
|||
qRegisterMetaType<AssemblyDebuggerData>("AssemblyDebuggerData"); |
|||
qRegisterMetaType<DebuggingStatusResult>("DebuggingStatusResult"); |
|||
|
|||
connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), |
|||
this, SLOT(updateGUI(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), Qt::QueuedConnection); |
|||
|
|||
m_modelDebugger = std::unique_ptr<AssemblyDebuggerModel>(new AssemblyDebuggerModel); |
|||
m_compilation = std::unique_ptr<ConstantCompilationModel>(new ConstantCompilationModel); |
|||
m_doc = _doc; |
|||
} |
|||
|
|||
QString AssemblyDebuggerControl::contentUrl() const |
|||
{ |
|||
return QStringLiteral("qrc:/qml/Debugger.qml"); |
|||
} |
|||
|
|||
QString AssemblyDebuggerControl::title() const |
|||
{ |
|||
return QApplication::tr("debugger"); |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::start() const |
|||
{ |
|||
//start to listen on F5
|
|||
m_ctx->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::keyPressed(int _key) |
|||
{ |
|||
if (_key == Qt::Key_F5) |
|||
{ |
|||
QtConcurrent::run([this]() |
|||
{ |
|||
deployContract(m_doc->toPlainText()); |
|||
}); |
|||
} |
|||
else if (_key == Qt::Key_F6) |
|||
{ |
|||
m_modelDebugger->resetState(); |
|||
AppContext::getInstance()->displayMessageDialog(QApplication::tr("State status"), QApplication::tr("State reseted ... need to redeploy contract")); |
|||
} |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::callContract(TransactionSettings _tr, dev::Address _contract) |
|||
{ |
|||
CompilerResult compilerRes = m_compilation->compile(m_doc->toPlainText()); |
|||
if (!compilerRes.success) |
|||
AppContext::getInstance()->displayMessageDialog("debugger","compilation failed"); |
|||
else |
|||
{ |
|||
ContractCallDataEncoder c; |
|||
std::shared_ptr<QContractDefinition> contractDef = QContractDefinition::Contract(m_doc->toPlainText()); |
|||
QFunctionDefinition* f = nullptr; |
|||
for (int k = 0; k < contractDef->functions().size(); k++) |
|||
{ |
|||
if (contractDef->functions().at(k)->name() == _tr.functionId) |
|||
{ |
|||
f = (QFunctionDefinition*)contractDef->functions().at(k); |
|||
break; |
|||
} |
|||
} |
|||
if (!f) |
|||
AppContext::getInstance()->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("function not found. Please redeploy this contract.")); |
|||
else |
|||
{ |
|||
c.encode(f->index()); |
|||
for (int k = 0; k < f->parameters().size(); k++) |
|||
{ |
|||
QVariableDeclaration* var = (QVariableDeclaration*)f->parameters().at(k); |
|||
c.encode(var, _tr.parameterValues[var->name()]); |
|||
} |
|||
DebuggingContent debuggingContent = m_modelDebugger->callContract(_contract, c.encodedData(), _tr); |
|||
debuggingContent.returnParameters = c.decode(f->returnParameters(), debuggingContent.returnValue); |
|||
finalizeExecution(debuggingContent); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::deployContract(QString _source) |
|||
{ |
|||
CompilerResult compilerRes = m_compilation->compile(_source); |
|||
if (!compilerRes.success) |
|||
emit dataAvailable(false, DebuggingStatusResult::Compilationfailed); |
|||
else |
|||
{ |
|||
m_previousDebugResult = m_modelDebugger->deployContract(compilerRes.bytes); |
|||
finalizeExecution(m_previousDebugResult); |
|||
} |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::finalizeExecution(DebuggingContent _debuggingContent) |
|||
{ |
|||
//we need to wrap states in a QObject before sending to QML.
|
|||
QList<QObject*> wStates; |
|||
for(int i = 0; i < _debuggingContent.machineStates.size(); i++) |
|||
{ |
|||
QPointer<DebuggingStateWrapper> s(new DebuggingStateWrapper(_debuggingContent.executionCode, _debuggingContent.executionData.toBytes())); |
|||
s->setState(_debuggingContent.machineStates.at(i)); |
|||
wStates.append(s); |
|||
} |
|||
AssemblyDebuggerData code = DebuggingStateWrapper::getHumanReadableCode(_debuggingContent.executionCode); |
|||
emit dataAvailable(true, DebuggingStatusResult::Ok, _debuggingContent.returnParameters, wStates, code); |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParam, QList<QObject*> const& _wStates, AssemblyDebuggerData const& _code) |
|||
{ |
|||
Q_UNUSED(_reason); |
|||
if (_success) |
|||
{ |
|||
m_appEngine->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); |
|||
m_appEngine->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); |
|||
m_appEngine->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); |
|||
m_appEngine->rootContext()->setContextProperty("contractCallReturnParameters", QVariant::fromValue(new QVariableDefinitionList(_returnParam))); |
|||
this->addContentOn(this); |
|||
} |
|||
else |
|||
m_ctx->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("compilation failed")); |
|||
} |
|||
|
|||
void AssemblyDebuggerControl::runTransaction(TransactionSettings const& _tr) |
|||
{ |
|||
QtConcurrent::run([this, _tr]() |
|||
{ |
|||
callContract(_tr, m_previousDebugResult.contractAddress); |
|||
}); |
|||
} |
@ -0,0 +1,84 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file AssemblyDebuggerControl.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Extension which display debugging steps in assembly code. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QKeySequence> |
|||
#include <QTextDocument> |
|||
#include "Extension.h" |
|||
#include "ConstantCompilationModel.h" |
|||
#include "TransactionListModel.h" |
|||
#include "AssemblyDebuggerModel.h" |
|||
#include "AppContext.h" |
|||
|
|||
using AssemblyDebuggerData = std::tuple<QList<QObject*>, dev::mix::QQMLMap*>; |
|||
enum DebuggingStatusResult |
|||
{ |
|||
Ok, |
|||
Compilationfailed |
|||
}; |
|||
|
|||
Q_DECLARE_METATYPE(AssemblyDebuggerData) |
|||
Q_DECLARE_METATYPE(DebuggingStatusResult) |
|||
Q_DECLARE_METATYPE(dev::mix::DebuggingContent) |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
/**
|
|||
* @brief Extension which display transaction creation or transaction call debugging. handle: F5 to deploy contract, F6 to reset state. |
|||
*/ |
|||
class AssemblyDebuggerControl: public Extension |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
AssemblyDebuggerControl(QTextDocument* _doc); |
|||
~AssemblyDebuggerControl() {} |
|||
void start() const override; |
|||
QString title() const override; |
|||
QString contentUrl() const override; |
|||
|
|||
private: |
|||
void deployContract(QString _source); |
|||
void callContract(TransactionSettings _tr, Address _contract); |
|||
void finalizeExecution(DebuggingContent _content); |
|||
|
|||
std::unique_ptr<AssemblyDebuggerModel> m_modelDebugger; |
|||
std::unique_ptr<ConstantCompilationModel> m_compilation; |
|||
DebuggingContent m_previousDebugResult; //TODO: to be replaced in a more consistent struct. Used for now to keep the contract address in case of future transaction call.
|
|||
QTextDocument* m_doc; |
|||
|
|||
public slots: |
|||
/// Handle key pressed. F5 deploy contract - F6 reset state.
|
|||
void keyPressed(int); |
|||
/// Update UI with machine states result. Display a modal dialog.
|
|||
void updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData()); |
|||
/// Run the given transaction.
|
|||
void runTransaction(TransactionSettings const& _tr); |
|||
|
|||
signals: |
|||
/// Emited when machine states are available.
|
|||
void dataAvailable(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData()); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,103 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file AssemblyDebuggerCtrl.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* display opcode debugging. |
|||
*/ |
|||
|
|||
#include <QtConcurrent/QtConcurrent> |
|||
#include <QDebug> |
|||
#include <QQmlContext> |
|||
#include <QModelIndex> |
|||
#include "libethereum/Transaction.h" |
|||
#include "AssemblyDebuggerModel.h" |
|||
#include "AssemblyDebuggerCtrl.h" |
|||
#include "TransactionBuilder.h" |
|||
#include "KeyEventManager.h" |
|||
#include "AppContext.h" |
|||
#include "DebuggingStateWrapper.h" |
|||
using namespace dev::mix; |
|||
|
|||
AssemblyDebuggerCtrl::AssemblyDebuggerCtrl(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::ModalDialog) |
|||
{ |
|||
qRegisterMetaType<AssemblyDebuggerData>(); |
|||
qRegisterMetaType<DebuggingStatusResult>(); |
|||
connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QObject*>, AssemblyDebuggerData)), |
|||
this, SLOT(updateGUI(bool, DebuggingStatusResult, QList<QObject*>, AssemblyDebuggerData)), Qt::QueuedConnection); |
|||
m_modelDebugger = std::unique_ptr<AssemblyDebuggerModel>(new AssemblyDebuggerModel); |
|||
m_doc = _doc; |
|||
} |
|||
|
|||
QString AssemblyDebuggerCtrl::contentUrl() const |
|||
{ |
|||
return QStringLiteral("qrc:/qml/Debugger.qml"); |
|||
} |
|||
|
|||
QString AssemblyDebuggerCtrl::title() const |
|||
{ |
|||
return QApplication::tr("debugger"); |
|||
} |
|||
|
|||
void AssemblyDebuggerCtrl::start() const |
|||
{ |
|||
//start to listen on F5
|
|||
m_ctx->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int))); |
|||
} |
|||
|
|||
void AssemblyDebuggerCtrl::keyPressed(int _key) |
|||
{ |
|||
if (_key == Qt::Key_F5) |
|||
{ |
|||
QString code = m_doc->toPlainText(); |
|||
QtConcurrent::run([this, code]() |
|||
{ |
|||
if (!m_modelDebugger->compile(m_doc->toPlainText())) |
|||
{ |
|||
emit dataAvailable(false, DebuggingStatusResult::Compilationfailed); |
|||
return; |
|||
} |
|||
|
|||
u256 gasPrice = 10000000000000; |
|||
u256 gas = 1000000; |
|||
u256 amount = 100; |
|||
DebuggingContent debuggingContent = m_modelDebugger->getContractInitiationDebugStates(amount, gasPrice, gas, m_doc->toPlainText()); |
|||
|
|||
//we need to wrap states in a QObject before sending to QML.
|
|||
QList<QObject*> wStates; |
|||
for(int i = 0; i < debuggingContent.states.size(); i++) |
|||
{ |
|||
DebuggingStateWrapper* s = new DebuggingStateWrapper(debuggingContent.executionCode, debuggingContent.executionData.toBytes(), this); |
|||
s->setState(debuggingContent.states.at(i)); |
|||
wStates.append(s); |
|||
} |
|||
AssemblyDebuggerData code = DebuggingStateWrapper::getHumanReadableCode(debuggingContent.executionCode, this); |
|||
emit dataAvailable(true, DebuggingStatusResult::Ok, wStates, code); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
void AssemblyDebuggerCtrl::updateGUI(bool success, DebuggingStatusResult reason, QList<QObject*> _wStates, AssemblyDebuggerData _code) |
|||
{ |
|||
Q_UNUSED(reason); |
|||
if (success) |
|||
{ |
|||
m_appEngine->rootContext()->setContextProperty("debugStates", QVariant::fromValue(_wStates)); |
|||
m_appEngine->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); |
|||
m_appEngine->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); |
|||
this->addContentOn(this); |
|||
} |
|||
else |
|||
m_ctx->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("compilation failed")); |
|||
} |
@ -1,70 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file AssemblyDebuggerCtrl.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QKeySequence> |
|||
#include "QTextDocument" |
|||
#include "Extension.h" |
|||
#include "ConstantCompilationModel.h" |
|||
#include "AssemblyDebuggerModel.h" |
|||
#include "AppContext.h" |
|||
|
|||
using AssemblyDebuggerData = std::tuple<QList<QObject*>, dev::mix::QQMLMap*>; |
|||
enum DebuggingStatusResult |
|||
{ |
|||
Ok, |
|||
Compilationfailed |
|||
}; |
|||
|
|||
Q_DECLARE_METATYPE(AssemblyDebuggerData) |
|||
Q_DECLARE_METATYPE(DebuggingStatusResult) |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class AssemblyDebuggerCtrl: public Extension |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
AssemblyDebuggerCtrl(QTextDocument*); |
|||
~AssemblyDebuggerCtrl() {} |
|||
void start() const override; |
|||
QString title() const override; |
|||
QString contentUrl() const override; |
|||
|
|||
private: |
|||
std::unique_ptr<AssemblyDebuggerModel> m_modelDebugger; |
|||
QTextDocument* m_doc; |
|||
|
|||
public slots: |
|||
void keyPressed(int); |
|||
void updateGUI(bool success, DebuggingStatusResult reason, QList<QObject*> _wStates = QList<QObject*>(), AssemblyDebuggerData _code = AssemblyDebuggerData()); |
|||
|
|||
signals: |
|||
void dataAvailable(bool success, DebuggingStatusResult reason, QList<QObject*> _wStates = QList<QObject*>(), AssemblyDebuggerData _code = AssemblyDebuggerData()); |
|||
|
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,131 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file ContractCallDataEncoder.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#include <QDebug> |
|||
#include <QMap> |
|||
#include <QStringList> |
|||
#include <libdevcore/CommonJS.h> |
|||
#include <libsolidity/AST.h> |
|||
#include "QVariableDeclaration.h" |
|||
#include "QVariableDefinition.h" |
|||
#include "ContractCallDataEncoder.h" |
|||
using namespace dev; |
|||
using namespace dev::solidity; |
|||
using namespace dev::mix; |
|||
|
|||
bytes ContractCallDataEncoder::encodedData() |
|||
{ |
|||
return m_encodedData; |
|||
} |
|||
|
|||
void ContractCallDataEncoder::encode(int _functionIndex) |
|||
{ |
|||
bytes i = jsToBytes(std::to_string(_functionIndex)); |
|||
m_encodedData.insert(m_encodedData.end(), i.begin(), i.end()); |
|||
} |
|||
|
|||
void ContractCallDataEncoder::encode(QVariableDeclaration* _dec, bool _value) |
|||
{ |
|||
return encode(_dec, QString(formatBool(_value))); |
|||
} |
|||
|
|||
void ContractCallDataEncoder::encode(QVariableDeclaration* _dec, QString _value) |
|||
{ |
|||
int padding = this->padding(_dec->type()); |
|||
bytes data = padded(jsToBytes(_value.toStdString()), padding); |
|||
m_encodedData.insert(m_encodedData.end(), data.begin(), data.end()); |
|||
} |
|||
|
|||
void ContractCallDataEncoder::encode(QVariableDeclaration* _dec, u256 _value) |
|||
{ |
|||
int padding = this->padding(_dec->type()); |
|||
std::ostringstream s; |
|||
s << std::hex << "0x" << _value; |
|||
bytes data = padded(jsToBytes(s.str()), padding); |
|||
m_encodedData.insert(m_encodedData.end(), data.begin(), data.end()); |
|||
encodedData(); |
|||
} |
|||
|
|||
QList<QVariableDefinition*> ContractCallDataEncoder::decode(QList<QVariableDeclaration*> _returnParameters, bytes _value) |
|||
{ |
|||
QList<QVariableDefinition*> r; |
|||
std::string returnValue = toJS(_value); |
|||
returnValue = returnValue.substr(2, returnValue.length() - 1); |
|||
for (int k = 0; k <_returnParameters.length(); k++) |
|||
{ |
|||
QVariableDeclaration* dec = (QVariableDeclaration*)_returnParameters.at(k); |
|||
int padding = this->padding(dec->type()); |
|||
std::string rawParam = returnValue.substr(0, padding * 2); |
|||
r.append(new QVariableDefinition(dec, convertToReadable(unpadLeft(rawParam), dec))); |
|||
returnValue = returnValue.substr(rawParam.length(), returnValue.length() - 1); |
|||
} |
|||
return r; |
|||
} |
|||
|
|||
int ContractCallDataEncoder::padding(QString type) |
|||
{ |
|||
// TODO : to be improved (load types automatically from solidity library).
|
|||
if (type.indexOf("uint") != -1) |
|||
return integerPadding(type.remove("uint").toInt()); |
|||
else if (type.indexOf("int") != -1) |
|||
return integerPadding(type.remove("int").toInt()); |
|||
else if (type.indexOf("bool") != -1) |
|||
return 1; |
|||
else if ((type.indexOf("address") != -1)) |
|||
return 20; |
|||
else |
|||
return 0; |
|||
} |
|||
|
|||
int ContractCallDataEncoder::integerPadding(int bitValue) |
|||
{ |
|||
return bitValue / 8; |
|||
} |
|||
|
|||
QString ContractCallDataEncoder::formatBool(bool _value) |
|||
{ |
|||
return (_value ? "1" : "0"); |
|||
} |
|||
|
|||
QString ContractCallDataEncoder::convertToReadable(std::string _v, QVariableDeclaration* _dec) |
|||
{ |
|||
if (_dec->type().indexOf("int") != -1) |
|||
return convertToInt(_v); |
|||
else if (_dec->type().indexOf("bool") != -1) |
|||
return convertToBool(_v); |
|||
else |
|||
return QString::fromStdString(_v); |
|||
} |
|||
|
|||
QString ContractCallDataEncoder::convertToBool(std::string _v) |
|||
{ |
|||
return _v == "1" ? "true" : "false"; |
|||
} |
|||
|
|||
QString ContractCallDataEncoder::convertToInt(std::string _v) |
|||
{ |
|||
//TO DO to be improve to manage all int, uint size (128, 256, ...) in ethereum QML types task #612.
|
|||
int x = std::stol(_v, nullptr, 16); |
|||
std::stringstream ss; |
|||
ss << std::dec << x; |
|||
return QString::fromStdString(ss.str()); |
|||
} |
@ -0,0 +1,64 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file ContractCallDataEncoder.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include "QVariableDeclaration.h" |
|||
#include "QVariableDefinition.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
/**
|
|||
* @brief Encode/Decode data to be sent to a transaction or to be displayed in a view. |
|||
*/ |
|||
class ContractCallDataEncoder |
|||
{ |
|||
public: |
|||
ContractCallDataEncoder() {} |
|||
/// Encode variable in order to be sent as parameter.
|
|||
void encode(QVariableDeclaration* _dec, QString _value); |
|||
/// Encode variable in order to be sent as parameter.
|
|||
void encode(QVariableDeclaration* _dec, u256 _value); |
|||
/// Encode variable in order to be sent as parameter.
|
|||
void encode(QVariableDeclaration* _dec, bool _value); |
|||
/// Encode index of the function to call.
|
|||
void encode(int _functionIndex); |
|||
/// Decode variable in order to be sent to QML view.
|
|||
QList<QVariableDefinition*> decode(QList<QVariableDeclaration*> _dec, bytes _value); |
|||
/// Get all encoded data encoded by encode function.
|
|||
bytes encodedData(); |
|||
|
|||
private: |
|||
int padding(QString _type); |
|||
bytes m_encodedData; |
|||
static QString convertToReadable(std::string _v, QVariableDeclaration* _dec); |
|||
static QString convertToBool(std::string _v); |
|||
static QString convertToInt(std::string _v); |
|||
static int integerPadding(int _bitValue); |
|||
static QString formatBool(bool _value); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,43 +1,49 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TransactionBuilder.h
|
|||
/** @file QBasicNodeDefinition.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QString> |
|||
#include "libdevcore/Common.h" |
|||
#include "libethereum/Transaction.h" |
|||
#include <QObject> |
|||
#include <libsolidity/AST.h> |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class TransactionBuilder |
|||
class QBasicNodeDefinition: public QObject |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(QString name READ name CONSTANT) |
|||
|
|||
public: |
|||
TransactionBuilder() {} |
|||
dev::eth::Transaction getBasicTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, |
|||
QString address, bytes _data, dev::u256 _nonce, Secret _secret) const; |
|||
dev::eth::Transaction getCreationTransaction(dev::u256 _value, dev::u256 _gasPrice, dev::u256 _gas, |
|||
dev::bytes _data, dev::u256 _nonce, Secret _secret) const; |
|||
QBasicNodeDefinition(): QObject() {} |
|||
~QBasicNodeDefinition() {} |
|||
QBasicNodeDefinition(solidity::Declaration const* _d): QObject(), m_name(QString::fromStdString(_d->getName())) {} |
|||
/// Get the name of the node.
|
|||
QString name() const { return m_name; } |
|||
|
|||
private: |
|||
QString m_name; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,48 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QContractDefinition.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include <QObject> |
|||
#include <libsolidity/CompilerStack.h> |
|||
#include <libsolidity/AST.h> |
|||
#include <libsolidity/Scanner.h> |
|||
#include <libsolidity/Parser.h> |
|||
#include <libsolidity/Scanner.h> |
|||
#include <libsolidity/NameAndTypeResolver.h> |
|||
#include "AppContext.h" |
|||
#include "QContractDefinition.h" |
|||
using namespace dev::solidity; |
|||
using namespace dev::mix; |
|||
|
|||
std::shared_ptr<QContractDefinition> QContractDefinition::Contract(QString _source) |
|||
{ |
|||
CompilerStack* comp = AppContext::getInstance()->compiler(); |
|||
comp->addSource("contract", _source.toStdString()); |
|||
comp->parse(); |
|||
ContractDefinition const* def = &comp->getContractDefinition(comp->getContractNames().front()); |
|||
return std::make_shared<QContractDefinition>(def); |
|||
} |
|||
|
|||
void QContractDefinition::initQFunctions() |
|||
{ |
|||
std::vector<FunctionDefinition const*> functions = m_contract->getInterfaceFunctions(); |
|||
for (unsigned i = 0; i < functions.size(); i++) |
|||
m_functions.append(new QFunctionDefinition(functions.at(i), i)); |
|||
} |
@ -0,0 +1,53 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QContractDefinition.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QObject> |
|||
#include <libsolidity/AST.h> |
|||
#include "QFunctionDefinition.h" |
|||
#include "QBasicNodeDefinition.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class QContractDefinition: public QBasicNodeDefinition |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(QList<QFunctionDefinition*> functions READ functions) |
|||
|
|||
public: |
|||
QContractDefinition(solidity::ContractDefinition const* _contract): QBasicNodeDefinition(_contract), m_contract(_contract) { initQFunctions(); } |
|||
/// Get all the functions of the contract.
|
|||
QList<QFunctionDefinition*> functions() const { return m_functions; } |
|||
/// Get the description (functions, parameters, return parameters, ...) of the contract describes by _code.
|
|||
static std::shared_ptr<QContractDefinition> Contract(QString _code); |
|||
|
|||
private: |
|||
solidity::ContractDefinition const* m_contract; |
|||
QList<QFunctionDefinition*> m_functions; |
|||
void initQFunctions(); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,37 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QFunctionDefinition.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include <libsolidity/AST.h> |
|||
#include "QVariableDeclaration.h" |
|||
#include "QFunctionDefinition.h" |
|||
using namespace dev::solidity; |
|||
using namespace dev::mix; |
|||
|
|||
void QFunctionDefinition::initQParameters() |
|||
{ |
|||
std::vector<std::shared_ptr<VariableDeclaration>> parameters = m_functions->getParameterList().getParameters(); |
|||
for (unsigned i = 0; i < parameters.size(); i++) |
|||
m_parameters.append(new QVariableDeclaration(parameters.at(i).get())); |
|||
|
|||
std::vector<std::shared_ptr<VariableDeclaration>> returnParameters = m_functions->getReturnParameters(); |
|||
for (unsigned i = 0; i < returnParameters.size(); i++) |
|||
m_returnParameters.append(new QVariableDeclaration(returnParameters.at(i).get())); |
|||
} |
@ -0,0 +1,58 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QFunctionDefinition.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QObject> |
|||
#include <libsolidity/AST.h> |
|||
#include <QVariableDeclaration.h> |
|||
#include "QBasicNodeDefinition.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class QFunctionDefinition: public QBasicNodeDefinition |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(QList<QVariableDeclaration*> parameters READ parameters) |
|||
Q_PROPERTY(int index READ index) |
|||
|
|||
public: |
|||
QFunctionDefinition(solidity::FunctionDefinition const* _f, int _index): QBasicNodeDefinition(_f), m_index(_index), m_functions(_f) { initQParameters(); } |
|||
/// Get all input parameters of this function.
|
|||
QList<QVariableDeclaration*> parameters() const { return m_parameters; } |
|||
/// Get all return parameters of this function.
|
|||
QList<QVariableDeclaration*> returnParameters() const { return m_returnParameters; } |
|||
/// Get the index of this function on the contract ABI.
|
|||
int index() const { return m_index; } |
|||
|
|||
private: |
|||
int m_index; |
|||
solidity::FunctionDefinition const* m_functions; |
|||
QList<QVariableDeclaration*> m_parameters; |
|||
QList<QVariableDeclaration*> m_returnParameters; |
|||
void initQParameters(); |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,49 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QVariableDeclaration.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include <libsolidity/AST.h> |
|||
#include "QBasicNodeDefinition.h" |
|||
|
|||
#pragma once |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class QVariableDeclaration: public QBasicNodeDefinition |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(QString type READ type CONSTANT) |
|||
|
|||
public: |
|||
QVariableDeclaration(solidity::VariableDeclaration const* _v): QBasicNodeDefinition(_v), m_variable(_v) {} |
|||
/// Get the type of this variable.
|
|||
QString type() const { return QString::fromStdString(m_variable->getType()->toString()); } |
|||
|
|||
private: |
|||
solidity::VariableDeclaration const* m_variable; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
Q_DECLARE_METATYPE(dev::mix::QVariableDeclaration*) |
@ -0,0 +1,55 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QVariableDefinition.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#include "QVariableDefinition.h" |
|||
|
|||
using namespace dev::mix; |
|||
int QVariableDefinitionList::rowCount(const QModelIndex& _parent) const |
|||
{ |
|||
Q_UNUSED(_parent); |
|||
return m_def.size(); |
|||
} |
|||
|
|||
QVariant QVariableDefinitionList::data(const QModelIndex& _index, int _role) const |
|||
{ |
|||
if (_role != Qt::DisplayRole) |
|||
return QVariant(); |
|||
|
|||
int i = _index.row(); |
|||
if (i < 0 || i >= m_def.size()) |
|||
return QVariant(QVariant::Invalid); |
|||
|
|||
return QVariant::fromValue(m_def.at(i)); |
|||
} |
|||
|
|||
QHash<int, QByteArray> QVariableDefinitionList::roleNames() const |
|||
{ |
|||
QHash<int, QByteArray> roles; |
|||
roles[Qt::DisplayRole] = "variable"; |
|||
return roles; |
|||
} |
|||
|
|||
QVariableDefinition* QVariableDefinitionList::val(int _idx) |
|||
{ |
|||
if (_idx < 0 || _idx >= m_def.size()) |
|||
return nullptr; |
|||
return m_def.at(_idx); |
|||
} |
@ -0,0 +1,72 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file QVariableDefinition.h
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QAbstractListModel> |
|||
#include "QVariableDeclaration.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class QVariableDefinition: public QObject |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(QString value READ value CONSTANT) |
|||
Q_PROPERTY(QVariableDeclaration* declaration READ declaration CONSTANT) |
|||
|
|||
public: |
|||
QVariableDefinition(QVariableDeclaration* _def, QString _value): QObject(), m_value(_value), m_dec(_def) {} |
|||
|
|||
/// Return the associated declaration of this variable definition.
|
|||
QVariableDeclaration* declaration() const { return m_dec; } |
|||
/// Return the variable value.
|
|||
QString value() const { return m_value; } |
|||
|
|||
private: |
|||
QString m_value; |
|||
QVariableDeclaration* m_dec; |
|||
}; |
|||
|
|||
class QVariableDefinitionList: public QAbstractListModel |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
QVariableDefinitionList(QList<QVariableDefinition*> _def): m_def(_def) {} |
|||
int rowCount(const QModelIndex& parent = QModelIndex()) const override; |
|||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; |
|||
QHash<int, QByteArray> roleNames() const override; |
|||
/// Return the variable definition at index _idx.
|
|||
QVariableDefinition* val(int _idx); |
|||
/// Return the list of variables.
|
|||
QList<QVariableDefinition*> def() { return m_def; } |
|||
|
|||
private: |
|||
QList<QVariableDefinition*> m_def; |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
Q_DECLARE_METATYPE(dev::mix::QVariableDefinition*) |
@ -1,40 +0,0 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TransactionBuilder.cpp
|
|||
* @author Yann yann@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#include "libethereum/Executive.h" |
|||
#include "libdevcore/CommonJS.h" |
|||
#include "libdevcore/Common.h" |
|||
#include "AppContext.h" |
|||
#include "TransactionBuilder.h" |
|||
using namespace dev::mix; |
|||
using namespace dev::eth; |
|||
using namespace dev; |
|||
|
|||
Transaction TransactionBuilder::getCreationTransaction(u256 _value, u256 _gasPrice, u256 _gas, |
|||
bytes _data, u256 _nonce, Secret _secret) const |
|||
{ |
|||
return Transaction(_value, _gasPrice, _gas, _data, _nonce, _secret); |
|||
} |
|||
|
|||
Transaction TransactionBuilder::getBasicTransaction(u256 _value, u256 _gasPrice, u256 _gas, |
|||
QString _address, bytes _data, u256 _nonce, Secret _secret) const |
|||
{ |
|||
return Transaction(_value, _gasPrice, _gas, dev::fromString(_address.toStdString()), _data, _nonce, _secret); |
|||
} |
|||
|
@ -0,0 +1,221 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TransactionListModel.cpp
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#include <QObject> |
|||
#include <QQmlEngine> |
|||
#include <QTextDocument> |
|||
#include <QAbstractListModel> |
|||
#include <libdevcore/CommonJS.h> |
|||
#include "TransactionListModel.h" |
|||
#include "QContractDefinition.h" |
|||
#include "QFunctionDefinition.h" |
|||
#include "QVariableDeclaration.h" |
|||
|
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
/// @todo Move this to QML
|
|||
u256 fromQString(QString const& _s) |
|||
{ |
|||
return dev::jsToU256(_s.toStdString()); |
|||
} |
|||
|
|||
/// @todo Move this to QML
|
|||
QString toQString(u256 _value) |
|||
{ |
|||
std::ostringstream s; |
|||
s << _value; |
|||
return QString::fromStdString(s.str()); |
|||
} |
|||
|
|||
TransactionListItem::TransactionListItem(int _index, TransactionSettings const& _t, QObject* _parent): |
|||
QObject(_parent), m_index(_index), m_title(_t.title), m_functionId(_t.functionId), m_value(toQString(_t.value)), |
|||
m_gas(toQString(_t.gas)), m_gasPrice(toQString(_t.gasPrice)) |
|||
{} |
|||
|
|||
TransactionListModel::TransactionListModel(QObject* _parent, QTextDocument* _document): |
|||
QAbstractListModel(_parent), m_document(_document) |
|||
{ |
|||
qRegisterMetaType<TransactionListItem*>("TransactionListItem*"); |
|||
} |
|||
|
|||
QHash<int, QByteArray> TransactionListModel::roleNames() const |
|||
{ |
|||
QHash<int, QByteArray> roles; |
|||
roles[TitleRole] = "title"; |
|||
roles[IdRole] = "transactionIndex"; |
|||
return roles; |
|||
} |
|||
|
|||
int TransactionListModel::rowCount(QModelIndex const& _parent) const |
|||
{ |
|||
Q_UNUSED(_parent); |
|||
return m_transactions.size(); |
|||
} |
|||
|
|||
QVariant TransactionListModel::data(QModelIndex const& _index, int _role) const |
|||
{ |
|||
if (_index.row() < 0 || _index.row() >= (int)m_transactions.size()) |
|||
return QVariant(); |
|||
auto const& transaction = m_transactions.at(_index.row()); |
|||
switch (_role) |
|||
{ |
|||
case TitleRole: |
|||
return QVariant(transaction.title); |
|||
case IdRole: |
|||
return QVariant(_index.row()); |
|||
default: |
|||
return QVariant(); |
|||
} |
|||
} |
|||
|
|||
///@todo: get parameters from code model
|
|||
QList<TransactionParameterItem*> buildParameters(QTextDocument* _document, TransactionSettings const& _transaction, QString const& _functionId) |
|||
{ |
|||
QList<TransactionParameterItem*> params; |
|||
try |
|||
{ |
|||
std::shared_ptr<QContractDefinition> contract = QContractDefinition::Contract(_document->toPlainText()); |
|||
auto functions = contract->functions(); |
|||
for (auto f : functions) |
|||
{ |
|||
if (f->name() != _functionId) |
|||
continue; |
|||
|
|||
auto parameters = f->parameters(); |
|||
//build a list of parameters for a function. If the function is selected as current, add parameter values as well
|
|||
for (auto p : parameters) |
|||
{ |
|||
QString paramValue; |
|||
if (f->name() == _transaction.functionId) |
|||
{ |
|||
auto paramValueIter = _transaction.parameterValues.find(p->name()); |
|||
if (paramValueIter != _transaction.parameterValues.cend()) |
|||
paramValue = toQString(paramValueIter->second); |
|||
} |
|||
|
|||
TransactionParameterItem* item = new TransactionParameterItem(p->name(), p->type(), paramValue); |
|||
QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership); |
|||
params.append(item); |
|||
} |
|||
} |
|||
} |
|||
catch (boost::exception const&) |
|||
{ |
|||
//TODO:
|
|||
} |
|||
|
|||
return params; |
|||
} |
|||
|
|||
///@todo: get fnctions from code model
|
|||
QList<QString> TransactionListModel::getFunctions() |
|||
{ |
|||
QList<QString> functionNames; |
|||
try |
|||
{ |
|||
QString code = m_document->toPlainText(); |
|||
std::shared_ptr<QContractDefinition> contract(QContractDefinition::Contract(code)); |
|||
auto functions = contract->functions(); |
|||
for (auto f : functions) |
|||
{ |
|||
functionNames.append(f->name()); |
|||
} |
|||
} |
|||
catch (boost::exception const&) |
|||
{ |
|||
} |
|||
return functionNames; |
|||
} |
|||
|
|||
QVariantList TransactionListModel::getParameters(int _index, QString const& _functionId) |
|||
{ |
|||
TransactionSettings const& transaction = (_index >= 0 && _index < (int)m_transactions.size()) ? m_transactions[_index] : TransactionSettings(); |
|||
auto plist = buildParameters(m_document, transaction, _functionId); |
|||
QVariantList vl; |
|||
for (QObject* p : plist) |
|||
vl.append(QVariant::fromValue(p)); |
|||
return vl; |
|||
} |
|||
|
|||
TransactionListItem* TransactionListModel::getItem(int _index) |
|||
{ |
|||
TransactionSettings const& transaction = (_index >= 0 && _index < (int)m_transactions.size()) ? m_transactions[_index] : TransactionSettings(); |
|||
TransactionListItem* item = new TransactionListItem(_index, transaction, nullptr); |
|||
QQmlEngine::setObjectOwnership(item, QQmlEngine::JavaScriptOwnership); |
|||
return item; |
|||
} |
|||
|
|||
void TransactionListModel::edit(QObject* _data) |
|||
{ |
|||
//these properties come from TransactionDialog QML object
|
|||
///@todo change the model to a qml component
|
|||
int index = _data->property("transactionIndex").toInt(); |
|||
QString title = _data->property("transactionTitle").toString(); |
|||
QString gas = _data->property("gas").toString(); |
|||
QString gasPrice = _data->property("gasPrice").toString(); |
|||
QString value = _data->property("transactionValue").toString(); |
|||
QString functionId = _data->property("functionId").toString(); |
|||
QAbstractListModel* paramsModel = qvariant_cast<QAbstractListModel*>(_data->property("transactionParams")); |
|||
TransactionSettings transaction(title, functionId, fromQString(value), fromQString(gas), fromQString(gasPrice)); |
|||
int paramCount = paramsModel->rowCount(QModelIndex()); |
|||
for (int p = 0; p < paramCount; ++p) |
|||
{ |
|||
QString paramName = paramsModel->data(paramsModel->index(p, 0), Qt::DisplayRole).toString(); |
|||
QString paramValue = paramsModel->data(paramsModel->index(p, 0), Qt::DisplayRole + 2).toString(); |
|||
if (!paramValue.isEmpty() && !paramName.isEmpty()) |
|||
transaction.parameterValues[paramName] = fromQString(paramValue); |
|||
} |
|||
|
|||
if (index >= 0 && index < (int)m_transactions.size()) |
|||
{ |
|||
beginRemoveRows(QModelIndex(), index, index); |
|||
m_transactions.erase(m_transactions.begin() + index); |
|||
endRemoveRows(); |
|||
} |
|||
else |
|||
index = rowCount(QModelIndex()); |
|||
|
|||
beginInsertRows(QModelIndex(), index, index); |
|||
m_transactions.push_back(transaction); |
|||
emit countChanged(); |
|||
endInsertRows(); |
|||
} |
|||
|
|||
int TransactionListModel::getCount() const |
|||
{ |
|||
return rowCount(QModelIndex()); |
|||
} |
|||
|
|||
void TransactionListModel::runTransaction(int _index) |
|||
{ |
|||
TransactionSettings tr = m_transactions.at(_index); |
|||
emit transactionStarted(tr); |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
|||
|
@ -0,0 +1,168 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TransactionListView.h
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QObject> |
|||
#include <QVariant> |
|||
#include <QAbstractListModel> |
|||
#include <QHash> |
|||
#include <QByteArray> |
|||
#include <libdevcore/Common.h> |
|||
#include <libethcore/CommonEth.h> |
|||
|
|||
class QTextDocument; |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
/// Backend transaction config class
|
|||
struct TransactionSettings |
|||
{ |
|||
TransactionSettings(): |
|||
value(0), gas(10000), gasPrice(10 * dev::eth::szabo) {} |
|||
|
|||
TransactionSettings(QString const& _title, QString const& _functionId, u256 _value, u256 _gas, u256 _gasPrice): |
|||
title(_title), functionId(_functionId), value(_value), gas(_gas), gasPrice(_gasPrice) {} |
|||
|
|||
/// User specified transaction title
|
|||
QString title; |
|||
/// Contract function name
|
|||
QString functionId; |
|||
/// Transaction value
|
|||
u256 value; |
|||
/// Gas
|
|||
u256 gas; |
|||
/// Gas price
|
|||
u256 gasPrice; |
|||
/// Mapping from contract function parameter name to value
|
|||
std::map<QString, u256> parameterValues; |
|||
}; |
|||
|
|||
/// QML transaction parameter class
|
|||
class TransactionParameterItem: public QObject |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(QString name READ name CONSTANT) |
|||
Q_PROPERTY(QString type READ type CONSTANT) |
|||
Q_PROPERTY(QString value READ value CONSTANT) |
|||
public: |
|||
TransactionParameterItem(QString const& _name, QString const& _type, QString const& _value): |
|||
m_name(_name), m_type(_type), m_value(_value) {} |
|||
|
|||
/// Parameter name, set by contract definition
|
|||
QString name() { return m_name; } |
|||
/// Parameter type, set by contract definition
|
|||
QString type() { return m_type; } |
|||
/// Parameter value, set by user
|
|||
QString value() { return m_value; } |
|||
|
|||
private: |
|||
QString m_name; |
|||
QString m_type; |
|||
QString m_value; |
|||
}; |
|||
|
|||
class TransactionListItem: public QObject |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(int index READ index CONSTANT) |
|||
Q_PROPERTY(QString title READ title CONSTANT) |
|||
Q_PROPERTY(QString functionId READ functionId CONSTANT) |
|||
Q_PROPERTY(QString gas READ gas CONSTANT) |
|||
Q_PROPERTY(QString gasPrice READ gasPrice CONSTANT) |
|||
Q_PROPERTY(QString value READ value CONSTANT) |
|||
|
|||
public: |
|||
TransactionListItem(int _index, TransactionSettings const& _t, QObject* _parent); |
|||
|
|||
/// User specified transaction title
|
|||
QString title() { return m_title; } |
|||
/// Gas
|
|||
QString gas() { return m_gas; } |
|||
/// Gas cost
|
|||
QString gasPrice() { return m_gasPrice; } |
|||
/// Transaction value
|
|||
QString value() { return m_value; } |
|||
/// Contract function name
|
|||
QString functionId() { return m_functionId; } |
|||
/// Index of this transaction in the transactions list
|
|||
int index() { return m_index; } |
|||
|
|||
private: |
|||
int m_index; |
|||
QString m_title; |
|||
QString m_functionId; |
|||
QString m_value; |
|||
QString m_gas; |
|||
QString m_gasPrice; |
|||
}; |
|||
|
|||
/// QML model for a list of transactions
|
|||
class TransactionListModel: public QAbstractListModel |
|||
{ |
|||
Q_OBJECT |
|||
Q_PROPERTY(int count READ getCount() NOTIFY countChanged()) |
|||
|
|||
enum Roles |
|||
{ |
|||
TitleRole = Qt::DisplayRole, |
|||
IdRole = Qt::UserRole + 1 |
|||
}; |
|||
|
|||
public: |
|||
TransactionListModel(QObject* _parent, QTextDocument* _document); |
|||
~TransactionListModel() {} |
|||
|
|||
QHash<int, QByteArray> roleNames() const override; |
|||
int rowCount(QModelIndex const& _parent) const override; |
|||
QVariant data(QModelIndex const& _index, int _role) const override; |
|||
int getCount() const; |
|||
/// Apply changes from transaction dialog. Argument is a dialog model as defined in TransactionDialog.qml
|
|||
/// @todo Change that to transaction item
|
|||
Q_INVOKABLE void edit(QObject* _data); |
|||
/// @returns transaction item for a give index
|
|||
Q_INVOKABLE TransactionListItem* getItem(int _index); |
|||
/// @returns a list of functions for current contract
|
|||
Q_INVOKABLE QList<QString> getFunctions(); |
|||
/// @returns function parameters along with parameter values if set. @see TransactionParameterItem
|
|||
Q_INVOKABLE QVariantList getParameters(int _id, QString const& _functionId); |
|||
/// Launch transaction execution UI handler
|
|||
Q_INVOKABLE void runTransaction(int _index); |
|||
|
|||
signals: |
|||
/// Transaction count has changed
|
|||
void countChanged(); |
|||
/// Transaction has been launched
|
|||
void transactionStarted(dev::mix::TransactionSettings); |
|||
|
|||
private: |
|||
std::vector<TransactionSettings> m_transactions; |
|||
QTextDocument* m_document; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
@ -0,0 +1,56 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
|
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TransactionListView.cpp
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#include <QQuickItem> |
|||
#include <QApplication> |
|||
#include <QQmlApplicationEngine> |
|||
#include <QQmlContext> |
|||
#include <QDebug> |
|||
#include "TransactionListView.h" |
|||
#include "TransactionListModel.h" |
|||
using namespace dev::mix; |
|||
|
|||
TransactionListView::TransactionListView(QTextDocument* _doc): Extension(ExtensionDisplayBehavior::RightTab) |
|||
{ |
|||
m_editor = _doc; |
|||
m_model.reset(new TransactionListModel(this, _doc)); |
|||
m_appEngine->rootContext()->setContextProperty("transactionListModel", m_model.get()); |
|||
} |
|||
|
|||
TransactionListView::~TransactionListView() |
|||
{ |
|||
//implementation is in cpp file so that all types deleted are complete
|
|||
} |
|||
|
|||
QString TransactionListView::contentUrl() const |
|||
{ |
|||
return QStringLiteral("qrc:/qml/TransactionList.qml"); |
|||
} |
|||
|
|||
QString TransactionListView::title() const |
|||
{ |
|||
return QApplication::tr("Transactions"); |
|||
} |
|||
|
|||
void TransactionListView::start() const |
|||
{ |
|||
} |
@ -0,0 +1,54 @@ |
|||
/*
|
|||
This file is part of cpp-ethereum. |
|||
cpp-ethereum is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
cpp-ethereum is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
You should have received a copy of the GNU General Public License |
|||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
/** @file TransactionListView.h
|
|||
* @author Arkadiy Paronyan arkadiy@ethdev.com |
|||
* @date 2014 |
|||
* Ethereum IDE client. |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <QTextDocument> |
|||
#include "Extension.h" |
|||
|
|||
namespace dev |
|||
{ |
|||
namespace mix |
|||
{ |
|||
|
|||
class TransactionListModel; |
|||
|
|||
/// Transactions list control
|
|||
/// @todo This should be moved into state as a sequence
|
|||
class TransactionListView: public Extension |
|||
{ |
|||
Q_OBJECT |
|||
|
|||
public: |
|||
TransactionListView(QTextDocument*); |
|||
~TransactionListView(); |
|||
void start() const override; |
|||
QString title() const override; |
|||
QString contentUrl() const override; |
|||
/// @returns the underlying model
|
|||
TransactionListModel* model() const { return m_model.get(); } |
|||
|
|||
private: |
|||
QTextDocument* m_editor; |
|||
std::unique_ptr<TransactionListModel> m_model; |
|||
}; |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,219 @@ |
|||
import QtQuick 2.2 |
|||
import QtQuick.Controls 1.2 |
|||
import QtQuick.Layouts 1.1 |
|||
import QtQuick.Window 2.0 |
|||
|
|||
Window { |
|||
modality: Qt.WindowModal |
|||
|
|||
width:640 |
|||
height:480 |
|||
|
|||
visible: false |
|||
|
|||
function open() |
|||
{ |
|||
visible = true; |
|||
} |
|||
function close() |
|||
{ |
|||
visible = false; |
|||
} |
|||
|
|||
property alias focus : titleField.focus |
|||
property alias transactionTitle : titleField.text |
|||
property int transactionIndex |
|||
property alias transactionParams : paramsModel; |
|||
property alias gas : gasField.text; |
|||
property alias gasPrice : gasPriceField.text; |
|||
property alias transactionValue : valueField.text; |
|||
property alias functionId : functionComboBox.currentText; |
|||
property var model; |
|||
|
|||
signal accepted; |
|||
|
|||
function reset(index, m) { |
|||
model = m; |
|||
var item = model.getItem(index); |
|||
transactionIndex = index; |
|||
transactionTitle = item.title; |
|||
gas = item.gas; |
|||
gasPrice = item.gasPrice; |
|||
transactionValue = item.value; |
|||
var functionId = item.functionId; |
|||
functionsModel.clear(); |
|||
var functionIndex = -1; |
|||
var functions = model.getFunctions(); |
|||
for (var f = 0; f < functions.length; f++) { |
|||
functionsModel.append({ text: functions[f] }); |
|||
if (functions[f] === item.functionId) |
|||
functionIndex = f; |
|||
} |
|||
functionComboBox.currentIndex = functionIndex; |
|||
} |
|||
|
|||
function loadParameters() { |
|||
if (!paramsModel) |
|||
return; |
|||
paramsModel.clear(); |
|||
if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { |
|||
var parameters = model.getParameters(transactionIndex, functionsModel.get(functionComboBox.currentIndex).text); |
|||
for (var p = 0; p < parameters.length; p++) { |
|||
paramsModel.append({ name: parameters[p].name, type: parameters[p].type, value: parameters[p].value }); |
|||
} |
|||
} |
|||
} |
|||
|
|||
GridLayout { |
|||
id: dialogContent |
|||
columns: 2 |
|||
anchors.fill: parent |
|||
anchors.margins: 10 |
|||
rowSpacing: 10 |
|||
columnSpacing: 10 |
|||
|
|||
Label { |
|||
text: qsTr("Title") |
|||
} |
|||
TextField { |
|||
id: titleField |
|||
focus: true |
|||
Layout.fillWidth: true |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Function") |
|||
} |
|||
|
|||
ComboBox { |
|||
id: functionComboBox |
|||
Layout.fillWidth: true |
|||
currentIndex: -1 |
|||
textRole: "text" |
|||
editable: false |
|||
model: ListModel { |
|||
id: functionsModel |
|||
} |
|||
onCurrentIndexChanged: { |
|||
loadParameters(); |
|||
} |
|||
} |
|||
Label { |
|||
text: qsTr("Value") |
|||
} |
|||
TextField { |
|||
id: valueField |
|||
Layout.fillWidth: true |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Gas") |
|||
} |
|||
TextField { |
|||
id: gasField |
|||
Layout.fillWidth: true |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Gas price") |
|||
} |
|||
TextField { |
|||
id: gasPriceField |
|||
Layout.fillWidth: true |
|||
} |
|||
|
|||
Label { |
|||
text: qsTr("Parameters") |
|||
} |
|||
TableView { |
|||
model: paramsModel |
|||
Layout.fillWidth: true |
|||
|
|||
TableViewColumn { |
|||
role: "name" |
|||
title: "Name" |
|||
width: 120 |
|||
} |
|||
TableViewColumn { |
|||
role: "type" |
|||
title: "Type" |
|||
width: 120 |
|||
} |
|||
TableViewColumn { |
|||
role: "value" |
|||
title: "Value" |
|||
width: 120 |
|||
} |
|||
|
|||
itemDelegate: { |
|||
return 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: editableDelegate |
|||
Item { |
|||
|
|||
Text { |
|||
width: parent.width |
|||
anchors.margins: 4 |
|||
anchors.left: parent.left |
|||
anchors.verticalCenter: parent.verticalCenter |
|||
elide: styleData.elideMode |
|||
text: styleData.value !== undefined ? styleData.value : "" |
|||
color: styleData.textColor |
|||
visible: !styleData.selected |
|||
} |
|||
Loader { |
|||
id: loaderEditor |
|||
anchors.fill: parent |
|||
anchors.margins: 4 |
|||
Connections { |
|||
target: loaderEditor.item |
|||
onTextChanged: { |
|||
paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text); |
|||
} |
|||
} |
|||
sourceComponent: (styleData.selected) ? editor : null |
|||
Component { |
|||
id: editor |
|||
TextInput { |
|||
id: textinput |
|||
color: styleData.textColor |
|||
text: styleData.value |
|||
MouseArea { |
|||
id: mouseArea |
|||
anchors.fill: parent |
|||
hoverEnabled: true |
|||
onClicked: textinput.forceActiveFocus() |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,89 @@ |
|||
import QtQuick 2.2 |
|||
import QtQuick.Controls.Styles 1.2 |
|||
import QtQuick.Controls 1.2 |
|||
import QtQuick.Dialogs 1.2 |
|||
import QtQuick.Layouts 1.1 |
|||
|
|||
|
|||
Rectangle { |
|||
color: "transparent" |
|||
id: transactionListContainer |
|||
focus: true |
|||
anchors.topMargin: 10 |
|||
anchors.left: parent.left |
|||
height: parent.height |
|||
width: parent.width |
|||
|
|||
ListView { |
|||
anchors.top: parent.top |
|||
height: parent.height |
|||
width: parent.width |
|||
id: transactionList |
|||
model: transactionListModel |
|||
delegate: renderDelegate |
|||
} |
|||
|
|||
Button { |
|||
anchors.bottom: parent.bottom |
|||
text: qsTr("Add") |
|||
onClicked: |
|||
{ |
|||
// Set next id here to work around Qt bug |
|||
// https://bugreports.qt-project.org/browse/QTBUG-41327 |
|||
// Second call to signal handle would just edit the item that was just created, no harm done |
|||
transactionDialog.reset(transactionListModel.count, transactionListModel); |
|||
transactionDialog.open(); |
|||
transactionDialog.focus = true; |
|||
} |
|||
} |
|||
|
|||
TransactionDialog { |
|||
id: transactionDialog |
|||
onAccepted: { |
|||
transactionListModel.edit(transactionDialog); |
|||
} |
|||
} |
|||
|
|||
Component { |
|||
id: renderDelegate |
|||
Item { |
|||
id: wrapperItem |
|||
height: 20 |
|||
width: parent.width |
|||
RowLayout |
|||
{ |
|||
anchors.fill: parent |
|||
Text { |
|||
//anchors.fill: parent |
|||
Layout.fillWidth: true |
|||
Layout.fillHeight: true |
|||
text: title |
|||
font.pointSize: 12 |
|||
verticalAlignment: Text.AlignBottom |
|||
} |
|||
ToolButton { |
|||
text: qsTr("Edit"); |
|||
Layout.fillHeight: true |
|||
onClicked: { |
|||
transactionDialog.reset(index, transactionListModel); |
|||
transactionDialog.open(); |
|||
transactionDialog.focus = true; |
|||
} |
|||
} |
|||
ToolButton { |
|||
text: qsTr("Delete"); |
|||
Layout.fillHeight: true |
|||
onClicked: { |
|||
} |
|||
} |
|||
ToolButton { |
|||
text: qsTr("Run"); |
|||
Layout.fillHeight: true |
|||
onClicked: { |
|||
transactionListModel.runTransaction(index); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
File diff suppressed because it is too large
Loading…
Reference in new issue