Browse Source

struct editor

cl-refactor
arkpar 10 years ago
parent
commit
34f13c5920
  1. 6
      mix/AppContext.cpp
  2. 16
      mix/ClientModel.cpp
  3. 107
      mix/CodeModel.cpp
  4. 30
      mix/CodeModel.h
  5. 90
      mix/ContractCallDataEncoder.cpp
  6. 13
      mix/ContractCallDataEncoder.h
  7. 6
      mix/QBasicNodeDefinition.h
  8. 10
      mix/QContractDefinition.cpp
  9. 3
      mix/QContractDefinition.h
  10. 10
      mix/QFunctionDefinition.cpp
  11. 5
      mix/QFunctionDefinition.h
  12. 65
      mix/QVariableDeclaration.cpp
  13. 63
      mix/QVariableDeclaration.h
  14. 17
      mix/QVariableDefinition.cpp
  15. 86
      mix/QVariableDefinition.h
  16. 65
      mix/SolidityType.h
  17. 7
      mix/qml/QBoolType.qml
  18. 10
      mix/qml/QBoolTypeView.qml
  19. 7
      mix/qml/QHashType.qml
  20. 6
      mix/qml/QHashTypeView.qml
  21. 7
      mix/qml/QIntType.qml
  22. 7
      mix/qml/QIntTypeView.qml
  23. 7
      mix/qml/QRealType.qml
  24. 7
      mix/qml/QStringType.qml
  25. 6
      mix/qml/QStringTypeView.qml
  26. 10
      mix/qml/SolidityTypeConverter.qml
  27. 2
      mix/qml/StateDialog.qml
  28. 38
      mix/qml/StateListModel.qml
  29. 182
      mix/qml/StructView.qml
  30. 204
      mix/qml/TransactionDialog.qml
  31. 7
      mix/res.qrc

6
mix/AppContext.cpp

@ -68,14 +68,10 @@ void AppContext::load()
m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get());
qmlRegisterType<QEther>("org.ethereum.qml.QEther", 1, 0, "QEther");
qmlRegisterType<QBigInt>("org.ethereum.qml.QBigInt", 1, 0, "QBigInt");
qmlRegisterType<QIntType>("org.ethereum.qml.QIntType", 1, 0, "QIntType");
qmlRegisterType<QRealType>("org.ethereum.qml.QRealType", 1, 0, "QRealType");
qmlRegisterType<QStringType>("org.ethereum.qml.QStringType", 1, 0, "QStringType");
qmlRegisterType<QHashType>("org.ethereum.qml.QHashType", 1, 0, "QHashType");
qmlRegisterType<QBoolType>("org.ethereum.qml.QBoolType", 1, 0, "QBoolType");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration");
qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry");
qmlRegisterType<SortFilterProxyModel>("org.ethereum.qml.SortFilterProxyModel", 1, 0, "SortFilterProxyModel");
qmlRegisterType<QSolidityType>("org.ethereum.qml.QSolidityType", 1, 0, "QSolidityType");
QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml"));
QObject* projectModel = projectModelComponent.create();
if (projectModelComponent.isError())

16
mix/ClientModel.cpp

@ -71,16 +71,11 @@ ClientModel::ClientModel(AppContext* _context):
m_context(_context), m_running(false), m_rpcConnector(new RpcConnector())
{
qRegisterMetaType<QBigInt*>("QBigInt*");
qRegisterMetaType<QIntType*>("QIntType*");
qRegisterMetaType<QStringType*>("QStringType*");
qRegisterMetaType<QRealType*>("QRealType*");
qRegisterMetaType<QHashType*>("QHashType*");
qRegisterMetaType<QEther*>("QEther*");
qRegisterMetaType<QVariableDefinition*>("QVariableDefinition*");
qRegisterMetaType<QVariableDefinitionList*>("QVariableDefinitionList*");
qRegisterMetaType<QList<QVariableDefinition*>>("QList<QVariableDefinition*>");
qRegisterMetaType<QList<QVariableDeclaration*>>("QList<QVariableDeclaration*>");
qRegisterMetaType<QVariableDeclaration*>("QVariableDeclaration*");
qRegisterMetaType<QSolidityType*>("QSolidityType*");
qRegisterMetaType<QMachineState*>("QMachineState");
qRegisterMetaType<QInstruction*>("QInstruction");
qRegisterMetaType<QCode*>("QCode");
@ -191,7 +186,7 @@ void ClientModel::setupState(QVariantMap _state)
{
if (contractId.isEmpty() && m_context->codeModel()->hasContract()) //TODO: This is to support old project files, remove later
contractId = m_context->codeModel()->contracts().keys()[0];
QVariantList qParams = transaction.value("qType").toList();
QVariantList qParams = transaction.value("parameters").toList();
TransactionSettings transactionSettings(contractId, functionId, value, gas, gasPrice, Secret(sender.toStdString()));
for (QVariant const& variant: qParams)
@ -525,9 +520,10 @@ void ClientModel::onNewTransaction()
{
function = funcDef->name();
ContractCallDataEncoder encoder;
QList<QVariableDefinition*> returnValues = encoder.decode(funcDef->returnParameters(), tr.returnValue);
for (auto const& var: returnValues)
returned += var->value() + " | ";
QStringList returnValues = encoder.decode(funcDef->returnParameters(), tr.returnValue);
returned += "(";
returned += returnValues.join(", ");
returned += ")";
}
}
}

107
mix/CodeModel.cpp

