Browse Source

cosmetic changes

cl-refactor
yann300 10 years ago
parent
commit
ec62858be1
  1. 2
      mix/ClientModel.cpp
  2. 57
      mix/ClientModel.h
  3. 2
      mix/ContractCallDataEncoder.cpp
  4. 2
      mix/ContractCallDataEncoder.h
  5. 86
      mix/MachineStates.h
  6. 55
      mix/MixClient.cpp
  7. 5
      mix/MixClient.h
  8. 2
      mix/QContractDefinition.cpp
  9. 4
      mix/main.cpp
  10. 10
      mix/qml/Application.qml
  11. 614
      mix/qml/Block.qml
  12. 931
      mix/qml/BlockChain.qml
  13. 144
      mix/qml/Debugger.qml
  14. 108
      mix/qml/MainContent.qml
  15. 3
      mix/qml/QAddressView.qml
  16. 112
      mix/qml/ScenarioButton.qml
  17. 78
      mix/qml/ScenarioExecution.qml
  18. 318
      mix/qml/ScenarioLoader.qml
  19. 241
      mix/qml/StateListModel.qml
  20. 2
      mix/qml/StructView.qml
  21. 20
      mix/qml/TransactionDialog.qml
  22. 110
      mix/qml/js/ProjectModel.js
  23. 4
      mix/qml/js/TransactionHelper.js

2
mix/ClientModel.cpp

@ -438,7 +438,7 @@ std::pair<QString, int> ClientModel::resolvePair(QString const& _contractId)
QString ClientModel::resolveToken(std::pair<QString, int> const& _value)
{
if (_value.second == -2)
if (_value.second == -2) //-2: first contains a real address
return _value.first;
else if (m_contractAddresses.size() > 0)
return QString::fromStdString("0x" + dev::toHex(m_contractAddresses[_value].ref()));

57
mix/ClientModel.h

@ -109,14 +109,14 @@ class RecordLogEntry: public QObject
Q_PROPERTY(RecordType type MEMBER m_type CONSTANT)
/// Gas used
Q_PROPERTY(QString gasUsed MEMBER m_gasUsed CONSTANT)
/// Sender
Q_PROPERTY(QString sender MEMBER m_sender CONSTANT)
/// label
Q_PROPERTY(QString label MEMBER m_label CONSTANT)
/// input parameters
Q_PROPERTY(QVariantMap parameters MEMBER m_inputParameters CONSTANT)
/// logs
Q_PROPERTY(QVariantList logs MEMBER m_logs CONSTANT)
/// Sender
Q_PROPERTY(QString sender MEMBER m_sender CONSTANT)
/// label
Q_PROPERTY(QString label MEMBER m_label CONSTANT)
/// input parameters
Q_PROPERTY(QVariantMap parameters MEMBER m_inputParameters CONSTANT)
/// logs
Q_PROPERTY(QVariantList logs MEMBER m_logs CONSTANT)
public:
enum RecordType
@ -127,10 +127,10 @@ public:
RecordLogEntry():
m_recordIndex(0), m_call(false), m_type(RecordType::Transaction) {}
RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call, RecordType _type, QString _gasUsed,
QString _sender, QString _label, QVariantMap _inputParameters, QVariantList _logs):
m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call), m_type(_type), m_gasUsed(_gasUsed),
m_sender(_sender), m_label(_label), m_inputParameters(_inputParameters), m_logs(_logs) {}
RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call, RecordType _type, QString _gasUsed,
QString _sender, QString _label, QVariantMap _inputParameters, QVariantList _logs):
m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call), m_type(_type), m_gasUsed(_gasUsed),
m_sender(_sender), m_label(_label), m_inputParameters(_inputParameters), m_logs(_logs) {}
private:
unsigned m_recordIndex;
@ -143,10 +143,10 @@ private:
bool m_call;
RecordType m_type;
QString m_gasUsed;
QString m_sender;
QString m_label;
QVariantMap m_inputParameters;
QVariantList m_logs;
QString m_sender;
QString m_label;
QVariantMap m_inputParameters;
QVariantList m_logs;
};
/**
@ -185,14 +185,11 @@ public:
Q_INVOKABLE QString toHex(QString const& _int);
public slots:
/// Setup state, run transaction sequence, show debugger for the last transaction
/// Setup scenario, run transaction sequence, show debugger for the last transaction
/// @param _state JS object with state configuration
//void setupState(QVariantMap _state);
/// Setup scenario, run transaction sequence, show debugger for the last transaction
/// @param _state JS object with state configuration
void setupScenario(QVariantMap _scenario);
/// Execute the given @param _tr on the curret state
void executeTr(QVariantMap _tr);
void setupScenario(QVariantMap _scenario);
/// Execute the given @param _tr on the current state
void executeTr(QVariantMap _tr);
/// Show the debugger for a specified record
Q_INVOKABLE void debugRecord(unsigned _index);
/// Show the debugger for an empty record
@ -244,7 +241,7 @@ private:
RecordLogEntry* lastBlock() const;
QVariantMap contractAddresses() const;
QVariantList gasCosts() const;
void executeSequence(std::vector<TransactionSettings> const& _sequence);
void executeSequence(std::vector<TransactionSettings> const& _sequence);
dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings());
void callAddress(Address const& _contract, bytes const& _data, TransactionSettings const& _tr);
void onNewTransaction();
@ -255,9 +252,9 @@ private:
std::pair<QString, int> retrieveToken(QString const& _value);
std::pair<QString, int> resolvePair(QString const& _contractId);
QVariant formatStorageValue(SolidityType const& _type, std::unordered_map<dev::u256, dev::u256> const& _storage, unsigned _offset, dev::u256 const& _slot);
void processNextTransactions();
void finalizeBlock();
void stopExecution();
void processNextTransactions();
void finalizeBlock();
void stopExecution();
void setupExecutionChain();
std::atomic<bool> m_running;
@ -267,7 +264,7 @@ private:
std::unique_ptr<RpcConnector> m_rpcConnector;
std::unique_ptr<Web3Server> m_web3Server;
std::shared_ptr<eth::FixedAccountHolder> m_ethAccounts;
std::unordered_map<Address, eth::Account> m_accounts;
std::unordered_map<Address, eth::Account> m_accounts;
std::vector<KeyPair> m_accountsSecret;
QList<u256> m_gasCosts;
std::map<std::pair<QString, int>, Address> m_contractAddresses;
@ -275,8 +272,8 @@ private:
std::map<QString, Address> m_stdContractAddresses;
std::map<Address, QString> m_stdContractNames;
CodeModel* m_codeModel = nullptr;
QList<QVariantList> m_queueTransactions;
QVariantMap m_currentScenario;
QList<QVariantList> m_queueTransactions;
QVariantMap m_currentScenario;
mutable boost::shared_mutex x_queueTransactions;
};

2
mix/ContractCallDataEncoder.cpp

@ -245,7 +245,7 @@ QStringList ContractCallDataEncoder::decode(QList<QVariableDeclaration*> const&
value.populate(&rawParam);
value = value.cropped(32);
QVariableDeclaration* dec = static_cast<QVariableDeclaration*>(_returnParameters.at(k));
SolidityType const& type = dec->type()->type();
SolidityType const& type = dec->type()->type();
r.append(decode(type, rawParam).toString());
}
return r;

2
mix/ContractCallDataEncoder.h

@ -50,7 +50,7 @@ public:
QStringList decode(QList<QVariableDeclaration*> const& _dec, bytes _value);
/// Decode @param _parameter
QString decode(QVariableDeclaration* const& _param, bytes _value);
/// Decode single variable
/// Decode single variable
QVariant decode(SolidityType const& _type, bytes const& _value);
/// Get all encoded data encoded by encode function.
bytes encodedData();

86
mix/MachineStates.h

@ -37,59 +37,59 @@ namespace dev
namespace mix
{
/**
/**
* @brief Store information about a machine state.
*/
struct MachineState
{
uint64_t steps;
dev::u256 curPC;
dev::eth::Instruction inst;
dev::bigint newMemSize;
dev::u256 gas;
dev::u256s stack;
dev::bytes memory;
dev::bigint gasCost;
std::unordered_map<dev::u256, dev::u256> storage;
std::vector<unsigned> levels;
unsigned codeIndex;
unsigned dataIndex;
};
struct MachineState
{
uint64_t steps;
dev::u256 curPC;
dev::eth::Instruction inst;
dev::bigint newMemSize;
dev::u256 gas;
dev::u256s stack;
dev::bytes memory;
dev::bigint gasCost;
std::unordered_map<dev::u256, dev::u256> storage;
std::vector<unsigned> levels;
unsigned codeIndex;
unsigned dataIndex;
};
/**
/**
* @brief Executed conract code info
*/
struct MachineCode
{
dev::Address address;
bytes code;
};
struct MachineCode
{
dev::Address address;
bytes code;
};
/**
/**
* @brief Store information about a machine states.
*/
struct ExecutionResult
{
ExecutionResult(): transactionIndex(std::numeric_limits<unsigned>::max()) {}
struct ExecutionResult
{
ExecutionResult(): transactionIndex(std::numeric_limits<unsigned>::max()) {}
std::vector<MachineState> machineStates;
std::vector<bytes> transactionData;
std::vector<MachineCode> executionCode;
dev::eth::ExecutionResult result;
dev::Address address;
dev::Address sender;
dev::Address contractAddress;
dev::u256 value;
dev::u256 gasUsed;
unsigned transactionIndex;
unsigned executonIndex = 0;
bytes inputParameters;
eth::LocalisedLogEntries logs;
std::vector<MachineState> machineStates;
std::vector<bytes> transactionData;
std::vector<MachineCode> executionCode;
dev::eth::ExecutionResult result;
dev::Address address;
dev::Address sender;
dev::Address contractAddress;
dev::u256 value;
dev::u256 gasUsed;
unsigned transactionIndex;
unsigned executonIndex = 0;
bytes inputParameters;
eth::LocalisedLogEntries logs;
bool isCall() const { return transactionIndex == std::numeric_limits<unsigned>::max(); }
bool isConstructor() const { return !isCall() && !address; }
};
bool isCall() const { return transactionIndex == std::numeric_limits<unsigned>::max(); }
bool isConstructor() const { return !isCall() && !address; }
};
using ExecutionResults = std::vector<ExecutionResult>;
using ExecutionResults = std::vector<ExecutionResult>;
}
}

