Browse Source

Transaction QML model

cl-refactor
arkpar 10 years ago
parent
commit
0594f79267
  1. 3
      mix/AppContext.cpp
  2. 14
      mix/AssemblyDebuggerControl.cpp
  3. 25
      mix/CodeModel.cpp
  4. 21
      mix/CodeModel.h
  5. 2
      mix/ConstantCompilationControl.cpp
  6. 36
      mix/ProjectFile.cpp
  7. 57
      mix/ProjectFile.h
  8. 8
      mix/QContractDefinition.h
  9. 10
      mix/QFunctionDefinition.h
  10. 3
      mix/QVariableDeclaration.h
  11. 23
      mix/TransactionListModel.cpp
  12. 6
      mix/TransactionListModel.h
  13. 2
      mix/TransactionListView.cpp
  14. 3
      mix/qml.qrc
  15. 22
      mix/qml/TransactionDialog.qml
  16. 11
      mix/qml/TransactionItem.qml
  17. 36
      mix/qml/TransactionList.qml

3
mix/AppContext.cpp

@ -25,6 +25,7 @@
#include <QDebug>
#include <QMessageBox>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <libdevcrypto/FileSystem.h>
#include <libwebthree/WebThree.h>
@ -43,6 +44,8 @@ AppContext::AppContext(QQmlApplicationEngine* _engine)
m_keyEventManager = std::unique_ptr<KeyEventManager>(new KeyEventManager());
m_webThree = std::unique_ptr<dev::WebThreeDirect>(new WebThreeDirect(std::string("Mix/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/Mix", false, {"eth", "shh"}));
m_codeModel = std::unique_ptr<CodeModel>(new CodeModel(this));
m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get());
}
AppContext::~AppContext()

14
mix/AssemblyDebuggerControl.cpp