@ -61,44 +61,6 @@ private:
return LocationPair(_node.getLocation().start, _node.getLocation().end);
}
SolidityType nodeType(Type const* _type)
{
if (!_type)
return SolidityType { SolidityType::Type::UnsignedInteger, 32 };
switch (_type->getCategory())
{
case Type::Category::Integer:
{
IntegerType const* it = dynamic_cast<IntegerType const*>(_type);
unsigned size = it->getNumBits() / 8;
SolidityType::Type typeCode = it->isAddress() ? SolidityType::Type::Address : it->isHash() ? SolidityType::Type::Hash : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger;
return SolidityType { typeCode, size };
}
case Type::Category::Bool:
return SolidityType { SolidityType::Type::Bool, _type->getSizeOnStack() * 32 };
case Type::Category::String:
{
StaticStringType const* s = dynamic_cast<StaticStringType const*>(_type);
return SolidityType { SolidityType::Type::String, static_cast<unsigned>(s->getNumBytes()) };
}
case Type::Category::Contract:
return SolidityType { SolidityType::Type::Address, _type->getSizeOnStack() * 32 };
case Type::Category::Array:
case Type::Category::Enum:
case Type::Category::Function:
case Type::Category::IntegerConstant:
case Type::Category::Magic:
case Type::Category::Mapping:
case Type::Category::Modifier:
case Type::Category::Real:
case Type::Category::Struct:
case Type::Category::TypeType:
case Type::Category::Void:
default:
return SolidityType { SolidityType::Type::UnsignedInteger, 32 };
}
}
virtual bool visit(FunctionDefinition const& _node)
{
m_functions->insert(nodeLocation(_node), QString::fromStdString(_node.getName()));
@ -114,7 +76,7 @@ private:
virtual bool visit(VariableDeclaration const& _node)
{
SolidityDeclaration decl;
decl.type = nodeType(_node.getType().get());
decl.type = CodeModel::nodeType(_node.getType().get());
decl.name = QString::fromStdString(_node.getName());
if (m_functionScope)
m_locals->insert(nodeLocation(_node), decl);
@ -143,7 +105,7 @@ CompiledContract::CompiledContract(const dev::solidity::CompilerStack& _compiler
{
std::string name = _contractName.toStdString();
auto const& contractDefinition = _compiler.getContractDefinition(name);
m_contract.reset(new QContractDefinition(&contractDefinition));
m_contract.reset(new QContractDefinition(nullptr, &contractDefinition));
QQmlEngine::setObjectOwnership(m_contract.get(), QQmlEngine::CppOwnership);
m_bytes = _compiler.getBytecode(_contractName.toStdString());
m_assemblyItems = _compiler.getRuntimeAssemblyItems(name);
@ -345,3 +307,68 @@ dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, co
return m_compiledContracts.at(_contractName);
}
SolidityType CodeModel::nodeType(solidity::Type const* _type)
{
SolidityType r { SolidityType::Type::UnsignedInteger, 32, false, false, QString::fromStdString(_type->toString()), std::vector<SolidityDeclaration>(), std::vector<QString>() };
if (!_type)
return r;
switch (_type->getCategory())
{
case Type::Category::Integer:
{
IntegerType const* it = dynamic_cast<IntegerType const*>(_type);
r.size = it->getNumBits() / 8;
r.type = it->isAddress() ? SolidityType::Type::Address : it->isHash() ? SolidityType::Type::Hash : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger;
}
break;
case Type::Category::Bool:
r.type = SolidityType::Type::Bool;
break;
case Type::Category::String:
{
StaticStringType const* s = dynamic_cast<StaticStringType const*>(_type);
r.type = SolidityType::Type::String;
r.size = static_cast<unsigned>(s->getNumBytes());
}
case Type::Category::Contract:
r.type = SolidityType::Type::Address;
break;
case Type::Category::Array:
{
ArrayType const* array = dynamic_cast<ArrayType const*>(_type);
SolidityType elementType = nodeType(array->getBaseType().get());
r = elementType;
r.array = true;
}
break;
case Type::Category::Enum:
{
r.type = SolidityType::Type::Enum;
EnumType const* e = dynamic_cast<EnumType const*>(_type);
for(auto const& enumValue: e->getEnumDefinition().getMembers())
r.enumNames.push_back(QString::fromStdString(enumValue->getName()));
}
break;
case Type::Category::Struct:
{
r.type = SolidityType::Type::Struct;
StructType const* s = dynamic_cast<StructType const*>(_type);
for(auto const& structMember: s->getMembers())
r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.first), nodeType(structMember.second.get()) });
}
break;
case Type::Category::Function:
case Type::Category::IntegerConstant:
case Type::Category::Magic:
case Type::Category::Mapping:
case Type::Category::Modifier:
case Type::Category::Real:
case Type::Category::TypeType:
case Type::Category::Void:
default:
break;
//BOOST_THROW_EXCEPTION(dev::Exception() << errinfo_comment("Unsupported solidityType: " + _type->toString()));
}
return r;
}

30
mix/CodeModel.h