55
mix/MixClient.cpp

@ -73,25 +73,11 @@ MixClient::MixClient(std::string const& _dbPath):
resetState(std::unordered_map<Address, Account>());
}
MixClient::~MixClient()
{
}
LocalisedLogEntries MixClient::logs()
{
return m_watches.at(0).changes;
}
void MixClient::resetState(std::unordered_map<Address, Account> const& _accounts, Secret const& _miner)
{
WriteGuard l(x_state);
Guard fl(x_filtersWatches);
m_filters.clear();
m_watches.clear();
//LogFilter filter;
//m_filters.insert(std::make_pair(filter.sha3(), filter));
//m_watches.insert(std::make_pair(0, ClientWatch(filter.sha3(), Reaping::Automatic)));
m_stateDB = OverlayDB();
SecureTrieDB<Address, MemoryDB> accountState(&m_stateDB);
@ -261,39 +247,15 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
if (t.isCreation() && _state.code(d.contractAddress).empty())
BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment"));
d.gasUsed = er.gasUsed + er.gasRefunded + er.gasForDeposit + c_callStipend;
// collect watches
h256Set changed;
Guard l(x_filtersWatches);
LocalisedLogEntries logs;
//for (unsigned i = 0; i < _state.pending().size(); ++i)
//{
TransactionReceipt const& tr = _state.receipt(_state.pending().size() - 1);
auto trHash = _state.pending().at(_state.pending().size() - 1).sha3();
//for (std::pair<h256 const, eth::InstalledFilter>& installedFilter: m_filters)
//{
LogEntries le = tr.log(); // installedFilter.second.filter.matches(tr);
LogEntries le = tr.log();
if (le.size())
for (unsigned j = 0; j < le.size(); ++j)
logs.insert(logs.begin(), LocalisedLogEntry(le[j], bc().number() + 1, trHash));
//}
//}
/*if ((unsigned)i.second.filter.latest() > bc().number())
{
// acceptable number.
auto m = i.second.filter.matches(_state.receipt(_state.pending().size() - 1));
if (m.size())
{
// filter catches them
for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l, bc().number() + 1));
changed.insert(i.first);
}
}*/
changed.insert(dev::eth::PendingChangedFilter);
d.logs = logs;
//noteChanged(changed);
}
WriteGuard l(x_executions);
m_executions.emplace_back(std::move(d));
@ -308,7 +270,6 @@ void MixClient::mine()
m_state.sync(bc());
m_startState = m_state;
h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter };
//noteChanged(changed);
}
ExecutionResult MixClient::lastExecution() const
@ -395,20 +356,6 @@ dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, b
return lastExecution().result;
}
/*void MixClient::noteChanged(h256Set const& _filters)
{
for (auto& i: m_watches)
if (_filters.count(i.second.id))
{
if (m_filters.count(i.second.id))
i.second.changes += m_filters.at(i.second.id).changes;
else
i.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, 0));
}
for (auto& i: m_filters)
i.second.changes.clear();
}*/
eth::BlockInfo MixClient::blockInfo() const
{
ReadGuard l(x_state);

5
mix/MixClient.h

@ -77,8 +77,6 @@ public:
using Interface::blockInfo; // to remove warning about hiding virtual function
eth::BlockInfo blockInfo() const;
dev::eth::LocalisedLogEntries logs();
protected:
/// ClientBase methods
using ClientBase::asOf;
@ -91,10 +89,9 @@ protected:
private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto, dev::Secret const& _secret = dev::Secret());
//void noteChanged(h256Set const& _filters);
dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::u256 const& _gas, dev::Secret const& _secret = dev::Secret());
eth::State m_state;
eth::State m_state;
eth::State m_startState;
OverlayDB m_stateDB;
std::unique_ptr<MixBlockChain> m_bc;

2
mix/QContractDefinition.cpp

@ -53,7 +53,7 @@ QContractDefinition::QContractDefinition(QObject* _parent, dev::solidity::Contra
}
for (auto const& it: _contract->getEvents())
for (auto const& it: _contract->getEvents())
m_events.append(new QFunctionDefinition(parent, it));
}

4
mix/main.cpp