@ -90,7 +90,7 @@ void AssemblyDebuggerControl::keyPressed(int _key)
void AssemblyDebuggerControl::callContract(TransactionSettings _tr, Address _contract)
{
auto compilerRes = m_ctx->codeModel()->lastCompilationResult();
auto compilerRes = m_ctx->codeModel()->code();
if (!compilerRes->successfull())
m_ctx->displayMessageDialog("debugger","compilation failed");
else
@ -98,11 +98,11 @@ void AssemblyDebuggerControl::callContract(TransactionSettings _tr, Address _con
ContractCallDataEncoder c;
QContractDefinition const* contractDef = compilerRes->contract();
QFunctionDefinition* f = nullptr;
for (int k = 0; k < contractDef->functions().size(); k++)
for (int k = 0; k < contractDef->functionsList().size(); k++)
{
if (contractDef->functions().at(k)->name() == _tr.functionId)
if (contractDef->functionsList().at(k)->name() == _tr.functionId)
{
f = (QFunctionDefinition*)contractDef->functions().at(k);
f = contractDef->functionsList().at(k);
break;
}
}
@ -111,9 +111,9 @@ void AssemblyDebuggerControl::callContract(TransactionSettings _tr, Address _con
else
{
c.encode(f->index());
for (int k = 0; k < f->parameters().size(); k++)
for (int k = 0; k < f->parametersList().size(); k++)
{
QVariableDeclaration* var = (QVariableDeclaration*)f->parameters().at(k);
QVariableDeclaration* var = (QVariableDeclaration*)f->parametersList().at(k);
c.encode(var, _tr.parameterValues[var->name()]);
}
DebuggingContent debuggingContent = m_modelDebugger->callContract(_contract, c.encodedData(), _tr);
@ -125,7 +125,7 @@ void AssemblyDebuggerControl::callContract(TransactionSettings _tr, Address _con
void AssemblyDebuggerControl::deployContract()
{
auto compilerRes = m_ctx->codeModel()->lastCompilationResult();
auto compilerRes = m_ctx->codeModel()->code();
if (!compilerRes->successfull())
emit dataAvailable(false, DebuggingStatusResult::Compilationfailed);
else

25
mix/CodeModel.cpp

@ -23,10 +23,13 @@
#include <sstream>
#include <QDebug>
#include <QApplication>
#include <QtQml>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libevmcore/Instruction.h>
#include "QContractDefinition.h"
#include "QFunctionDefinition.h"
#include "QVariableDeclaration.h"
#include "CodeModel.h"
namespace dev
@ -59,6 +62,13 @@ CodeModel::CodeModel(QObject* _parent) : QObject(_parent),
{
m_backgroundWorker.moveToThread(&m_backgroundThread);
connect(this, &CodeModel::scheduleCompilationJob, &m_backgroundWorker, &BackgroundWorker::queueCodeChange, Qt::QueuedConnection);
connect(this, &CodeModel::compilationCompleteInternal, this, &CodeModel::onCompilationComplete, Qt::QueuedConnection);
qRegisterMetaType<CompilationResult*>("CompilationResult*");
qRegisterMetaType<QContractDefinition*>("QContractDefinition*");
qRegisterMetaType<QFunctionDefinition*>("QFunctionDefinition*");
qRegisterMetaType<QVariableDeclaration*>("QVariableDeclaration*");
qmlRegisterType<QFunctionDefinition>("org.ethereum.qml", 1, 0, "QFunctionDefinition");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml", 1, 0, "QVariableDeclaration");
m_backgroundThread.start();
}
@ -93,19 +103,26 @@ void CodeModel::runCompilationJob(int _jobId, QString const& _code)
{
cs.setSource(_code.toStdString());
cs.compile(false);
std::shared_ptr<CompilationResult> result(new CompilationResult(cs, nullptr));
m_result.swap(result);
std::unique_ptr<CompilationResult> result(new CompilationResult(cs, nullptr));
qDebug() << QString(QApplication::tr("compilation succeeded"));
emit compilationCompleteInternal(result.release());
}
catch (dev::Exception const& _exception)
{
std::ostringstream error;
solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs);
std::shared_ptr<CompilationResult> result(new CompilationResult(*m_result, QString::fromStdString(error.str()), nullptr));
m_result.swap(result);
std::unique_ptr<CompilationResult> result(new CompilationResult(*m_result, QString::fromStdString(error.str()), nullptr));
qDebug() << QString(QApplication::tr("compilation failed") + " " + m_result->compilerMessage());
emit compilationCompleteInternal(result.release());
}
}
void CodeModel::onCompilationComplete(CompilationResult*_newResult)
{
m_result.reset(_newResult);
emit compilationComplete();
if (m_result->successfull())
emit codeChanged();
}
}

21
mix/CodeModel.h

@ -59,7 +59,7 @@ private:
class CompilationResult : public QObject
{
Q_OBJECT
Q_PROPERTY(QContractDefinition const* contract READ contract)
Q_PROPERTY(QContractDefinition* contract READ contract)
public:
/// Successfull compilation result constructor
@ -68,7 +68,7 @@ public:
CompilationResult(CompilationResult const& _prev, QString const& _compilerMessage, QObject* parent);
/// @returns contract definition
QContractDefinition const* contract() const { return m_contract.get(); }
QContractDefinition* contract() { return m_contract.get(); }
/// Indicates if the compilation was successfull
bool successfull() const { return m_successfull; }
@ -84,7 +84,7 @@ public:
private:
bool m_successfull;
std::shared_ptr<QContractDefinition const> m_contract;
std::shared_ptr<QContractDefinition> m_contract;
QString m_compilerMessage; ///< @todo: use some structure here
dev::bytes m_bytes;
QString m_assemblyCode;
@ -107,7 +107,11 @@ public:
~CodeModel();
/// @returns latest compilation result
std::shared_ptr<CompilationResult> lastCompilationResult() { return m_result; }
CompilationResult* code() { return m_result.get(); }
/// @returns latest compilation resul
CompilationResult const* code() const { return m_result.get(); }
Q_PROPERTY(CompilationResult* code READ code NOTIFY codeChanged)
signals:
/// Emited on compilation status change
@ -116,6 +120,13 @@ signals:
void compilationComplete();
/// Internal signal used to transfer compilation job to background thread
void scheduleCompilationJob(int _jobId, QString const& _content);
/// Emitted if there are any changes in the code model
void codeChanged();
/// Emitted on compilation complete. Internal
void compilationCompleteInternal(CompilationResult* _newResult);
private slots:
void onCompilationComplete(CompilationResult*_newResult);
public slots:
/// Update code model on source code change
@ -125,7 +136,7 @@ private:
void runCompilationJob(int _jobId, QString const& _content);
void stop();
std::shared_ptr<CompilationResult> m_result;
std::unique_ptr<CompilationResult> m_result;
QThread m_backgroundThread;
BackgroundWorker m_backgroundWorker;
int m_backgroundJobId = 0; //protects from starting obsolete compilation job

2
mix/ConstantCompilationControl.cpp

@ -55,7 +55,7 @@ void ConstantCompilationControl::start() const
void ConstantCompilationControl::update()
{
auto result = m_ctx->codeModel()->lastCompilationResult();
auto result = m_ctx->codeModel()->code();
QObject* status = m_view->findChild<QObject*>("status", Qt::FindChildrenRecursively);
QObject* content = m_view->findChild<QObject*>("content", Qt::FindChildrenRecursively);

36
mix/ProjectFile.cpp

@ -0,0 +1,36 @@
/*
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 ProjectFile.cpp
* @author Arkadiy Paronyan arkadiy@ethdev.com
* @date 2014
* Ethereum IDE client.
*/
#include <jsoncpp/json/json.h>
#include "ProjectFile.h"
namespace dev
{
namespace mix
{
void ProjectFile::saveProject()
{
}
}
}

57
mix/ProjectFile.h

@ -0,0 +1,57 @@
/*
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 ProjectFile.h
* @author Arkadiy Paronyan arkadiy@ethdev.com
* @date 2014
* Ethereum IDE client.
*/
#pragma once
#include <QString>
#include "TransactionListModel.h"
namespace dev
{
namespace mix
{
/// Background code compiler
class ProjectFile : public QObject
{
Q_OBJECT
public:
ProjectFile();
void loadProject();
signals:
void projectLoaded();
public slots:
void saveProject();
private:
QString defaultProjectPath() const;
TransactionListModel* transactionModel();
};
}
}

8
mix/QContractDefinition.h

@ -22,6 +22,7 @@
#pragma once
#include <QObject>
#include <QQmlListProperty>
#include <libsolidity/AST.h>
#include "QFunctionDefinition.h"
#include "QBasicNodeDefinition.h"
@ -34,16 +35,17 @@ namespace mix
class QContractDefinition: public QBasicNodeDefinition
{
Q_OBJECT
Q_PROPERTY(QList<QFunctionDefinition*> functions READ functions)
Q_PROPERTY(QQmlListProperty<dev::mix::QFunctionDefinition> functions READ functions CONSTANT)
public:
QContractDefinition(solidity::ContractDefinition const* _contract);
/// Get all the functions of the contract.
QList<QFunctionDefinition*> functions() const { return m_functions; }
QQmlListProperty<QFunctionDefinition> functions() const { return QQmlListProperty<QFunctionDefinition>(const_cast<QContractDefinition*>(this), const_cast<QContractDefinition*>(this)->m_functions); }
QList<QFunctionDefinition*> const& functionsList() const { return m_functions; }
private:
QList<QFunctionDefinition*> m_functions;
};
}
}

10
mix/QFunctionDefinition.h

@ -22,8 +22,9 @@
#pragma once
#include <QObject>
#include <QQmlListProperty>
#include <libsolidity/AST.h>
#include <QVariableDeclaration.h>
#include "QVariableDeclaration.h"
#include "QBasicNodeDefinition.h"
namespace dev
@ -34,13 +35,16 @@ namespace mix
class QFunctionDefinition: public QBasicNodeDefinition
{
Q_OBJECT
Q_PROPERTY(QList<QVariableDeclaration*> parameters READ parameters)
Q_PROPERTY(QQmlListProperty<dev::mix::QVariableDeclaration> parameters READ parameters)
Q_PROPERTY(int index READ index)
public:
QFunctionDefinition() {}
QFunctionDefinition(solidity::FunctionDefinition const* _f, int _index);
/// Get all input parameters of this function.
QList<QVariableDeclaration*> parameters() const { return m_parameters; }
QList<QVariableDeclaration*> const& parametersList() const { return m_parameters; }
/// Get all input parameters of this function as QML property.
QQmlListProperty<QVariableDeclaration> parameters() const { return QQmlListProperty<QVariableDeclaration>(const_cast<QFunctionDefinition*>(this), const_cast<QFunctionDefinition*>(this)->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.

3
mix/QVariableDeclaration.h

@ -35,6 +35,7 @@ class QVariableDeclaration: public QBasicNodeDefinition
Q_PROPERTY(QString type READ type CONSTANT)
public:
QVariableDeclaration() {}
QVariableDeclaration(solidity::VariableDeclaration const* _v): QBasicNodeDefinition(_v), m_type(QString::fromStdString(_v->getType()->toString())) {}
QString type() const { return m_type; }
private:
@ -43,5 +44,3 @@ private:
}
}
Q_DECLARE_METATYPE(dev::mix::QVariableDeclaration*)

23
mix/TransactionListModel.cpp

@ -96,14 +96,14 @@ QVariant TransactionListModel::data(QModelIndex const& _index, int _role) const
QList<TransactionParameterItem*> buildParameters(CodeModel* _codeModel, TransactionSettings const& _transaction, QString const& _functionId)
{
QList<TransactionParameterItem*> params;
QContractDefinition const* contract = _codeModel->lastCompilationResult()->contract();
auto functions = contract->functions();
QContractDefinition const* contract = _codeModel->code()->contract();
auto functions = contract->functionsList();
for (auto f : functions)
{
if (f->name() != _functionId)
continue;
auto parameters = f->parameters();
auto parameters = f->parametersList();
for (auto p : parameters)
{
QString paramValue;
@ -126,8 +126,8 @@ QList<TransactionParameterItem*> buildParameters(CodeModel* _codeModel, Transact
QList<QString> TransactionListModel::getFunctions()
{
QList<QString> functionNames;
QContractDefinition const* contract = m_appContext->codeModel()->lastCompilationResult()->contract();
auto functions = contract->functions();
QContractDefinition const* contract = m_appContext->codeModel()->code()->contract();
auto functions = contract->functionsList();
for (auto f : functions)
{
functionNames.append(f->name());
@ -200,6 +200,19 @@ void TransactionListModel::runTransaction(int _index)
emit transactionStarted(tr);
}
QVariantMap TransactionListModel::save()
{
}
/// Load transactions from a map
void TransactionListModel::load(QVariantMap const& _data)
{
std::vector<TransactionSettings> transactions;
m_transactions.swap(transactions);
}
}
}

6
mix/TransactionListModel.h

@ -24,9 +24,11 @@
#include <QObject>
#include <QVariant>
#include <QVariantMap>
#include <QAbstractListModel>
#include <QHash>
#include <QByteArray>
#include <QVariantMap>
#include <libdevcore/Common.h>
#include <libethcore/CommonEth.h>
@ -150,6 +152,10 @@ public:
Q_INVOKABLE QVariantList getParameters(int _id, QString const& _functionId);
/// Launch transaction execution UI handler
Q_INVOKABLE void runTransaction(int _index);
/// Save transaction to a map for serialization into file
QVariantMap save();
/// Load transactions from a map
void load(QVariantMap const& _data);
signals:
/// Transaction count has changed

2
mix/TransactionListView.cpp

@ -32,7 +32,7 @@ using namespace dev::mix;
TransactionListView::TransactionListView(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::RightTab)
{
m_model.reset(new TransactionListModel(this, _context));
m_appEngine->rootContext()->setContextProperty("transactionListModel", m_model.get());
//m_appEngine->rootContext()->setContextProperty("transactionListModel", m_model.get());
}
TransactionListView::~TransactionListView()

3
mix/qml.qrc

@ -11,5 +11,8 @@
<file>qml/TransactionList.qml</file>
<file>qml/ModalDialog.qml</file>
<file>qml/AlertMessageDialog.qml</file>
<file>qml/StateItem.qml</file>
<file>qml/StateList.qml</file>
<file>qml/TransactionItem.qml</file>
</qresource>
</RCC>

22
mix/qml/TransactionDialog.qml

@ -32,9 +32,7 @@ Window {
signal accepted;
function reset(index, m) {
model = m;
var item = model.getItem(index);
function reset(index, item) {
transactionIndex = index;
transactionTitle = item.title;
gas = item.gas;
@ -43,10 +41,10 @@ Window {
var functionId = item.functionId;
functionsModel.clear();
var functionIndex = -1;
var functions = model.getFunctions();
var functions = codeModel.code.contract.functions;
for (var f = 0; f < functions.length; f++) {
functionsModel.append({ text: functions[f] });
if (functions[f] === item.functionId)
functionsModel.append({ text: functions[f].name });
if (functions[f].name === item.functionId)
functionIndex = f;
}
functionComboBox.currentIndex = functionIndex;
@ -57,9 +55,13 @@ Window {
return;
paramsModel.clear();
if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) {
var parameters = model.getParameters(transactionIndex, functionsModel.get(functionComboBox.currentIndex).text);
console.log(codeModel.code.contract.functions[functionComboBox.currentIndex]);
var func = codeModel.code.contract.functions[functionComboBox.currentIndex];
var parameters = func.parameters;
console.log(parameters);
console.log(parameters.length);
for (var p = 0; p < parameters.length; p++) {
paramsModel.append({ name: parameters[p].name, type: parameters[p].type, value: parameters[p].value });
paramsModel.append({ name: parameters[p].name, type: parameters[p].type, value: parameters[p].value !== undefined ? parameters[p].value : "" });
}
}
}
@ -195,7 +197,9 @@ Window {
Connections {
target: loaderEditor.item
onTextChanged: {
paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text);
console.log(styleData.row + " : " + styleData.role + " = " + loaderEditor.item.text );
if (styleData.role === "value" && styleData.row < paramsModel.count)
paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text);
}
}
sourceComponent: (styleData.selected) ? editor : null

11
mix/qml/TransactionItem.qml

@ -0,0 +1,11 @@
import QtQuick 2.2
Item {
property string title;
property string functionId;
property string value;
property string gas;
property string gasPrice;
property var paramValues;
}

36
mix/qml/TransactionList.qml

@ -19,7 +19,14 @@ Rectangle {
height: parent.height
width: parent.width
id: transactionList
model: transactionListModel
model: ListModel {
id: transactionListModel
function runTransaction(index) {
console.log("runTransaction");
}
}
delegate: renderDelegate
}
@ -30,8 +37,16 @@ Rectangle {
{
// 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);
// Second call to signal handler would just edit the item that was just created, no harm done
var item = {
title: "",
value: "",
functionId: "",
gas: "1000000000000",
gasPrice: "100000"
};
transactionDialog.reset(transactionListModel.count, item);
transactionDialog.open();
transactionDialog.focus = true;
}
@ -40,7 +55,18 @@ Rectangle {
TransactionDialog {
id: transactionDialog
onAccepted: {
transactionListModel.edit(transactionDialog);
var item = {
title: transactionDialog.transactionTitle,
functionId: transactionDialog.functionId,
gas: transactionDialog.gas,
gasPrice: transactionDialog.gasPrice,
value: transactionDialog.transactionValue
}
console.log(item.title);
if (transactionDialog.transactionIndex < transactionListModel.count)
transactionListModel.set(transactionDialog.transactionIndex, item);
else
transactionListModel.append(item);
}
}
@ -65,7 +91,7 @@ Rectangle {
text: qsTr("Edit");
Layout.fillHeight: true
onClicked: {
transactionDialog.reset(index, transactionListModel);
transactionDialog.reset(index, transactionListModel.get(index));
transactionDialog.open();
transactionDialog.focus = true;
}

Loading…
Cancel
Save