@ -31,13 +31,18 @@
#include <libdevcore/Common.h>
#include <libdevcore/Guards.h>
#include <libevmcore/Assembly.h>
#include "SolidityType.h"
class QTextDocument;
namespace dev
{
namespace solidity { class CompilerStack; }
namespace solidity
{
class CompilerStack;
class Type;
}
namespace mix
{
@ -63,27 +68,6 @@ private:
using LocationPair = QPair<int, int>;
struct SolidityType
{
enum class Type //TODO: arrays and structs
{
SignedInteger,
UnsignedInteger,
Hash,
Bool,
Address,
String,
};
Type type;
unsigned size; //bytes
};
struct SolidityDeclaration
{
QString name;
SolidityType type;
};
///Compilation result model. Contains all the compiled contract data required by UI
class CompiledContract: public QObject
{
@ -163,6 +147,8 @@ public:
Q_INVOKABLE CompiledContract* contractByDocumentId(QString _documentId) const;
/// Reset code model
Q_INVOKABLE void reset() { reset(QVariantMap()); }
/// Convert solidity type info to mix type
static SolidityType nodeType(solidity::Type const* _type);
signals:
/// Emited on compilation state change

90
mix/ContractCallDataEncoder.cpp

@ -49,33 +49,85 @@ void ContractCallDataEncoder::push(bytes const& _b)
m_encodedData.insert(m_encodedData.end(), _b.begin(), _b.end());
}
QList<QVariableDefinition*> ContractCallDataEncoder::decode(QList<QVariableDeclaration*> const& _returnParameters, bytes _value)
bigint ContractCallDataEncoder::decodeInt(dev::bytes const& _rawValue)
{
dev::u256 un = dev::fromBigEndian<dev::u256>(_rawValue);
if (un >> 255)
return (-s256(~un + 1));
return un;
}
dev::bytes ContractCallDataEncoder::encodeInt(QString const& _str)
{
dev::bigint i(_str.toStdString());
bytes ret(32);
toBigEndian((u256)i, ret);
return ret;
}
QString ContractCallDataEncoder::toString(dev::bigint const& _int)
{
std::stringstream str;
str << std::dec << _int;
return QString::fromStdString(str.str());
}
dev::bytes ContractCallDataEncoder::encodeBool(QString const& _str)
{
bytes b(1);
b[0] = _str == "1" || _str.toLower() == "true " ? 1 : 0;
return padded(b, 32);
}
bool ContractCallDataEncoder::decodeBool(dev::bytes const& _rawValue)
{
byte ret = _rawValue.at(_rawValue.size() - 1);
return (ret != 0);
}
QString ContractCallDataEncoder::toString(bool _b)
{
return _b ? "true" : "false";
}
dev::bytes ContractCallDataEncoder::encodeBytes(QString const& _str)
{
QByteArray bytesAr = _str.toLocal8Bit();
bytes r = bytes(bytesAr.begin(), bytesAr.end());
return padded(r, 32);
}
dev::bytes ContractCallDataEncoder::decodeBytes(dev::bytes const& _rawValue)
{
return _rawValue;
}
QString ContractCallDataEncoder::toString(dev::bytes const& _b)
{
return QString::fromStdString(dev::toJS(_b));
}
QStringList ContractCallDataEncoder::decode(QList<QVariableDeclaration*> const& _returnParameters, bytes _value)
{
bytesConstRef value(&_value);
bytes rawParam(32);
QList<QVariableDefinition*> r;
QStringList r;
for (int k = 0; k <_returnParameters.length(); k++)
{
value.populate(&rawParam);
value = value.cropped(32);
QVariableDeclaration* dec = static_cast<QVariableDeclaration*>(_returnParameters.at(k));
QVariableDefinition* def = nullptr;
if (dec->type().contains("int"))
def = new QIntType(dec, QString());
else if (dec->type().contains("real"))
def = new QRealType(dec, QString());
else if (dec->type().contains("bool"))
def = new QBoolType(dec, QString());
else if (dec->type().contains("string") || dec->type().contains("text"))
def = new QStringType(dec, QString());
else if (dec->type().contains("hash") || dec->type().contains("address"))
def = new QHashType(dec, QString());
QSolidityType::Type type = dec->type()->type();
if (type == QSolidityType::Type::SignedInteger || type == QSolidityType::Type::UnsignedInteger)
r.append(toString(decodeInt(rawParam)));
else if (type == QSolidityType::Type::Bool)
r.append(toString(decodeBool(rawParam)));
else if (type == QSolidityType::Type::String || type == QSolidityType::Type::Hash)
r.append(toString(decodeBytes(rawParam)));
else if (type == QSolidityType::Type::Struct)
r.append("struct"); //TODO
else
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Parameter declaration not found"));
value.populate(&rawParam);
def->decodeValue(rawParam);
r.push_back(def);
value = value.cropped(32);
qDebug() << "decoded return value : " << dec->type() << " " << def->value();
}
return r;
}

13
mix/ContractCallDataEncoder.h

@ -44,12 +44,23 @@ public:
/// Encode hash of the function to call.
void encode(QFunctionDefinition const* _function);
/// Decode variable in order to be sent to QML view.
QList<QVariableDefinition*> decode(QList<QVariableDeclaration*> const& _dec, bytes _value);
QStringList decode(QList<QVariableDeclaration*> const& _dec, bytes _value);
/// Get all encoded data encoded by encode function.
bytes encodedData();
/// Push the given @a _b to the current param context.
void push(bytes const& _b);
private:
bigint decodeInt(dev::bytes const& _rawValue);
dev::bytes encodeInt(QString const& _str);
QString toString(dev::bigint const& _int);
dev::bytes encodeBool(QString const& _str);
bool decodeBool(dev::bytes const& _rawValue);
QString toString(bool _b);
dev::bytes encodeBytes(QString const& _str);
dev::bytes decodeBytes(dev::bytes const& _rawValue);
QString toString(dev::bytes const& _b);
private:
bytes m_encodedData;
};

6
mix/QBasicNodeDefinition.h

@ -35,10 +35,10 @@ class QBasicNodeDefinition: public QObject
Q_PROPERTY(QString name READ name CONSTANT)
public:
QBasicNodeDefinition(): QObject() {}
QBasicNodeDefinition(QObject* _parent = nullptr): QObject(_parent) {}
~QBasicNodeDefinition() {}
QBasicNodeDefinition(solidity::Declaration const* _d): QObject(), m_name(QString::fromStdString(_d->getName())) {}
QBasicNodeDefinition(std::string const& _name): QObject(), m_name(QString::fromStdString(_name)) {}
QBasicNodeDefinition(QObject* _parent, solidity::Declaration const* _d): QObject(_parent), m_name(QString::fromStdString(_d->getName())) {}
QBasicNodeDefinition(QObject* _parent, std::string const& _name): QObject(_parent), m_name(QString::fromStdString(_name)) {}
/// Get the name of the node.
QString name() const { return m_name; }

10
mix/QContractDefinition.cpp

@ -32,16 +32,16 @@
using namespace dev::solidity;
using namespace dev::mix;
QContractDefinition::QContractDefinition(dev::solidity::ContractDefinition const* _contract): QBasicNodeDefinition(_contract)
QContractDefinition::QContractDefinition(QObject* _parent, dev::solidity::ContractDefinition const* _contract): QBasicNodeDefinition(_parent, _contract)
{
if (_contract->getConstructor() != nullptr)
m_constructor = new QFunctionDefinition(ContractType(*_contract).getConstructorType());
m_constructor = new QFunctionDefinition(_parent, ContractType(*_contract).getConstructorType());
else
m_constructor = new QFunctionDefinition();
m_constructor = new QFunctionDefinition(_parent);
for (auto const& it: _contract->getInterfaceFunctions())
m_functions.append(new QFunctionDefinition(it.second));}
m_functions.append(new QFunctionDefinition(_parent, it.second));
}
QFunctionDefinition const* QContractDefinition::getFunction(dev::FixedHash<4> _hash) const
{

3
mix/QContractDefinition.h

@ -39,8 +39,7 @@ class QContractDefinition: public QBasicNodeDefinition
Q_PROPERTY(dev::mix::QFunctionDefinition* constructor READ constructor CONSTANT)
public:
QContractDefinition() {}
QContractDefinition(solidity::ContractDefinition const* _contract);
QContractDefinition(QObject* _parent, solidity::ContractDefinition const* _contract);
/// Get all the functions of the contract.
QQmlListProperty<QFunctionDefinition> functions() const { return QQmlListProperty<QFunctionDefinition>(const_cast<QContractDefinition*>(this), const_cast<QContractDefinition*>(this)->m_functions); }
/// Get the constructor of the contract.

10
mix/QFunctionDefinition.cpp

@ -28,15 +28,15 @@
using namespace dev::solidity;
using namespace dev::mix;
QFunctionDefinition::QFunctionDefinition(dev::solidity::FunctionTypePointer const& _f): QBasicNodeDefinition(&_f->getDeclaration()), m_hash(dev::sha3(_f->getCanonicalSignature()))
QFunctionDefinition::QFunctionDefinition(QObject* _parent, dev::solidity::FunctionTypePointer const& _f): QBasicNodeDefinition(_parent, &_f->getDeclaration()), m_hash(dev::sha3(_f->getCanonicalSignature()))
{
auto paramNames = _f->getParameterNames();
auto paramTypes = _f->getParameterTypeNames();
auto paramTypes = _f->getParameterTypes();
auto returnNames = _f->getReturnParameterNames();
auto returnTypes = _f->getReturnParameterTypeNames();
auto returnTypes = _f->getReturnParameterTypes();
for (unsigned i = 0; i < paramNames.size(); ++i)
m_parameters.append(new QVariableDeclaration(paramNames[i], paramTypes[i]));
m_parameters.append(new QVariableDeclaration(_parent, paramNames[i], paramTypes[i].get()));
for (unsigned i = 0; i < returnNames.size(); ++i)
m_returnParameters.append(new QVariableDeclaration(returnNames[i], returnTypes[i]));
m_returnParameters.append(new QVariableDeclaration(_parent, returnNames[i], returnTypes[i].get()));
}

5
mix/QFunctionDefinition.h

@ -38,8 +38,9 @@ class QFunctionDefinition: public QBasicNodeDefinition
Q_PROPERTY(QQmlListProperty<dev::mix::QVariableDeclaration> parameters READ parameters)
public:
QFunctionDefinition() {}
QFunctionDefinition(solidity::FunctionTypePointer const& _f);
QFunctionDefinition(){}
QFunctionDefinition(QObject* _parent): QBasicNodeDefinition(_parent) {}
QFunctionDefinition(QObject* _parent, solidity::FunctionTypePointer const& _f);
/// Get all input parameters of this function.
QList<QVariableDeclaration*> const& parametersList() const { return m_parameters; }
/// Get all input parameters of this function as QML property.

65
mix/QVariableDeclaration.cpp

@ -0,0 +1,65 @@
/*
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 2015
*/
#include "QVariableDeclaration.h"
#include "CodeModel.h"
namespace dev
{
namespace mix
{
QVariableDeclaration::QVariableDeclaration(QObject* _parent, solidity::VariableDeclaration const* _v):
QBasicNodeDefinition(_parent, _v),
m_type(new QSolidityType(this, CodeModel::nodeType(_v->getType().get())))
{
}
QVariableDeclaration::QVariableDeclaration(QObject* _parent, std::string const& _name, SolidityType const& _type):
QBasicNodeDefinition(_parent, _name),
m_type(new QSolidityType(_parent, _type))
{
}
QVariableDeclaration::QVariableDeclaration(QObject* _parent, std::string const& _name, solidity::Type const* _type):
QBasicNodeDefinition(_parent, _name),
m_type(new QSolidityType(this, CodeModel::nodeType(_type)))
{
}
QSolidityType::QSolidityType(QObject* _parent, SolidityType const& _type):
QObject(_parent),
m_type(_type.type),
m_size(_type.size),
m_name(_type.name)
{
if (_type.type == Type::Struct)
for (auto const& structMember: _type.members)
m_members.push_back(QVariant::fromValue(new QVariableDeclaration(_parent, structMember.name.toStdString(), structMember.type)));
if (_type.type == Type::Enum)
for (auto const& enumName: _type.enumNames)
m_members.push_back(QVariant::fromValue(enumName));
}
}
}

63
mix/QVariableDeclaration.h

@ -20,34 +20,77 @@
*/
#include <QDebug>
#include <QStringList>
#include <libsolidity/AST.h>
#include <QVariantList>
#include "QBasicNodeDefinition.h"
#include "SolidityType.h"
#pragma once
namespace solidity
{
class Type;
class VariableDeclaration;
}
namespace dev
{
namespace mix
{
class QSolidityType: public QObject
{
Q_OBJECT
Q_PROPERTY(int type READ type CONSTANT) //qml does not support enum properties
Q_PROPERTY(int size READ size CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QVariantList members READ members CONSTANT)
public:
QSolidityType() {}
QSolidityType(QObject* _parent, SolidityType const& _type);
using Type = SolidityType::Type;
enum QmlType //TODO: arrays and structs
{
SignedInteger,
UnsignedInteger,
Hash,
Bool,
Address,
String,
Enum,
Struct
};
Q_ENUMS(QmlType)
Type type() const { return m_type; }
int size() const { return m_size; }
QString name() const { return m_name; }
QVariantList members() const { return m_members; }
private:
Type m_type;
int m_size;
QString m_name;
QVariantList m_members;
};
class QVariableDeclaration: public QBasicNodeDefinition
{
Q_OBJECT
Q_PROPERTY(QString type READ type WRITE setType)
Q_PROPERTY(QSolidityType* type READ type CONSTANT)
public:
QVariableDeclaration() {}
QVariableDeclaration(solidity::VariableDeclaration const* _v): QBasicNodeDefinition(_v), m_type(QString::fromStdString(_v->getType()->toString())) {}
QVariableDeclaration(std::string const& _name, std::string const& _type): QBasicNodeDefinition(_name), m_type(QString::fromStdString(_type)) {}
QString type() const { return m_type; }
void setType(QString _type) { m_type = _type; }
QVariableDeclaration(QObject* _parent, solidity::VariableDeclaration const* _v);
QVariableDeclaration(QObject* _parent, std::string const& _name, SolidityType const& _type);
QVariableDeclaration(QObject* _parent, std::string const& _name, solidity::Type const* _type);
QSolidityType* type() const { return m_type; }
void setType(QSolidityType* _type) { m_type = _type; }
private:
QString m_type;
QSolidityType* m_type;
};
}
}
Q_DECLARE_METATYPE(dev::mix::QVariableDeclaration*)

17
mix/QVariableDefinition.cpp

@ -24,6 +24,7 @@
#include "QVariableDefinition.h"
using namespace dev::mix;
/*
int QVariableDefinitionList::rowCount(const QModelIndex& _parent) const
{
Q_UNUSED(_parent);
@ -56,9 +57,6 @@ QVariableDefinition* QVariableDefinitionList::val(int _idx)
return m_def.at(_idx);
}
/*
* QIntType
*/
void QIntType::setValue(dev::bigint _value)
{
m_bigIntvalue = _value;
@ -84,9 +82,6 @@ void QIntType::decodeValue(dev::bytes const& _rawValue)
setValue(un);
}
/*
* QHashType
*/
dev::bytes QHashType::encodeValue()
{
QByteArray bytesAr = value().toLocal8Bit();
@ -100,9 +95,6 @@ void QHashType::decodeValue(dev::bytes const& _rawValue)
setValue(QString::fromStdString(_ret));
}
/*
* QRealType
*/
dev::bytes QRealType::encodeValue()
{
return bytes();
@ -113,9 +105,6 @@ void QRealType::decodeValue(dev::bytes const& _rawValue)
Q_UNUSED(_rawValue);
}
/*
* QStringType
*/
dev::bytes QStringType::encodeValue()
{
QByteArray b = value().toUtf8();
@ -128,9 +117,6 @@ void QStringType::decodeValue(dev::bytes const& _rawValue)
setValue(QString::fromUtf8((char*)_rawValue.data()));
}
/*
* QBoolType
*/
dev::bytes QBoolType::encodeValue()
{
return padded(jsToBytes(value().toStdString()), 32);
@ -143,3 +129,4 @@ void QBoolType::decodeValue(dev::bytes const& _rawValue)
m_boolValue = boolRet;
m_value = m_boolValue ? "1" : "0";
}
*/

86
mix/QVariableDefinition.h

@ -63,95 +63,9 @@ private:
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;
};
class QIntType: public QVariableDefinition
{
Q_OBJECT
public:
QIntType() {}
QIntType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value) {}
dev::bytes encodeValue() override;
void decodeValue(dev::bytes const& _rawValue) override;
/// @returns an instance of QBigInt for the current value.
QBigInt* toBigInt() { return new QBigInt(m_bigIntvalue); }
dev::bigint bigInt() { return m_bigIntvalue; }
void setValue(dev::bigint _value);
private:
dev::bigint m_bigIntvalue;
};
class QRealType: public QVariableDefinition
{
Q_OBJECT
public:
QRealType() {}
QRealType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value) {}
dev::bytes encodeValue() override;
void decodeValue(dev::bytes const& _rawValue) override;
};
class QStringType: public QVariableDefinition
{
Q_OBJECT
public:
QStringType() {}
QStringType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value) {}
dev::bytes encodeValue() override;
void decodeValue(dev::bytes const& _rawValue) override;
};
class QHashType: public QVariableDefinition
{
Q_OBJECT
public:
QHashType() {}
QHashType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value) {}
dev::bytes encodeValue() override;
void decodeValue(dev::bytes const& _rawValue) override;
};
class QBoolType: public QVariableDefinition
{
Q_OBJECT
public:
QBoolType(): m_boolValue(false) {}
QBoolType(QVariableDeclaration* _def, QString _value): QVariableDefinition(_def, _value), m_boolValue(false) {}
dev::bytes encodeValue() override;
void decodeValue(dev::bytes const& _rawValue) override;
/// @returns the boolean value for the current definition.
bool toBool() { return m_boolValue; }
private:
bool m_boolValue;
};
}
}
Q_DECLARE_METATYPE(dev::mix::QIntType*)
Q_DECLARE_METATYPE(dev::mix::QStringType*)
Q_DECLARE_METATYPE(dev::mix::QHashType*)
Q_DECLARE_METATYPE(dev::mix::QBoolType*)