@ -32,9 +32,9 @@ int main(int _argc, char* _argv[])
{
try
{
MixApplication::initialize();
MixApplication::initialize();
MixApplication app(_argc, _argv);
return app.exec();
return app.exec();
}
catch (boost::exception const& _e)
{

10
mix/qml/Application.qml

@ -205,14 +205,14 @@ ApplicationWindow {
enabled: codeModel.hasContract && !clientModel.running
}
Action {
Action {
id: toggleAssemblyDebuggingAction
text: qsTr("Show VM Code")
shortcut: "Ctrl+Alt+V"
onTriggered: mainContent.debuggerPanel.assemblyMode = !mainContent.debuggerPanel.assemblyMode;
checked: mainContent.debuggerPanel.assemblyMode;
onTriggered: mainContent.debuggerPanel.assemblyMode = !mainContent.debuggerPanel.assemblyMode;
checked: mainContent.debuggerPanel.assemblyMode;
enabled: true
}
}
Action {
id: toggleWebPreviewAction
@ -221,7 +221,7 @@ ApplicationWindow {
checkable: true
checked: mainContent.webViewVisible
onTriggered: mainContent.toggleWebPreview();
}
}
Action {
id: toggleProjectNavigatorAction

614
mix/qml/Block.qml

@ -10,337 +10,337 @@ import "."
ColumnLayout
{
id: root
property variant transactions
property string status
property int number
property int blockWidth: Layout.preferredWidth - statusWidth - horizontalMargin
property int horizontalMargin: 10
property int trHeight: 30
spacing: 0
property int openedTr: 0
property int blockIndex
property variant scenario
id: root
property variant transactions
property string status
property int number
property int blockWidth: Layout.preferredWidth - statusWidth - horizontalMargin
property int horizontalMargin: 10
property int trHeight: 30
spacing: 0
property int openedTr: 0
property int blockIndex
property variant scenario
function calculateHeight()
{
if (transactions)
{
if (index >= 0)
return 30 + 30 * transactions.count + openedTr
else
return 30
}
else
return 30
}
function calculateHeight()
{
if (transactions)
{
if (index >= 0)
return 30 + 30 * transactions.count + openedTr
else
return 30
}
else
return 30
}
onOpenedTrChanged:
{
Layout.preferredHeight = calculateHeight()
height = calculateHeight()
}
onOpenedTrChanged:
{
Layout.preferredHeight = calculateHeight()
height = calculateHeight()
}
RowLayout
{
Layout.preferredHeight: trHeight
Layout.preferredWidth: blockWidth
id: rowHeader
Rectangle
{
color: "#DEDCDC"
Layout.preferredWidth: blockWidth
Layout.preferredHeight: trHeight
radius: 4
anchors.left: parent.left
anchors.leftMargin: statusWidth + 5
Label {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
text:
{
if (status === "mined")
return qsTr("BLOCK") + " " + number
else
return qsTr("BLOCK") + " pending"
}
}
}
}
RowLayout
{
Layout.preferredHeight: trHeight
Layout.preferredWidth: blockWidth
id: rowHeader
Rectangle
{
color: "#DEDCDC"
Layout.preferredWidth: blockWidth
Layout.preferredHeight: trHeight
radius: 4
anchors.left: parent.left
anchors.leftMargin: statusWidth + 5
Label {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
text:
{
if (status === "mined")
return qsTr("BLOCK") + " " + number
else
return qsTr("BLOCK") + " pending"
}
}
}
}
Repeater // List of transactions
{
id: transactionRepeater
model: transactions
Repeater // List of transactions
{
id: transactionRepeater
model: transactions
RowLayout
{
id: rowTransaction
Layout.preferredHeight: trHeight
function displayContent()
{
logsText.text = ""
if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
{
for (var k = 0; k < transactions.get(index).logs.count; k++)
{
var log = transactions.get(index).logs.get(k)
if (log.name)
logsText.text += log.name + ":\n"
else
logsText.text += "log:\n"
RowLayout
{
id: rowTransaction
Layout.preferredHeight: trHeight
function displayContent()
{
logsText.text = ""
if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
{
for (var k = 0; k < transactions.get(index).logs.count; k++)
{
var log = transactions.get(index).logs.get(k)
if (log.name)
logsText.text += log.name + ":\n"
else
logsText.text += "log:\n"
if (log.param)
for (var i = 0; i < log.param.count; i++)
{
var p = log.param.get(i)
logsText.text += p.name + " = " + p.value + " - indexed:" + p.indexed + "\n"
}
else{
logsText.text += "From : " + log.address + "\n"
}
}
logsText.text += "\n\n"
}
rowDetailedContent.visible = !rowDetailedContent.visible
}
if (log.param)
for (var i = 0; i < log.param.count; i++)
{
var p = log.param.get(i)
logsText.text += p.name + " = " + p.value + " - indexed:" + p.indexed + "\n"
}
else{
logsText.text += "From : " + log.address + "\n"
}
}
logsText.text += "\n\n"
}
rowDetailedContent.visible = !rowDetailedContent.visible
}
Rectangle
{
id: trSaveStatus
Layout.preferredWidth: statusWidth
Layout.preferredHeight: trHeight
color: "transparent"
anchors.top: parent.top
property bool saveStatus
Rectangle
{
id: trSaveStatus
Layout.preferredWidth: statusWidth
Layout.preferredHeight: trHeight
color: "transparent"
anchors.top: parent.top
property bool saveStatus
Image {
id: saveStatusImage
source: "qrc:/qml/img/recyclediscard@2x.png"
width: statusWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Image {
id: saveStatusImage
source: "qrc:/qml/img/recyclediscard@2x.png"
width: statusWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Component.onCompleted:
{
if (index >= 0)
saveStatus = transactions.get(index).saveStatus
}
Component.onCompleted:
{
if (index >= 0)
saveStatus = transactions.get(index).saveStatus
}
onSaveStatusChanged:
{
if (saveStatus)
saveStatusImage.source = "qrc:/qml/img/recyclekeep@2x.png"
else
saveStatusImage.source = "qrc:/qml/img/recyclediscard@2x.png"
onSaveStatusChanged:
{
if (saveStatus)
saveStatusImage.source = "qrc:/qml/img/recyclekeep@2x.png"
else
saveStatusImage.source = "qrc:/qml/img/recyclediscard@2x.png"
if (index >= 0)
transactions.get(index).saveStatus = saveStatus
}
if (index >= 0)
transactions.get(index).saveStatus = saveStatus
}
MouseArea {
id: statusMouseArea
anchors.fill: parent
onClicked:
{
parent.saveStatus = !parent.saveStatus
}
}
}
MouseArea {
id: statusMouseArea
anchors.fill: parent
onClicked:
{
parent.saveStatus = !parent.saveStatus
}
}
}
Rectangle
{
Layout.preferredWidth: blockWidth
Layout.preferredHeight: parent.height
color: "#DEDCDC"
id: rowContentTr
anchors.top: parent.top
ColumnLayout
{
anchors.top: parent.top
spacing: 10
RowLayout
{
anchors.top: parent.top
anchors.verticalCenter: parent.verticalCenter
spacing: cellSpacing
Text
{
id: hash
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
Layout.preferredWidth: fromWidth
elide: Text.ElideRight
maximumLineCount: 1
text: {
if (index >= 0)
return transactions.get(index).sender
else
return ""
}
}
Rectangle
{
Layout.preferredWidth: blockWidth
Layout.preferredHeight: parent.height
color: "#DEDCDC"
id: rowContentTr
anchors.top: parent.top
ColumnLayout
{
anchors.top: parent.top
spacing: 10
RowLayout
{
anchors.top: parent.top
anchors.verticalCenter: parent.verticalCenter
spacing: cellSpacing
Text
{
id: hash
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
Layout.preferredWidth: fromWidth
elide: Text.ElideRight
maximumLineCount: 1
text: {
if (index >= 0)
return transactions.get(index).sender
else
return ""
}
}
Text
{
id: func
text: {
if (index >= 0)
parent.userFrienldyToken(transactions.get(index).label)
else
return ""
}
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: toWidth
}
Text
{
id: func
text: {
if (index >= 0)
parent.userFrienldyToken(transactions.get(index).label)
else
return ""
}
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: toWidth
}
function userFrienldyToken(value)
{
if (value && value.indexOf("<") === 0)
{
if (value.split("> ")[1] === " - ")
return value.split(" - ")[0].replace("<", "")
else
return value.split(" - ")[0].replace("<", "") + "." + value.split("> ")[1] + "()";
}
else
return value
}
function userFrienldyToken(value)
{
if (value && value.indexOf("<") === 0)
{
if (value.split("> ")[1] === " - ")
return value.split(" - ")[0].replace("<", "")
else
return value.split(" - ")[0].replace("<", "") + "." + value.split("> ")[1] + "()";
}
else
return value
}
Text
{
id: returnValue
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: valueWidth
text: {
if (index >= 0 && transactions.get(index).returned)
return transactions.get(index).returned
else
return ""
}
}
Text
{
id: returnValue
elide: Text.ElideRight
maximumLineCount: 1
Layout.preferredWidth: valueWidth
text: {
if (index >= 0 && transactions.get(index).returned)
return transactions.get(index).returned
else
return ""
}
}
Rectangle
{
Layout.preferredWidth: logsWidth
Layout.preferredHeight: trHeight - 10
width: logsWidth
color: "transparent"
Text
{
id: logs
anchors.left: parent.left
anchors.leftMargin: 10
text: {
if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
return transactions.get(index).logs.count
else
return ""
}
}
MouseArea {
anchors.fill: parent
onClicked: {
rowTransaction.displayContent();
}
}
}
Rectangle
{
Layout.preferredWidth: logsWidth
Layout.preferredHeight: trHeight - 10
width: logsWidth
color: "transparent"
Text
{
id: logs
anchors.left: parent.left
anchors.leftMargin: 10
text: {
if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count)
return transactions.get(index).logs.count
else
return ""
}
}
MouseArea {
anchors.fill: parent
onClicked: {
rowTransaction.displayContent();
}
}
}
Rectangle
{
Layout.preferredWidth: debugActionWidth
Layout.preferredHeight: trHeight - 10
color: "transparent"
Rectangle
{
Layout.preferredWidth: debugActionWidth
Layout.preferredHeight: trHeight - 10
color: "transparent"
Image {
source: "qrc:/qml/img/edit.png"
width: 18
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea
{
anchors.fill: parent
onClicked:
{
transactionDialog.stateAccounts = scenario.accounts
transactionDialog.execute = false
transactionDialog.open(index, blockIndex, transactions.get(index))
}
}
}
Image {
source: "qrc:/qml/img/edit.png"
width: 18
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
MouseArea
{
anchors.fill: parent
onClicked:
{
transactionDialog.stateAccounts = scenario.accounts
transactionDialog.execute = false
transactionDialog.open(index, blockIndex, transactions.get(index))
}
}
}
Rectangle
{
Layout.preferredWidth: debugActionWidth
Layout.preferredHeight: trHeight - 10
color: "transparent"
Rectangle
{
Layout.preferredWidth: debugActionWidth
Layout.preferredHeight: trHeight - 10
color: "transparent"
Image {
id: debugImg
source: "qrc:/qml/img/rightarrow@2x.png"
width: statusWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
visible: transactions.get(index).recordIndex !== undefined
}
MouseArea
{
anchors.fill: parent
onClicked:
{
if (transactions.get(index).recordIndex !== undefined)
{
debugTrRequested = [ blockIndex, index ]
clientModel.debugRecord(transactions.get(index).recordIndex);
}
}
}
}
}
Image {
id: debugImg
source: "qrc:/qml/img/rightarrow@2x.png"
width: statusWidth
fillMode: Image.PreserveAspectFit
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
visible: transactions.get(index).recordIndex !== undefined
}
MouseArea
{
anchors.fill: parent
onClicked:
{
if (transactions.get(index).recordIndex !== undefined)
{
debugTrRequested = [ blockIndex, index ]
clientModel.debugRecord(transactions.get(index).recordIndex);
}
}
}
}
}
RowLayout
{
id: rowDetailedContent
visible: false
Layout.preferredHeight:{
if (index >= 0 && transactions.get(index).logs)
return 100 * transactions.get(index).logs.count
else
return 100
}
onVisibleChanged:
{
var lognb = transactions.get(index).logs.count
if (visible)
{
rowContentTr.Layout.preferredHeight = trHeight + 100 * lognb
openedTr += 100 * lognb
}
else
{
rowContentTr.Layout.preferredHeight = trHeight
openedTr -= 100 * lognb
}
}
RowLayout
{
id: rowDetailedContent
visible: false
Layout.preferredHeight:{
if (index >= 0 && transactions.get(index).logs)
return 100 * transactions.get(index).logs.count
else
return 100
}
onVisibleChanged:
{
var lognb = transactions.get(index).logs.count
if (visible)
{
rowContentTr.Layout.preferredHeight = trHeight + 100 * lognb
openedTr += 100 * lognb
}
else
{
rowContentTr.Layout.preferredHeight = trHeight
openedTr -= 100 * lognb
}
}
Text {
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
id: logsText
}
}
}
}
}
}
Text {
anchors.left: parent.left
anchors.leftMargin: horizontalMargin
id: logsText
}
}
}
}
}
}
}

931
mix/qml/BlockChain.qml

@ -12,474 +12,469 @@ import "js/QEtherHelper.js" as QEtherHelper
import "."
ColumnLayout {
id: blockChainPanel
property variant model
spacing: 0
property int previousWidth
property variant debugTrRequested: []
signal chainChanged
onChainChanged: {
reBuildNeeded.start()
}
onWidthChanged:
{
if (width <= 630 || previousWidth <= 630)
{
fromWidth = 100
toWidth = 100
valueWidth = 200
}
else
{
var diff = (width - previousWidth) / 3;
fromWidth = fromWidth + diff < 100 ? 100 : fromWidth + diff
toWidth = toWidth + diff < 100 ? 100 : toWidth + diff
valueWidth = valueWidth + diff < 200 ? 200 : valueWidth + diff
}
previousWidth = width
}
function load(scenario)
{
if (!scenario)
return;
if (model)
chainChanged()
model = scenario
blockModel.clear()
for (var b in model.blocks)
blockModel.append(model.blocks[b])
previousWidth = width
}
property int statusWidth: 30
property int fromWidth: 100
property int toWidth: 100
property int valueWidth: 200
property int logsWidth: 50
property int debugActionWidth: 50
property int horizontalMargin: 10
property int cellSpacing: 10
RowLayout
{
id: header
spacing: 0
Layout.preferredHeight: 25
Image {
id: debugImage
source: "qrc:/qml/img/recycleicon@2x.png"
Layout.preferredWidth: statusWidth
Layout.preferredHeight: 25
fillMode: Image.PreserveAspectFit
}
Rectangle
{
Layout.preferredWidth: fromWidth + cellSpacing
Label
{
anchors.verticalCenter: parent.verticalCenter
text: "From"
anchors.left: parent.left
anchors.leftMargin: horizontalMargin + 5
}
}
Label
{
text: "To"
Layout.preferredWidth: toWidth + cellSpacing
}
Label
{
text: "Value"
Layout.preferredWidth: valueWidth + cellSpacing
}
Label
{
text: "Logs"
Layout.preferredWidth: logsWidth + cellSpacing
}
Label
{
text: ""
Layout.preferredWidth: debugActionWidth
}
}
Rectangle
{
Layout.preferredHeight: 500
Layout.preferredWidth: parent.width
border.color: "#cccccc"
border.width: 2
color: "white"
ScrollView
{
id: blockChainScrollView
anchors.fill: parent
anchors.topMargin: 10
ColumnLayout
{
id: blockChainLayout
width: parent.width
spacing: 10
Repeater // List of blocks
{
id: blockChainRepeater
model: blockModel
Block
{
scenario: blockChainPanel.model
Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight:
{
return calculateHeight()
}
blockIndex: index
transactions:
{
if (index >= 0)
return blockModel.get(index).transactions
else
return []
}
status:
{
if (index >= 0)
return blockModel.get(index).status
else
return ""
}
number:
{
if (index >= 0)
return blockModel.get(index).number
else
return 0
}
}
}
}
}
}
ListModel
{
id: blockModel
function appendBlock(block)
{
blockModel.append(block);
}
function appendTransaction(tr)
{
blockModel.get(blockModel.count - 1).transactions.append(tr)
}
function removeTransaction(blockIndex, trIndex)
{
blockModel.get(blockIndex).transactions.remove(trIndex)
}
function removeLastBlock()
{
blockModel.remove(blockModel.count - 1)
}
function removeBlock(index)
{
blockModel.remove(index)
}
function getTransaction(block, tr)
{
return blockModel.get(block).transactions.get(tr)
}
function setTransaction(blockIndex, trIndex, tr)
{
blockModel.get(blockIndex).transactions.set(trIndex, tr)
}
function setTransactionProperty(blockIndex, trIndex, propertyName, value)
{
blockModel.get(blockIndex).transactions.set(trIndex, { propertyName: value })
}
}
Rectangle
{
Layout.preferredWidth: parent.width
RowLayout
{
width: 4 * 100
anchors.top: parent.top
anchors.topMargin: 10
spacing: 0
ScenarioButton {
id: rebuild
text: qsTr("Rebuild")
onClicked:
{
if (ensureNotFuturetime.running)
return;
reBuildNeeded.stop()
var retBlocks = [];
var bAdded = 0;
for (var j = 0; j < model.blocks.length; j++)
{
var b = model.blocks[j];
var block = {
hash: b.hash,
number: b.number,
transactions: [],
status: b.status
}
for (var k = 0; k < model.blocks[j].transactions.length; k++)
{
if (blockModel.get(j).transactions.get(k).saveStatus)
{
var tr = model.blocks[j].transactions[k]
tr.saveStatus = true
block.transactions.push(tr);
}
}
if (block.transactions.length > 0)
{
bAdded++
block.number = bAdded
block.status = "mined"
retBlocks.push(block)
}
}
if (retBlocks.length === 0)
retBlocks.push(projectModel.stateListModel.createEmptyBlock())
else
{
var last = retBlocks[retBlocks.length - 1]
last.number = -1
last.status = "pending"
}
model.blocks = retBlocks
blockModel.clear()
for (var j = 0; j < model.blocks.length; j++)
blockModel.append(model.blocks[j])
ensureNotFuturetime.start()
clientModel.setupScenario(model);
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycleicon@2x.png"
Timer
{
id: reBuildNeeded
repeat: true
interval: 1000
running: false
onTriggered: {
if (!parent.fillColor || parent.fillColor === "white")
parent.fillColor = "orange"
else
parent.fillColor = "white"
}
onRunningChanged: {
if (!running)
parent.fillColor = "white"
}
}
}
ScenarioButton {
id: addTransaction
text: qsTr("Add Transaction")
onClicked:
{
var lastBlock = model.blocks[model.blocks.length - 1];
console.log(lastBlock.status + "!!!")
if (lastBlock.status === "mined")
{
var newblock = projectModel.stateListModel.createEmptyBlock()
blockModel.appendBlock(newblock)
model.blocks.push(newblock);
}
var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = model.accounts
transactionDialog.execute = true
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item)
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png"
}
Timer
{
id: ensureNotFuturetime
interval: 1000
repeat: false
running: false
}
ScenarioButton {
id: addBlockBtn
text: qsTr("Add Block")
onClicked:
{
if (ensureNotFuturetime.running)
return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
{
var lastBlock = model.blocks[model.blocks.length - 1]
if (lastBlock.status === "pending")
{
ensureNotFuturetime.start()
clientModel.mine()
}
else
addNewBlock()
}
else
addNewBlock()
}
function addNewBlock()
{
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/addblock@2x.png"
}
Connections
{
target: clientModel
onNewBlock:
{
console.log("new Block!!")
if (!clientModel.running)
{
var lastBlock = model.blocks[model.blocks.length - 1]
lastBlock.status = "mined"
lastBlock.number = model.blocks.length
var lastB = blockModel.get(model.blocks.length - 1)
lastB.status = "mined"
lastB.number = model.blocks.length
addBlockBtn.addNewBlock()
}
}
onStateCleared:
{
}
onNewRecord:
{
var blockIndex = parseInt(_r.transactionIndex.split(":")[0]) - 1
var trIndex = parseInt(_r.transactionIndex.split(":")[1])
if (blockIndex <= model.blocks.length - 1)
{
var item = model.blocks[blockIndex]
if (trIndex <= item.transactions.length - 1)
{
var tr = item.transactions[trIndex]
tr.returned = _r.returned
tr.recordIndex = _r.recordIndex
tr.logs = _r.logs
tr.sender = _r.sender
var trModel = blockModel.getTransaction(blockIndex, trIndex)
trModel.returned = _r.returned
trModel.recordIndex = _r.recordIndex
trModel.logs = _r.logs
trModel.sender = _r.sender
blockModel.setTransaction(blockIndex, trIndex, trModel)
return;
}
}
// tr is not in the list.
var itemTr = TransactionHelper.defaultTransaction()
itemTr.saveStatus = false
itemTr.functionId = _r.function
itemTr.contractId = _r.contract
itemTr.gasAuto = true
itemTr.parameters = _r.parameters
itemTr.isContractCreation = itemTr.functionId === itemTr.contractId
itemTr.label = _r.label
itemTr.isFunctionCall = itemTr.functionId !== ""
itemTr.returned = _r.returned
itemTr.value = QEtherHelper.createEther(_r.value, QEther.Wei)
itemTr.sender = _r.sender
itemTr.recordIndex = _r.recordIndex
itemTr.logs = _r.logs
console.log(JSON.stringify(itemTr))
model.blocks[model.blocks.length - 1].transactions.push(itemTr)
blockModel.appendTransaction(itemTr)
}
onMiningComplete:
{
}
}
ScenarioButton {
id: newAccount
text: qsTr("New Account")
onClicked: {
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether))
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/newaccounticon@2x.png"
}
}
}
TransactionDialog {
id: transactionDialog
property bool execute
onAccepted: {
var item = transactionDialog.getItem()
if (execute)
{
console.log("cc " + model.blocks.length)
var lastBlock = model.blocks[model.blocks.length - 1];
console.log("mined?" + lastBlock.status)
if (lastBlock.status === "mined")
{
var newBlock = projectModel.stateListModel.createEmptyBlock();
model.blocks.push(newBlock);
blockModel.appendBlock(newBlock)
}
if (!clientModel.running)
clientModel.executeTr(item)
}
else {
model.blocks[blockIndex].transactions[transactionIndex] = item
blockModel.setTransaction(blockIndex, transactionIndex, item)
chainChanged()
}
}
}
id: blockChainPanel
property variant model
spacing: 0
property int previousWidth
property variant debugTrRequested: []
signal chainChanged
onChainChanged: {
reBuildNeeded.start()
}
onWidthChanged:
{
if (width <= 630 || previousWidth <= 630)
{
fromWidth = 100
toWidth = 100
valueWidth = 200
}
else
{
var diff = (width - previousWidth) / 3;
fromWidth = fromWidth + diff < 100 ? 100 : fromWidth + diff
toWidth = toWidth + diff < 100 ? 100 : toWidth + diff
valueWidth = valueWidth + diff < 200 ? 200 : valueWidth + diff
}
previousWidth = width
}
function load(scenario)
{
if (!scenario)
return;
if (model)
chainChanged()
model = scenario
blockModel.clear()
for (var b in model.blocks)
blockModel.append(model.blocks[b])
previousWidth = width
}
property int statusWidth: 30
property int fromWidth: 100
property int toWidth: 100
property int valueWidth: 200
property int logsWidth: 50
property int debugActionWidth: 50
property int horizontalMargin: 10
property int cellSpacing: 10
RowLayout
{
id: header
spacing: 0
Layout.preferredHeight: 25
Image {
id: debugImage
source: "qrc:/qml/img/recycleicon@2x.png"
Layout.preferredWidth: statusWidth
Layout.preferredHeight: 25
fillMode: Image.PreserveAspectFit
}
Rectangle
{
Layout.preferredWidth: fromWidth + cellSpacing
Label
{
anchors.verticalCenter: parent.verticalCenter
text: "From"
anchors.left: parent.left
anchors.leftMargin: horizontalMargin + 5
}
}
Label
{
text: "To"
Layout.preferredWidth: toWidth + cellSpacing
}
Label
{
text: "Value"
Layout.preferredWidth: valueWidth + cellSpacing
}
Label
{
text: "Logs"
Layout.preferredWidth: logsWidth + cellSpacing
}
Label
{
text: ""
Layout.preferredWidth: debugActionWidth
}
}
Rectangle
{
Layout.preferredHeight: 500
Layout.preferredWidth: parent.width
border.color: "#cccccc"
border.width: 2
color: "white"
ScrollView
{
id: blockChainScrollView
anchors.fill: parent
anchors.topMargin: 10
ColumnLayout
{
id: blockChainLayout
width: parent.width
spacing: 10
Repeater // List of blocks
{
id: blockChainRepeater
model: blockModel
Block
{
scenario: blockChainPanel.model
Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight:
{
return calculateHeight()
}
blockIndex: index
transactions:
{
if (index >= 0)
return blockModel.get(index).transactions
else
return []
}
status:
{
if (index >= 0)
return blockModel.get(index).status
else
return ""
}
number:
{
if (index >= 0)
return blockModel.get(index).number
else
return 0
}
}
}
}
}
}
ListModel
{
id: blockModel
function appendBlock(block)
{
blockModel.append(block);
}
function appendTransaction(tr)
{
blockModel.get(blockModel.count - 1).transactions.append(tr)
}
function removeTransaction(blockIndex, trIndex)
{
blockModel.get(blockIndex).transactions.remove(trIndex)
}
function removeLastBlock()
{
blockModel.remove(blockModel.count - 1)
}
function removeBlock(index)
{
blockModel.remove(index)
}
function getTransaction(block, tr)
{
return blockModel.get(block).transactions.get(tr)
}
function setTransaction(blockIndex, trIndex, tr)
{
blockModel.get(blockIndex).transactions.set(trIndex, tr)
}
function setTransactionProperty(blockIndex, trIndex, propertyName, value)
{
blockModel.get(blockIndex).transactions.set(trIndex, { propertyName: value })
}
}
Rectangle
{
Layout.preferredWidth: parent.width
RowLayout
{
width: 4 * 100
anchors.top: parent.top
anchors.topMargin: 10
spacing: 0
ScenarioButton {
id: rebuild
text: qsTr("Rebuild")
onClicked:
{
if (ensureNotFuturetime.running)
return;
reBuildNeeded.stop()
var retBlocks = [];
var bAdded = 0;
for (var j = 0; j < model.blocks.length; j++)
{
var b = model.blocks[j];
var block = {
hash: b.hash,
number: b.number,
transactions: [],
status: b.status
}
for (var k = 0; k < model.blocks[j].transactions.length; k++)
{
if (blockModel.get(j).transactions.get(k).saveStatus)
{
var tr = model.blocks[j].transactions[k]
tr.saveStatus = true
block.transactions.push(tr);
}
}
if (block.transactions.length > 0)
{
bAdded++
block.number = bAdded
block.status = "mined"
retBlocks.push(block)
}
}
if (retBlocks.length === 0)
retBlocks.push(projectModel.stateListModel.createEmptyBlock())
else
{
var last = retBlocks[retBlocks.length - 1]
last.number = -1
last.status = "pending"
}
model.blocks = retBlocks
blockModel.clear()
for (var j = 0; j < model.blocks.length; j++)
blockModel.append(model.blocks[j])
ensureNotFuturetime.start()
clientModel.setupScenario(model);
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/recycleicon@2x.png"
Timer
{
id: reBuildNeeded
repeat: true
interval: 1000
running: false
onTriggered: {
if (!parent.fillColor || parent.fillColor === "white")
parent.fillColor = "orange"
else
parent.fillColor = "white"
}
onRunningChanged: {
if (!running)
parent.fillColor = "white"
}
}
}
ScenarioButton {
id: addTransaction
text: qsTr("Add Transaction")
onClicked:
{
var lastBlock = model.blocks[model.blocks.length - 1];
if (lastBlock.status === "mined")
{
var newblock = projectModel.stateListModel.createEmptyBlock()
blockModel.appendBlock(newblock)
model.blocks.push(newblock);
}
var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = model.accounts
transactionDialog.execute = true
transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item)
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/sendtransactionicon@2x.png"
}
Timer
{
id: ensureNotFuturetime
interval: 1000
repeat: false
running: false
}
ScenarioButton {
id: addBlockBtn
text: qsTr("Add Block")
onClicked:
{
if (ensureNotFuturetime.running)
return
if (clientModel.mining || clientModel.running)
return
if (model.blocks.length > 0)
{
var lastBlock = model.blocks[model.blocks.length - 1]
if (lastBlock.status === "pending")
{
ensureNotFuturetime.start()
clientModel.mine()
}
else
addNewBlock()
}
else
addNewBlock()
}
function addNewBlock()
{
var block = projectModel.stateListModel.createEmptyBlock()
model.blocks.push(block)
blockModel.appendBlock(block)
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/addblock@2x.png"
}
Connections
{
target: clientModel
onNewBlock:
{
if (!clientModel.running)
{
var lastBlock = model.blocks[model.blocks.length - 1]
lastBlock.status = "mined"
lastBlock.number = model.blocks.length
var lastB = blockModel.get(model.blocks.length - 1)
lastB.status = "mined"
lastB.number = model.blocks.length
addBlockBtn.addNewBlock()
}
}
onStateCleared:
{
}
onNewRecord:
{
var blockIndex = parseInt(_r.transactionIndex.split(":")[0]) - 1
var trIndex = parseInt(_r.transactionIndex.split(":")[1])
if (blockIndex <= model.blocks.length - 1)
{
var item = model.blocks[blockIndex]
if (trIndex <= item.transactions.length - 1)
{
var tr = item.transactions[trIndex]
tr.returned = _r.returned
tr.recordIndex = _r.recordIndex
tr.logs = _r.logs
tr.sender = _r.sender
var trModel = blockModel.getTransaction(blockIndex, trIndex)
trModel.returned = _r.returned
trModel.recordIndex = _r.recordIndex
trModel.logs = _r.logs
trModel.sender = _r.sender
blockModel.setTransaction(blockIndex, trIndex, trModel)
return;
}
}
// tr is not in the list.
var itemTr = TransactionHelper.defaultTransaction()
itemTr.saveStatus = false
itemTr.functionId = _r.function
itemTr.contractId = _r.contract
itemTr.gasAuto = true
itemTr.parameters = _r.parameters
itemTr.isContractCreation = itemTr.functionId === itemTr.contractId
itemTr.label = _r.label
itemTr.isFunctionCall = itemTr.functionId !== ""
itemTr.returned = _r.returned
itemTr.value = QEtherHelper.createEther(_r.value, QEther.Wei)
itemTr.sender = _r.sender
itemTr.recordIndex = _r.recordIndex
itemTr.logs = _r.logs
model.blocks[model.blocks.length - 1].transactions.push(itemTr)
blockModel.appendTransaction(itemTr)
}
onMiningComplete:
{
}
}
ScenarioButton {
id: newAccount
text: qsTr("New Account")
onClicked: {
model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether))
}
Layout.preferredWidth: 100
Layout.preferredHeight: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/newaccounticon@2x.png"
}
}
}
TransactionDialog {
id: transactionDialog
property bool execute
onAccepted: {
var item = transactionDialog.getItem()
if (execute)
{
var lastBlock = model.blocks[model.blocks.length - 1];
if (lastBlock.status === "mined")
{
var newBlock = projectModel.stateListModel.createEmptyBlock();
model.blocks.push(newBlock);
blockModel.appendBlock(newBlock)
}
if (!clientModel.running)
clientModel.executeTr(item)
}
else {
model.blocks[blockIndex].transactions[transactionIndex] = item
blockModel.setTransaction(blockIndex, transactionIndex, item)
chainChanged()
}
}
}
}

144
mix/qml/Debugger.qml

@ -11,7 +11,7 @@ import "."
Rectangle {
id: debugPanel
property alias debugSlider: statesSlider
property alias debugSlider: statesSlider
property alias solLocals: solLocals
property alias solStorage: solStorage
property alias solCallStack: solCallStack
@ -22,7 +22,7 @@ Rectangle {
signal debugExecuteLocation(string documentId, var location)
property string compilationErrorMessage
property bool assemblyMode: false
signal panelClosed
signal panelClosed
objectName: "debugPanel"
color: "#ededed"
clip: true
@ -39,10 +39,10 @@ Rectangle {
machineStates.updateHeight();
}
function setTr(tr)
{
trName.text = tr.label
}
function setTr(tr)
{
trName.text = tr.label
}
function displayCompilationErrorIfAny()
{
@ -109,68 +109,68 @@ Rectangle {
property alias solLocalsHeightSettings: solLocalsRect.height
}
ColumnLayout {
ColumnLayout {
id: debugScrollArea
anchors.fill: parent
//orientation: Qt.Vertical
spacing: 0
RowLayout
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: 30
Rectangle
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height
color: "transparent"
Text {
anchors.centerIn: parent
text: qsTr("Current Transaction")
}
Rectangle
{
anchors.left: parent.left
anchors.leftMargin: 10
width: 30
height: parent.height
color: "transparent"
anchors.verticalCenter: parent.verticalCenter
Image {
source: "qrc:/qml/img/leftarrow@2x.png"
width: parent.width
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
}
MouseArea
{
anchors.fill: parent
onClicked:
{
Debugger.init(null);
panelClosed()
}
}
}
}
}
RowLayout
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: 30
Rectangle
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height
color: "#2C79D3"
Text {
id: trName
color: "white"
anchors.centerIn: parent
}
}
}
//orientation: Qt.Vertical
spacing: 0
RowLayout
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: 30
Rectangle
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height
color: "transparent"
Text {
anchors.centerIn: parent
text: qsTr("Current Transaction")
}
Rectangle
{
anchors.left: parent.left
anchors.leftMargin: 10
width: 30
height: parent.height
color: "transparent"
anchors.verticalCenter: parent.verticalCenter
Image {
source: "qrc:/qml/img/leftarrow@2x.png"
width: parent.width
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
}
MouseArea
{
anchors.fill: parent
onClicked:
{
Debugger.init(null);
panelClosed()
}
}
}
}
}
RowLayout
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: 30
Rectangle
{
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height
color: "#2C79D3"
Text {
id: trName
color: "white"
anchors.centerIn: parent
}
}
}
ScrollView
{
@ -520,12 +520,12 @@ Rectangle {
}
Rectangle {
id: separator
width: parent.width;
height: 1;
color: "#cccccc"
anchors.bottom: parent.bottom
}
id: separator
width: parent.width;
height: 1;
color: "#cccccc"
anchors.bottom: parent.bottom
}
}
}
}

108
mix/qml/MainContent.qml

@ -20,14 +20,14 @@ Rectangle {
anchors.fill: parent
id: root
property alias rightViewVisible: scenarioExe.visible
property alias rightViewVisible: scenarioExe.visible
property alias webViewVisible: webPreview.visible
property alias webView: webPreview
property alias projectViewVisible: projectList.visible
property alias projectNavigator: projectList
property alias runOnProjectLoad: mainSettings.runOnProjectLoad
property alias rightPane: scenarioExe
property alias debuggerPanel: debugPanel
property alias rightPane: scenarioExe
property alias debuggerPanel: debugPanel
property alias codeEditor: codeEditor
property bool webViewHorizontal: codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally
property bool firstCompile: true
@ -43,17 +43,17 @@ Rectangle {
}
}
Connections {
target: debugPanel
onDebugExecuteLocation: {
Connections {
target: debugPanel
onDebugExecuteLocation: {
codeEditor.highlightExecution(documentId, location);
}
}
}
Connections {
target: codeEditor
onBreakpointsChanged: {
debugPanel.setBreakpoints(codeEditor.getBreakpoints());
debugPanel.setBreakpoints(codeEditor.getBreakpoints());
}
}
@ -64,20 +64,20 @@ Rectangle {
}
function toggleRightView() {
scenarioExe.visible = !scenarioExe.visible;
scenarioExe.visible = !scenarioExe.visible;
}
function ensureRightView() {
scenarioExe.visible = true;
scenarioExe.visible = true;
}
function rightViewIsVisible()
{
return scenarioExe.visible;
return scenarioExe.visible;
}
function hideRightView() {
scenarioExe.visible = lfalse;
scenarioExe.visible = lfalse;
}
function toggleWebPreview() {
@ -99,8 +99,8 @@ Rectangle {
function displayCompilationErrorIfAny()
{
scenarioExe.visible = true;
scenarioExe.displayCompilationErrorIfAny();
scenarioExe.visible = true;
scenarioExe.displayCompilationErrorIfAny();
}
Settings {
@ -154,7 +154,7 @@ Rectangle {
id: splitSettings
property alias projectWidth: projectList.width
property alias contentViewWidth: contentView.width
property alias rightViewWidth: scenarioExe.width
property alias rightViewWidth: scenarioExe.width
}
Splitter
@ -199,45 +199,45 @@ Rectangle {
}
}
ScenarioExecution
{
id: scenarioExe;
visible: false;
Layout.fillHeight: true
Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650
anchors.right: parent.right
}
Debugger
{
id: debugPanel
visible: false
Layout.fillHeight: true
Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650
anchors.right: parent.right
}
Connections {
target: clientModel
onDebugDataReady: {
scenarioExe.visible = false
debugPanel.visible = true
if (scenarioExe.bc.debugTrRequested)
{
debugPanel.setTr(scenarioExe.bc.model.blocks[scenarioExe.bc.debugTrRequested[0]].transactions[scenarioExe.bc.debugTrRequested[1]])
}
}
}
Connections {
target: debugPanel
onPanelClosed: {
debugPanel.visible = false
scenarioExe.visible = true
}
}
ScenarioExecution
{
id: scenarioExe;
visible: false;
Layout.fillHeight: true
Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650
anchors.right: parent.right
}
Debugger
{
id: debugPanel
visible: false
Layout.fillHeight: true
Keys.onEscapePressed: visible = false
Layout.minimumWidth: 650
anchors.right: parent.right
}
Connections {
target: clientModel
onDebugDataReady: {
scenarioExe.visible = false
debugPanel.visible = true
if (scenarioExe.bc.debugTrRequested)
{
debugPanel.setTr(scenarioExe.bc.model.blocks[scenarioExe.bc.debugTrRequested[0]].transactions[scenarioExe.bc.debugTrRequested[1]])
}
}
}
Connections {
target: debugPanel
onPanelClosed: {
debugPanel.visible = false
scenarioExe.visible = true
}
}
}
}
}

3
mix/qml/QAddressView.qml

@ -39,9 +39,6 @@ Item
{
accountRef.clear();
accountRef.append({"itemid": " - "});
console.log(blockIndex)
console.log(transactionIndex)
if (subType === "contract" || subType === "address")
{
var trCr = 0;

112
mix/qml/ScenarioButton.qml

@ -4,64 +4,64 @@ import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1
Rectangle {
id: buttonActionContainer
property string text
property string buttonShortcut
property string sourceImg
property string fillColor
signal clicked
id: buttonActionContainer
property string text
property string buttonShortcut
property string sourceImg
property string fillColor
signal clicked
Rectangle {
id: contentRectangle
anchors.fill: parent
border.color: "#cccccc"
border.width: 1
radius: 4
color: parent.fillColor ? parent.fillColor : "white"
Image {
id: debugImage
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin: debugImg.pressed ? 0 : 2;
topMargin: debugImg.pressed ? 2 : 0;
}
source: sourceImg
fillMode: Image.PreserveAspectFit
height: 30
}
Rectangle {
id: contentRectangle
anchors.fill: parent
border.color: "#cccccc"
border.width: 1
radius: 4
color: parent.fillColor ? parent.fillColor : "white"
Image {
id: debugImage
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
bottomMargin: debugImg.pressed ? 0 : 2;
topMargin: debugImg.pressed ? 2 : 0;
}
source: sourceImg
fillMode: Image.PreserveAspectFit
height: 30
}
Button {
anchors.fill: parent
id: debugImg
action: buttonAction
style: ButtonStyle {
background: Rectangle {
color: "transparent"
}
}
}
Button {
anchors.fill: parent
id: debugImg
action: buttonAction
style: ButtonStyle {
background: Rectangle {
color: "transparent"
}
}
}
Action {
id: buttonAction
shortcut: buttonShortcut
onTriggered: {
buttonActionContainer.clicked();
}
}
}
Action {
id: buttonAction
shortcut: buttonShortcut
onTriggered: {
buttonActionContainer.clicked();
}
}
}
Rectangle
{
anchors.top: contentRectangle.bottom
anchors.topMargin: 15
width: parent.width
Text
{
text: buttonActionContainer.text
anchors.centerIn: parent
}
}
Rectangle
{
anchors.top: contentRectangle.bottom
anchors.topMargin: 15
width: parent.width
Text
{
text: buttonActionContainer.text
anchors.centerIn: parent
}
}
}

78
mix/qml/ScenarioExecution.qml

@ -9,49 +9,49 @@ import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "."
Rectangle {
color: "#ededed"
property alias bc: blockChain
color: "#ededed"
property alias bc: blockChain
Connections
{
target: projectModel
onProjectLoaded: {
loader.init()
}
Connections
{
target: projectModel
onProjectLoaded: {
loader.init()
}
}
}
Column
{
anchors.margins: 10
anchors.fill: parent
spacing: 10
ScenarioLoader
{
height: 70
width: parent.width
id: loader
}
Column
{
anchors.margins: 10
anchors.fill: parent
spacing: 10
ScenarioLoader
{
height: 70
width: parent.width
id: loader
}
Rectangle
{
width: parent.width
height: 1
color: "#cccccc"
}
Rectangle
{
width: parent.width
height: 1
color: "#cccccc"
}
Connections
{
target: loader
onLoaded: {
blockChain.load(scenario)
}
}
Connections
{
target: loader
onLoaded: {
blockChain.load(scenario)
}
}
BlockChain
{
id: blockChain
width: parent.width
}
}
BlockChain
{
id: blockChain
width: parent.width
}
}
}

318
mix/qml/ScenarioLoader.qml

@ -12,164 +12,164 @@ import "."
RowLayout
{
signal restored(variant scenario)
signal saved(variant scenario)
signal duplicated(variant scenario)
signal loaded(variant scenario)
spacing: 0
function init()
{
scenarioList.load()
}
id: blockChainSelector
Dialog {
id: newStateWin
modality: Qt.ApplicationModal
title: qsTr("New Project");
width: 320
height: 120
visible: false
contentItem: Rectangle {
anchors.fill: parent
anchors.margins: 10
RowLayout {
anchors.verticalCenter: parent.verticalCenter
Text {
text: qsTr("Name:")
}
Rectangle
{
Layout.preferredWidth: 250
Layout.preferredHeight: parent.height
border.width: 1
border.color: "#cccccc"
TextInput
{
anchors.fill: parent
id: stateName
}
}
}
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
function acceptAndClose()
{
var item = projectModel.stateListModel.createDefaultState();
item.title = stateName.text
projectModel.stateListModel.appendState(item)
projectModel.stateListModel.save()
close()
scenarioList.currentIndex = projectModel.stateListModel.count - 1
}
function close()
{
newStateWin.close()
stateName.text = ""
}
Button {
id: okButton;
enabled: stateName.text !== ""
text: qsTr("OK");
onClicked: {
parent.acceptAndClose();
}
}
Button {
text: qsTr("Cancel");
onClicked: parent.close();
}
}
}
}
ComboBox
{
id: scenarioList
model: projectModel.stateListModel
textRole: "title"
onCurrentIndexChanged:
{
restoreScenario.restore()
}
function load()
{
var state = projectModel.stateListModel.getState(currentIndex)
loaded(state)
}
}
Row
{
Layout.preferredWidth: 100 * 4
Layout.preferredHeight: 30
spacing: 0
ScenarioButton {
id: restoreScenario
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/restoreicon@2x.png"
onClicked: {
restore()
}
text: qsTr("Restore")
function restore()
{
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex)
restored(state)
loaded(state)
}
}
ScenarioButton {
id: saveScenario
text: qsTr("Save")
onClicked: {
projectModel.saveProjectFile()
saved(state)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/saveicon@2x.png"
}
ScenarioButton
{
id: duplicateScenario
text: qsTr("Duplicate")
onClicked: {
projectModel.stateListModel.duplicateState(scenarioList.currentIndex)
duplicated(state)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/duplicateicon@2x.png"
}
ScenarioButton {
id: addScenario
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/plus.png"
onClicked: {
newStateWin.open()
}
text: qsTr("New")
}
}
signal restored(variant scenario)
signal saved(variant scenario)
signal duplicated(variant scenario)
signal loaded(variant scenario)
spacing: 0
function init()
{
scenarioList.load()
}
id: blockChainSelector
Dialog {
id: newStateWin
modality: Qt.ApplicationModal
title: qsTr("New Project");
width: 320
height: 120
visible: false
contentItem: Rectangle {
anchors.fill: parent
anchors.margins: 10
RowLayout {
anchors.verticalCenter: parent.verticalCenter
Text {
text: qsTr("Name:")
}
Rectangle
{
Layout.preferredWidth: 250
Layout.preferredHeight: parent.height
border.width: 1
border.color: "#cccccc"
TextInput
{
anchors.fill: parent
id: stateName
}
}
}
RowLayout
{
anchors.bottom: parent.bottom
anchors.right: parent.right;
function acceptAndClose()
{
var item = projectModel.stateListModel.createDefaultState();
item.title = stateName.text
projectModel.stateListModel.appendState(item)
projectModel.stateListModel.save()
close()
scenarioList.currentIndex = projectModel.stateListModel.count - 1
}
function close()
{
newStateWin.close()
stateName.text = ""
}
Button {
id: okButton;
enabled: stateName.text !== ""
text: qsTr("OK");
onClicked: {
parent.acceptAndClose();
}
}
Button {
text: qsTr("Cancel");
onClicked: parent.close();
}
}
}
}
ComboBox
{
id: scenarioList
model: projectModel.stateListModel
textRole: "title"
onCurrentIndexChanged:
{
restoreScenario.restore()
}
function load()
{
var state = projectModel.stateListModel.getState(currentIndex)
loaded(state)
}
}
Row
{
Layout.preferredWidth: 100 * 4
Layout.preferredHeight: 30
spacing: 0
ScenarioButton {
id: restoreScenario
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/restoreicon@2x.png"
onClicked: {
restore()
}
text: qsTr("Restore")
function restore()
{
var state = projectModel.stateListModel.reloadStateFromFromProject(scenarioList.currentIndex)
restored(state)
loaded(state)
}
}
ScenarioButton {
id: saveScenario
text: qsTr("Save")
onClicked: {
projectModel.saveProjectFile()
saved(state)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/saveicon@2x.png"
}
ScenarioButton
{
id: duplicateScenario
text: qsTr("Duplicate")
onClicked: {
projectModel.stateListModel.duplicateState(scenarioList.currentIndex)
duplicated(state)
}
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/duplicateicon@2x.png"
}
ScenarioButton {
id: addScenario
width: 100
height: 30
buttonShortcut: ""
sourceImg: "qrc:/qml/img/plus.png"
onClicked: {
newStateWin.open()
}
text: qsTr("New")
}
}
}

241
mix/qml/StateListModel.qml

@ -16,32 +16,33 @@ Item {
property string defaultAccount: "cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074" //support for old project
function fromPlainStateItem(s) {
if (!s.accounts)
if (!s.accounts)
s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project
if (!s.contracts)
s.contracts = [];
var ret = {};
ret.title = s.title;
ret.transactions = s.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem); //support old projects by filtering std contracts
if (s.blocks)
ret.blocks = s.blocks.map(fromPlainBlockItem);
ret.accounts = s.accounts.map(fromPlainAccountItem);
ret.contracts = s.contracts.map(fromPlainAccountItem);
ret.miner = s.miner;
// support old projects
if (!ret.blocks)
{
ret.blocks = [{
hash: "",
number: -1,
transactions: [],
status: "pending"
}]
for (var j in ret.transactions)
ret.blocks[0].transactions.push(fromPlainTransactionItem(toPlainTransactionItem(ret.transactions[j])))
}
var ret = {};
ret.title = s.title;
ret.transactions = s.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem); //support old projects by filtering std contracts
if (s.blocks)
ret.blocks = s.blocks.map(fromPlainBlockItem);
ret.accounts = s.accounts.map(fromPlainAccountItem);
ret.contracts = s.contracts.map(fromPlainAccountItem);
ret.miner = s.miner;
// support old projects
if (!ret.blocks)
{
ret.blocks = [{
hash: "",
number: -1,
transactions: [],
status: "pending"
}]
for (var j in ret.transactions)
ret.blocks[0].transactions.push(fromPlainTransactionItem(toPlainTransactionItem(ret.transactions[j])))
}
return ret;
}
function fromPlainAccountItem(t)
@ -73,12 +74,12 @@ Item {
sender: t.sender,
isContractCreation: t.isContractCreation,
label: t.label,
isFunctionCall: t.isFunctionCall,
saveStatus: t.saveStatus
isFunctionCall: t.isFunctionCall,
saveStatus: t.saveStatus
};
if (r.saveStatus === undefined)
r.saveStatus = true
if (r.saveStatus === undefined)
r.saveStatus = true
if (r.isFunctionCall === undefined)
r.isFunctionCall = true;
@ -95,22 +96,22 @@ Item {
return r;
}
function fromPlainBlockItem(b)
{
var r = {
hash: b.hash,
number: b.number,
transactions: b.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem), //support old projects by filtering std contracts
status: b.status
}
return r;
}
function fromPlainBlockItem(b)
{
var r = {
hash: b.hash,
number: b.number,
transactions: b.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem), //support old projects by filtering std contracts
status: b.status
}
return r;
}
function toPlainStateItem(s) {
return {
title: s.title,
blocks: s.blocks.map(toPlainBlockItem),
transactions: s.transactions.map(toPlainTransactionItem),
blocks: s.blocks.map(toPlainBlockItem),
transactions: s.transactions.map(toPlainTransactionItem),
accounts: s.accounts.map(toPlainAccountItem),
contracts: s.contracts.map(toPlainAccountItem),
miner: s.miner
@ -127,16 +128,16 @@ Item {
return '';
}
function toPlainBlockItem(b)
{
var r = {
hash: b.hash,
number: b.number,
transactions: b.transactions.map(toPlainTransactionItem),
status: b.status
}
return r;
}
function toPlainBlockItem(b)
{
var r = {
hash: b.hash,
number: b.number,
transactions: b.transactions.map(toPlainTransactionItem),
status: b.status
}
return r;
}
function toPlainAccountItem(t)
{
@ -167,8 +168,8 @@ Item {
parameters: {},
isContractCreation: t.isContractCreation,
label: t.label,
isFunctionCall: t.isFunctionCall,
saveStatus: t.saveStatus
isFunctionCall: t.isFunctionCall,
saveStatus: t.saveStatus
};
for (var key in t.parameters)
r.parameters[key] = t.parameters[key];
@ -189,16 +190,16 @@ Item {
projectData.states.push(toPlainStateItem(stateList[i]));
}
projectData.defaultStateIndex = stateListModel.defaultStateIndex;
stateListModel.data = projectData
stateListModel.data = projectData
}
}
onNewProject: {
var state = toPlainStateItem(stateListModel.createDefaultState());
state.title = qsTr("Default");
projectData.states = [ state ];
projectData.defaultStateIndex = 0;
stateListModel.loadStatesFromProject(projectData);
}
stateListModel.loadStatesFromProject(projectData);
}
}
Connections {
@ -215,40 +216,40 @@ Item {
id: stateDialog
onAccepted: {
var item = stateDialog.getItem();
saveState(item);
saveState(item);
}
function saveState(item)
{
if (stateDialog.stateIndex < stateListModel.count) {
if (stateDialog.isDefault)
stateListModel.defaultStateIndex = stateIndex;
stateList[stateDialog.stateIndex] = item;
stateListModel.set(stateDialog.stateIndex, item);
} else {
if (stateDialog.isDefault)
stateListModel.defaultStateIndex = 0;
stateList.push(item);
stateListModel.append(item);
}
if (stateDialog.isDefault)
stateListModel.defaultStateChanged();
stateListModel.save();
}
function saveState(item)
{
if (stateDialog.stateIndex < stateListModel.count) {
if (stateDialog.isDefault)
stateListModel.defaultStateIndex = stateIndex;
stateList[stateDialog.stateIndex] = item;
stateListModel.set(stateDialog.stateIndex, item);
} else {
if (stateDialog.isDefault)
stateListModel.defaultStateIndex = 0;
stateList.push(item);
stateListModel.append(item);
}
if (stateDialog.isDefault)
stateListModel.defaultStateChanged();
stateListModel.save();
}
}
ListModel {
id: stateListModel
property int defaultStateIndex: 0
property variant data
signal defaultStateChanged;
property variant data
signal defaultStateChanged;
signal stateListModelReady;
signal stateRun(int index)
signal stateDeleted(int index)
function defaultTransactionItem() {
return TransactionHelper.defaultTransaction();
}
}
function newAccount(_balance, _unit, _secret)
{
@ -259,35 +260,35 @@ Item {
return { name: name, secret: _secret, balance: QEtherHelper.createEther(_balance, _unit), address: address };
}
function duplicateState(index)
{
var state = stateList[index]
var item = fromPlainStateItem(toPlainStateItem(state))
item.title = qsTr("Copy of") + " " + state.title
appendState(item)
save()
}
function createEmptyBlock()
{
return {
hash: "",
number: -1,
transactions: [],
status: "pending"
}
}
function duplicateState(index)
{
var state = stateList[index]
var item = fromPlainStateItem(toPlainStateItem(state))
item.title = qsTr("Copy of") + " " + state.title
appendState(item)
save()
}
function createEmptyBlock()
{
return {
hash: "",
number: -1,
transactions: [],
status: "pending"
}
}
function createDefaultState() {
var item = {
title: "",
transactions: [],
accounts: [],
contracts: [],
blocks: [{ status: "pending", number: -1, hash: "", transactions: []}]
};
contracts: [],
blocks: [{ status: "pending", number: -1, hash: "", transactions: []}]
};
var account = newAccount("1000000", QEther.Ether, defaultAccount)
var account = newAccount("1000000", QEther.Ether, defaultAccount)
item.accounts.push(account);
item.miner = account;
@ -299,8 +300,8 @@ Item {
ctorTr.label = qsTr("Deploy") + " " + ctorTr.contractId;
ctorTr.sender = item.accounts[0].secret;
item.transactions.push(ctorTr);
item.blocks[0].transactions.push(ctorTr)
}
item.blocks[0].transactions.push(ctorTr)
}
return item;
}
@ -356,19 +357,19 @@ Item {
stateDialog.open(stateListModel.count, item, false);
}
function appendState(item)
{
stateListModel.append(item);
stateList.push(item);
}
function appendState(item)
{
stateListModel.append(item);
stateList.push(item);
}
function editState(index) {
stateDialog.open(index, stateList[index], defaultStateIndex === index);
}
function getState(index) {
return stateList[index];
}
function getState(index) {
return stateList[index];
}
function debugDefaultState() {
if (defaultStateIndex >= 0 && defaultStateIndex < stateList.length)
@ -377,8 +378,8 @@ Item {
function runState(index) {
var item = stateList[index];
//clientModel.setupState(item);
//stateRun(index);
clientModel.setupScenario(item);
stateRun(index);
}
function deleteState(index) {
@ -404,20 +405,20 @@ Item {
return stateList[defaultStateIndex].title;
}
function reloadStateFromFromProject(index)
{
if (data)
{
var item = fromPlainStateItem(data.states[index])
stateListModel.set(index, item)
stateList[index] = item
return item
}
}
function reloadStateFromFromProject(index)
{
if (data)
{
var item = fromPlainStateItem(data.states[index])
stateListModel.set(index, item)
stateList[index] = item
return item
}
}
function loadStatesFromProject(projectData)
{
data = projectData
data = projectData
if (!projectData.states)
projectData.states = [];
if (projectData.defaultStateIndex !== undefined)

2
mix/qml/StructView.qml

@ -9,7 +9,7 @@ Column
property alias members: repeater.model //js array
property variant accounts
property var value: ({})
property int blockIndex
property int blockIndex
property int transactionIndex
property string context
Layout.fillWidth: true

20
mix/qml/TransactionDialog.qml

@ -17,7 +17,7 @@ Dialog {
visible: false
title: qsTr("Edit Transaction")
property int transactionIndex
property int blockIndex
property int blockIndex
property alias gas: gasValueEdit.gasValue;
property alias gasAuto: gasAutoCheck.checked;
property alias gasPrice: gasPriceField.value;
@ -28,24 +28,24 @@ Dialog {
property var paramsModel: [];
property bool useTransactionDefaultValue: false
property alias stateAccounts: senderComboBox.model
property bool saveStatus
property bool saveStatus
signal accepted;
StateDialogStyle {
id: transactionDialogStyle
}
function open(index, blockIdx, item) {
function open(index, blockIdx, item) {
rowFunction.visible = !useTransactionDefaultValue;
rowValue.visible = !useTransactionDefaultValue;
rowGas.visible = !useTransactionDefaultValue;
rowGasPrice.visible = !useTransactionDefaultValue;
transactionIndex = index
blockIndex = blockIdx
typeLoader.transactionIndex = index
typeLoader.blockIndex = blockIdx
saveStatus = item.saveStatus
transactionIndex = index
blockIndex = blockIdx
typeLoader.transactionIndex = index
typeLoader.blockIndex = blockIdx
saveStatus = item.saveStatus
gasValueEdit.gasValue = item.gas;
gasAutoCheck.checked = item.gasAuto ? true : false;
gasPriceField.value = item.gasPrice;
@ -64,7 +64,7 @@ Dialog {
for (var c in contracts) {
contractsModel.append({ cid: c, text: contracts[c].contract.name });
if (contracts[c].contract.name === contractId)
contractIndex = contractsModel.count - 1;
contractIndex = contractsModel.count - 1;
}
if (contractIndex == -1 && contractsModel.count > 0)
@ -233,7 +233,7 @@ Dialog {
item.functionId = item.contractId;
item.label = qsTr("Deploy") + " " + item.contractId;
}
item.saveStatus = saveStatus
item.saveStatus = saveStatus
item.sender = senderComboBox.model[senderComboBox.currentIndex].secret;
item.parameters = paramValues;
return item;

110
mix/qml/js/ProjectModel.js

@ -82,9 +82,9 @@ function saveProjectFile()
};
for (var i = 0; i < projectListModel.count; i++)
projectData.files.push({
title: projectListModel.get(i).name,
fileName: projectListModel.get(i).fileName,
});
title: projectListModel.get(i).name,
fileName: projectListModel.get(i).fileName,
});
projectFileSaving(projectData);
var json = JSON.stringify(projectData, null, "\t");
@ -98,52 +98,52 @@ function saveProjectFile()
function loadProject(path) {
closeProject(function() {
console.log("Loading project at " + path);
var projectFile = path + projectFileName;
var json = fileIo.readFile(projectFile);
if (!json)
return;
var projectData = JSON.parse(json);
if (projectData.deploymentDir)
projectModel.deploymentDir = projectData.deploymentDir
if (projectData.packageHash)
deploymentDialog.packageHash = projectData.packageHash
if (projectData.packageBase64)
deploymentDialog.packageBase64 = projectData.packageBase64
if (projectData.applicationUrlEth)
deploymentDialog.applicationUrlEth = projectData.applicationUrlEth
if (projectData.applicationUrlHttp)
deploymentDialog.applicationUrlHttp = projectData.applicationUrlHttp
if (!projectData.title) {
var parts = path.split("/");
projectData.title = parts[parts.length - 2];
}
deploymentAddresses = projectData.deploymentAddresses ? projectData.deploymentAddresses : [];
projectTitle = projectData.title;
projectPath = path;
if (!projectData.files)
projectData.files = [];
for(var i = 0; i < projectData.files.length; i++) {
var entry = projectData.files[i];
if (typeof(entry) === "string")
addFile(entry); //TODO: remove old project file support
else
addFile(entry.fileName, entry.title);
}
if (mainApplication.trackLastProject)
projectSettings.lastProjectPath = path;
projectLoading(projectData);
projectLoaded()
//TODO: move this to codemodel
var contractSources = {};
for (var d = 0; d < listModel.count; d++) {
var doc = listModel.get(d);
if (doc.isContract)
contractSources[doc.documentId] = fileIo.readFile(doc.path);
}
codeModel.reset(contractSources);
console.log("Loading project at " + path);
var projectFile = path + projectFileName;
var json = fileIo.readFile(projectFile);
if (!json)
return;
var projectData = JSON.parse(json);
if (projectData.deploymentDir)
projectModel.deploymentDir = projectData.deploymentDir
if (projectData.packageHash)
deploymentDialog.packageHash = projectData.packageHash
if (projectData.packageBase64)
deploymentDialog.packageBase64 = projectData.packageBase64
if (projectData.applicationUrlEth)
deploymentDialog.applicationUrlEth = projectData.applicationUrlEth
if (projectData.applicationUrlHttp)
deploymentDialog.applicationUrlHttp = projectData.applicationUrlHttp
if (!projectData.title) {
var parts = path.split("/");
projectData.title = parts[parts.length - 2];
}
deploymentAddresses = projectData.deploymentAddresses ? projectData.deploymentAddresses : [];
projectTitle = projectData.title;
projectPath = path;
if (!projectData.files)
projectData.files = [];
for(var i = 0; i < projectData.files.length; i++) {
var entry = projectData.files[i];
if (typeof(entry) === "string")
addFile(entry); //TODO: remove old project file support
else
addFile(entry.fileName, entry.title);
}
if (mainApplication.trackLastProject)
projectSettings.lastProjectPath = path;
projectLoading(projectData);
projectLoaded()
//TODO: move this to codemodel
var contractSources = {};
for (var d = 0; d < listModel.count; d++) {
var doc = listModel.get(d);
if (doc.isContract)
contractSources[doc.documentId] = fileIo.readFile(doc.path);
}
codeModel.reset(contractSources);
});
}
@ -162,12 +162,12 @@ function addFile(fileName, title) {
path: p,
fileName: fileName,
name: title !== undefined ? title : fileName,
documentId: fileName,
syntaxMode: syntaxMode,
isText: isContract || isHtml || isCss || isJs,
isContract: isContract,
isHtml: isHtml,
groupName: groupName
documentId: fileName,
syntaxMode: syntaxMode,
isText: isContract || isHtml || isCss || isJs,
isContract: isContract,
isHtml: isHtml,
groupName: groupName
};
projectListModel.append(docData);

4
mix/qml/js/TransactionHelper.js

@ -12,8 +12,8 @@ function defaultTransaction()
stdContract: false,
isContractCreation: true,
label: "",
isFunctionCall: true,
saveStatus: true
isFunctionCall: true,
saveStatus: true
};
}

Loading…
Cancel
Save