65
mix/SolidityType.h

@ -0,0 +1,65 @@
/*
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 SolidityType.h
* @author Yann yann@ethdev.com
* @author Arkadiy Paronyan arkadiy@ethdev.com
* @date 2015
* Ethereum IDE client.
*/
#pragma once
#include <QString>
#include <vector>
namespace dev
{
namespace mix
{
struct SolidityDeclaration;
struct SolidityType
{
enum Type //TODO: arrays and structs
{
SignedInteger,
UnsignedInteger,
Hash,
Bool,
Address,
String,
Enum,
Struct
};
Type type;
unsigned size; //bytes,
bool array;
bool dynamicSize;
QString name;
std::vector<SolidityDeclaration> members;
std::vector<QString> enumNames;
};
struct SolidityDeclaration
{
QString name;
SolidityType type;
};
}
}

7
mix/qml/QBoolType.qml

@ -1,7 +0,0 @@
import QtQuick 2.0
import org.ethereum.qml.QBoolType 1.0
QBoolType
{
}

10
mix/qml/QBoolTypeView.qml

@ -4,8 +4,10 @@ import QtQuick.Controls 1.3
Item
{
id: editRoot
property string text
property string value
property string defaultValue
height: 20
width: 150
Rectangle {
anchors.fill: parent
@ -14,10 +16,10 @@ Item
property bool inited: false
Component.onCompleted:
{
if (text === "")
if (value === "")
currentIndex = parseInt(defaultValue);
else
currentIndex = parseInt(text);
currentIndex = parseInt(value);
inited = true
}
@ -26,7 +28,7 @@ Item
onCurrentIndexChanged:
{
if (inited)
text = comboModel.get(currentIndex).value;
value = comboModel.get(currentIndex).value;
}
model: ListModel
{

7
mix/qml/QHashType.qml

@ -1,7 +0,0 @@
import QtQuick 2.0
import org.ethereum.qml.QHashType 1.0
QHashType
{
}

6
mix/qml/QHashTypeView.qml

@ -2,8 +2,10 @@ import QtQuick 2.0
Item
{
property alias text: textinput.text
property alias value: textinput.text
id: editRoot
height: 20
width: 150
SourceSansProBold
{
@ -16,7 +18,7 @@ Item
color: "#f7f7f7"
TextInput {
id: textinput
text: text
text: value
anchors.fill: parent
wrapMode: Text.WrapAnywhere
clip: true

7
mix/qml/QIntType.qml

@ -1,7 +0,0 @@
import QtQuick 2.0
import org.ethereum.qml.QIntType 1.0
QIntType
{
}

7
mix/qml/QIntTypeView.qml

@ -1,9 +1,12 @@
import QtQuick 2.0
import QtQuick.Layouts 1.1
Item
{
property alias text: textinput.text
property alias value: textinput.text
id: editRoot
height: 20
width: 150
SourceSansProBold
{
@ -16,7 +19,7 @@ Item
color: "#f7f7f7"
TextInput {
id: textinput
text: text
text: value
anchors.fill: parent
font.family: boldFont.name
clip: true

7
mix/qml/QRealType.qml

@ -1,7 +0,0 @@
import QtQuick 2.0
import org.ethereum.qml.QRealType 1.0
QRealType
{
}

7
mix/qml/QStringType.qml

@ -1,7 +0,0 @@
import QtQuick 2.0
import org.ethereum.qml.QStringType 1.0
QStringType
{
}

6
mix/qml/QStringTypeView.qml

@ -2,8 +2,10 @@ import QtQuick 2.0
Item
{
property alias text: textinput.text
property alias value: textinput.text
id: editRoot
height: 20
width: 150
SourceSansProBold
{
@ -16,7 +18,7 @@ Item
color: "#f7f7f7"
TextInput {
id: textinput
text: text
text: value
clip: true
anchors.fill: parent
wrapMode: Text.WrapAnywhere

10
mix/qml/SolidityTypeConverter.qml

@ -0,0 +1,10 @@
import QtQuick 2.0
Item
{
function toJson(value)
{
if (
}
}

2
mix/qml/StateDialog.qml

@ -373,7 +373,7 @@ Window {
{
iconSource: "qrc:/qml/img/edit.png"
action: editAction
visible: !stdContract
visible: stdContract === false
width: 10
height: 10
Action {

38
mix/qml/StateListModel.qml

@ -41,38 +41,13 @@ Item {
value: QEtherHelper.createEther(t.value.value, t.value.unit),
gas: QEtherHelper.createBigInt(t.gas.value),
gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit),
stdContract: t.stdContract,
stdContract: t.stdContract ? true : false,
parameters: {},
sender: t.sender
};
var qType = [];
for (var key in t.parameters)
{
r.parameters[key] = t.parameters[key].value;
var type = t.parameters[key].type;
var varComponent;
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");
else {
console.log("Unknown parameter type: " + type);
continue;
}
r.parameters[key] = t.parameters[key];
var param = varComponent.createObject(stateListModel);
var dec = Qt.createComponent("qrc:/qml/QVariableDeclaration.qml");
param.setDeclaration(dec.createObject(stateListModel, { "type": type }));
param.setValue(r.parameters[key]);
qType.push(param);
}
r.qType = qType;
return r;
}
@ -118,14 +93,7 @@ Item {
parameters: {}
};
for (var key in t.parameters)
{
var param = {
name: key,
value: t.parameters[key],
type: getParamType(key, t.qType)
}
r.parameters[key] = param;
}
r.parameters[key] = t.parameters[key];
return r;
}

182
mix/qml/StructView.qml

@ -0,0 +1,182 @@
import QtQuick 2.0
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import org.ethereum.qml.QSolidityType 1.0
Item
{
id: editRoot
property alias membersModel: repeater.model //js array
property var value
property int level: 0
Column
{
id: paramRepeater
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 3
Repeater
{
id: repeater
height: 20 * model.length
visible: model.length > 0
RowLayout
{
id: row
Layout.fillWidth: true
DefaultLabel {
id: typeLabel
text: modelData.type.name
Layout.preferredWidth: 50
}
DefaultLabel {
id: nameLabel
text: modelData.name
Layout.preferredWidth: 80
}
DefaultLabel {
id: equalLabel
text: "="
Layout.preferredWidth: 15
}
/*
Component.onCompleted: {
var t = type.type;
var src = undefined;
if (t === QSolidityType.SignedInteger || t === QSolidityType.UnsignedInteger)
src = "qrc:/qml/QIntTypeView.qml"
else if (t === QSolidityType.Bool)
src = "qrc:/qml/QBoolTypeView.qml"
else if (t === QSolidityType.String)
src = "qrc:/qml/QStringTypeView.qml"
else if (t === QSolidityType.Hash || t === QSolidityType.Address)
src = "qrc:/qml/QHashTypeView.qml"
else if (t === QSolidityType.Struct)
src = "qrc:/qml/StructView.qml";
else
return null;
typeLoader.setSource(src, {
height: 20,
width: 150,
value: typeLoader.getCurrent().value
});
console.log(src);
}
*/
Loader
{
id: typeLoader
Layout.preferredWidth: 150
/*
Binding {
target: typeLoader.item
property: "membersModel"
value: type.members
when: typeLoader.status === Loader.Ready
}*/
sourceComponent:
{
var t = modelData.type.type;
if (t === QSolidityType.SignedInteger || t === QSolidityType.UnsignedInteger)
return Qt.createComponent("qrc:/qml/QIntTypeView.qml");
else if (t === QSolidityType.Bool)
return Qt.createComponent("qrc:/qml/QBoolTypeView.qml");
else if (t === QSolidityType.String)
return Qt.createComponent("qrc:/qml/QStringTypeView.qml");
else if (t === QSolidityType.Hash || t === QSolidityType.Address)
return Qt.createComponent("qrc:/qml/QHashTypeView.qml");
else if (t === QSolidityType.Struct)
return Qt.createComponent("qrc:/qml/StructView.qml");
else
return undefined;
}
onLoaded:
{
var ptype = membersModel[index].type;
var pname = membersModel[index].name;
var vals = value;
if (ptype.type === QSolidityType.Struct && !item.membersModel) {
item.level = level + 1;
item.value = getValue();
item.membersModel = ptype.members;
}
else
item.value = getValue();
item.onValueChanged.connect(function() {
vals[pname] = item.value;
valueChanged();
});
}
function getValue()
{
if (value && value[modelData.name])
return value[modelData.name];
else if (modelData.type.type === QSolidityType.Struct)
return {};
return "";
}
Component
{
id: intViewComp
QIntTypeView
{
height: 20
width: 150
id: intView
}
}
Component
{
id: boolViewComp
QBoolTypeView
{
height: 20
width: 150
id: boolView
defaultValue: "1"
Component.onCompleted:
{
var current = getValue()
(current === "" ? text = defaultValue : text = current);
}
}
}
Component
{
id: stringViewComp
QStringTypeView
{
height: 20
width: 150
id: stringView
}
}
Component
{
id: hashViewComp
QHashTypeView
{
height: 20
width: 150
id: hashView
}
}
}
}
}
}
}

204
mix/qml/TransactionDialog.qml

@ -11,26 +11,24 @@ Window {
id: modalTransactionDialog
modality: Qt.ApplicationModal
width: 520
height: (paramsModel.count > 0 ? 500 : 300)
height: 500;//(paramsModel.count > 0 ? 500 : 300)
visible: false
color: StateDialogStyle.generic.backgroundColor
title: qsTr("Edit Transaction")
property int transactionIndex
property alias transactionParams: paramsModel;
property alias gas: gasValueEdit.gasValue;
property alias gasPrice: gasPriceField.value;
property alias transactionValue: valueField.value;
property string contractId: contractComboBox.currentValue();
property alias functionId: functionComboBox.currentText;
property var itemParams;
property var paramValues;
property var paramsModel: [];
property bool useTransactionDefaultValue: false
property var qType;
property alias stateAccounts: senderComboBox.model
signal accepted;
function open(index, item) {
qType = [];
rowFunction.visible = !useTransactionDefaultValue;
rowValue.visible = !useTransactionDefaultValue;
rowGas.visible = !useTransactionDefaultValue;
@ -44,7 +42,7 @@ Window {
var functionId = item.functionId;
rowFunction.visible = true;
itemParams = item.parameters !== undefined ? item.parameters : {};
paramValues = item.parameters !== undefined ? item.parameters : {};
if (item.sender)
senderComboBox.select(item.sender);
@ -73,15 +71,15 @@ Window {
functionComboBox.currentIndex = functionIndex;
paramsModel.clear();
paramsModel = [];
if (functionId !== contractComboBox.currentValue())
loadParameters();
else {
var contract = codeModel.contracts[contractId];
if (contract) {
var parameters = contract.contract.constructor.parameters;
for (var p = 0; p < parameters.length; p++)
loadParameter(parameters[p]);
var params = contract.contract.constructor.params;
for (var p = 0; p < params.length; p++)
loadParameter(params[p]);
}
}
modalTransactionDialog.setX((Screen.width - width) / 2);
@ -110,32 +108,11 @@ Window {
{
var type = parameter.type;
var pname = parameter.name;
var varComponent;
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(parameter);
qType.push({ name: pname, value: param });
paramsModel.append({ name: pname, type: type, value: value });
paramsModel.push({ name: pname, type: type });
}
function loadParameters() {
paramsModel.clear();
if (!paramsModel)
return;
paramsModel = []
if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) {
var contract = codeModel.contracts[contractComboBox.currentValue()];
if (contract) {
@ -147,31 +124,29 @@ Window {
}
}
}
typeLoader.value = {}
typeLoader.membersModel = []
typeLoader.value = paramValues;
typeLoader.membersModel = paramsModel;
}
/*
function param(name)
{
for (var k = 0; k < paramsModel.count; k++)
for (var k = 0; k < paramsModel.length; k++)
{
if (paramsModel.get(k).name === name)
return paramsModel.get(k);
if (paramsModel[k].name === name)
return paramsModel[k];
}
}
*/
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;
@ -194,15 +169,7 @@ Window {
}
item.sender = senderComboBox.model[senderComboBox.currentIndex].secret;
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;
item.parameters = paramValues;
return item;
}
@ -370,7 +337,7 @@ Window {
id: paramLabel
text: qsTr("Parameters:")
Layout.preferredWidth: 75
visible: paramsModel.count > 0
visible: true;//paramsModel.length > 0
}
ScrollView
@ -379,128 +346,19 @@ Window {
anchors.topMargin: 10
Layout.preferredWidth: 350
Layout.fillHeight: true
visible: paramsModel.count > 0
visible: true;//paramsModel.length > 0
Column
{
id: paramRepeater
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 3
Repeater
{
height: 20 * paramsModel.count
model: paramsModel
visible: paramsModel.count > 0
RowLayout
{
id: row
Layout.fillWidth: true
height: 20
DefaultLabel {
id: typeLabel
text: type
Layout.preferredWidth: 50
}
DefaultLabel {
id: nameLabel
text: name
Layout.preferredWidth: 80
}
DefaultLabel {
id: equalLabel
text: "="
Layout.preferredWidth: 15
}
Loader
{
id: typeLoader
Layout.preferredWidth: 150
function getCurrent()
{
return modalTransactionDialog.param(name);
}
Connections {
target: typeLoader.item
onTextChanged: {
typeLoader.getCurrent().value = typeLoader.item.text;
}
}
sourceComponent:
{
if (type.indexOf("int") !== -1)
return intViewComp;
else if (type.indexOf("bool") !== -1)
return boolViewComp;
else if (type.indexOf("string") !== -1)
return stringViewComp;
else if (type.indexOf("hash") !== -1 || type.indexOf("address") !== -1)
return hashViewComp;
else
return null;
}
Component
{
id: intViewComp
QIntTypeView
{
height: 20
width: 150
id: intView
text: typeLoader.getCurrent().value
}
}
Component
{
id: boolViewComp
QBoolTypeView
{
height: 20
width: 150
id: boolView
defaultValue: "1"
Component.onCompleted:
{
var current = typeLoader.getCurrent().value;
(current === "" ? text = defaultValue : text = current);
}
}
}
Component
{
id: stringViewComp
QStringTypeView
{
height: 20
width: 150
id: stringView
text:
{
return typeLoader.getCurrent().value
}
}
}
Component
{
id: hashViewComp
QHashTypeView
{
height: 20
width: 150
id: hashView
text: typeLoader.getCurrent().value
}
}
}
}
StructView
{
id: typeLoader
Layout.preferredWidth: 150
membersModel: paramsModel;
}
}
}
@ -508,7 +366,7 @@ Window {
CommonSeparator
{
Layout.fillWidth: true
visible: paramsModel.count > 0
visible: paramsModel.length > 0
}
}
@ -530,8 +388,4 @@ Window {
}
}
}
ListModel {
id: paramsModel
}
}

7
mix/res.qrc

@ -44,13 +44,8 @@
<file>qml/EtherValue.qml</file>
<file>qml/BigIntValue.qml</file>
<file>qml/QVariableDefinition.qml</file>
<file>qml/QBoolType.qml</file>
<file>qml/QHashType.qml</file>
<file>qml/QIntType.qml</file>
<file>qml/QRealType.qml</file>
<file>qml/js/QEtherHelper.js</file>
<file>qml/js/TransactionHelper.js</file>
<file>qml/QStringType.qml</file>
<file>qml/QBoolTypeView.qml</file>
<file>qml/QIntTypeView.qml</file>
<file>qml/QRealTypeView.qml</file>
@ -115,5 +110,7 @@
<file>qml/img/copy.png</file>
<file>qml/img/broom.png</file>
<file>qml/LogsPaneStyle.qml</file>
<file>qml/SolidityTypeConverter.qml</file>
<file>qml/StructView.qml</file>
</qresource>
</RCC>

Loading…
Cancel
Save