Browse Source

project save/load

cl-refactor
arkpar 10 years ago
parent
commit
4ddaa9dd94
  1. 54
      mix/AppContext.cpp
  2. 14
      mix/AppContext.h
  3. 34
      mix/AssemblyDebuggerControl.cpp
  4. 5
      mix/AssemblyDebuggerControl.h
  5. 49
      mix/KeyEventManager.cpp
  6. 53
      mix/KeyEventManager.h
  7. 2
      mix/MixApplication.cpp
  8. 3
      mix/qml.qrc
  9. 4
      mix/qml/TransactionDialog.qml
  10. 11
      mix/qml/TransactionItem.qml
  11. 21
      mix/qml/TransactionList.qml
  12. 21
      mix/qml/main.qml

54
mix/AppContext.cpp

@ -27,9 +27,11 @@
#include <QQmlComponent> #include <QQmlComponent>
#include <QQmlContext> #include <QQmlContext>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QStandardPaths>
#include <QFile>
#include <QDir>
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
#include "KeyEventManager.h"
#include "AppContext.h" #include "AppContext.h"
#include "CodeModel.h" #include "CodeModel.h"
@ -38,37 +40,39 @@ using namespace dev::eth;
using namespace dev::solidity; using namespace dev::solidity;
using namespace dev::mix; using namespace dev::mix;
const QString c_projectFileName = "project.mix";
AppContext::AppContext(QQmlApplicationEngine* _engine) AppContext::AppContext(QQmlApplicationEngine* _engine)
{ {
m_applicationEngine = _engine; m_applicationEngine = _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_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_codeModel = std::unique_ptr<CodeModel>(new CodeModel(this));
m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get()); m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get());
m_applicationEngine->rootContext()->setContextProperty("appContext", this);
} }
AppContext::~AppContext() AppContext::~AppContext()
{ {
} }
QQmlApplicationEngine* AppContext::appEngine() void AppContext::loadProject()
{ {
return m_applicationEngine; QString path = QStandardPaths::locate(QStandardPaths::DataLocation, c_projectFileName);
if (!path.isEmpty())
{
QFile file(path);
if(file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream stream(&file);
QString json = stream.readAll();
emit projectLoaded(json);
}
}
} }
void AppContext::initKeyEventManager(QObject* _res) QQmlApplicationEngine* AppContext::appEngine()
{
QObject* mainContent = _res->findChild<QObject*>("mainContent", Qt::FindChildrenRecursively);
if (mainContent)
QObject::connect(mainContent, SIGNAL(keyPressed(QVariant)), m_keyEventManager.get(), SLOT(keyPressed(QVariant)));
else
qDebug() << "Unable to find QObject of mainContent.qml. KeyEvent will not be handled!";
}
KeyEventManager* AppContext::getKeyEventManager()
{ {
return m_keyEventManager.get(); return m_applicationEngine;
} }
void AppContext::displayMessageDialog(QString _title, QString _message) void AppContext::displayMessageDialog(QString _title, QString _message)
@ -84,8 +88,18 @@ void AppContext::displayMessageDialog(QString _title, QString _message)
QMetaObject::invokeMethod(dialogWin, "open"); QMetaObject::invokeMethod(dialogWin, "open");
} }
void AppContext::resourceLoaded(QObject *_obj, QUrl _url) void AppContext::saveProject(QString const& _json)
{ {
Q_UNUSED(_url); QDir dirPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
initKeyEventManager(_obj); QString path = QDir(dirPath).filePath(c_projectFileName);
if (!path.isEmpty())
{
dirPath.mkpath(dirPath.path());
QFile file(path);
if(file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream stream(&file);
stream << _json;
}
}
} }

14
mix/AppContext.h

@ -47,7 +47,6 @@ namespace mix
{ {
class CodeModel; class CodeModel;
class KeyEventManager;
/** /**
* @brief Provides access to application scope variable. * @brief Provides access to application scope variable.
*/ */
@ -60,26 +59,25 @@ public:
AppContext(QQmlApplicationEngine* _engine); AppContext(QQmlApplicationEngine* _engine);
~AppContext(); ~AppContext();
QQmlApplicationEngine* appEngine(); QQmlApplicationEngine* appEngine();
/// Initialize KeyEventManager (used to handle key pressed event).
void initKeyEventManager(QObject* _obj);
/// Get the current KeyEventManager instance.
KeyEventManager* getKeyEventManager();
/// Get code model /// Get code model
CodeModel* codeModel() { return m_codeModel.get(); } CodeModel* codeModel() { return m_codeModel.get(); }
/// Display an alert message. /// Display an alert message.
void displayMessageDialog(QString _title, QString _message); void displayMessageDialog(QString _title, QString _message);
/// Load project settings
void loadProject();
signals:
void projectLoaded(QString const& _json);
private: private:
QQmlApplicationEngine* m_applicationEngine; //owned by app QQmlApplicationEngine* m_applicationEngine; //owned by app
std::unique_ptr<dev::WebThreeDirect> m_webThree; std::unique_ptr<dev::WebThreeDirect> m_webThree;
std::unique_ptr<KeyEventManager> m_keyEventManager;
std::unique_ptr<CodeModel> m_codeModel; std::unique_ptr<CodeModel> m_codeModel;
public slots: public slots:
/// Delete the current instance when application quit. /// Delete the current instance when application quit.
void quitApplication() {} void quitApplication() {}
/// Initialize components after the loading of the main QML view.
void resourceLoaded(QObject* _obj, QUrl _url); void saveProject(QString const& _json);
}; };
} }

34
mix/AssemblyDebuggerControl.cpp

@ -26,16 +26,13 @@
#include <libethereum/Transaction.h> #include <libethereum/Transaction.h>
#include "AssemblyDebuggerModel.h" #include "AssemblyDebuggerModel.h"
#include "AssemblyDebuggerControl.h" #include "AssemblyDebuggerControl.h"
#include "KeyEventManager.h"
#include "AppContext.h" #include "AppContext.h"
#include "DebuggingStateWrapper.h" #include "DebuggingStateWrapper.h"
#include "TransactionListModel.h" #include "TransactionListModel.h"
#include "QContractDefinition.h" #include "QContractDefinition.h"
#include "QVariableDeclaration.h" #include "QVariableDeclaration.h"
#include "ContractCallDataEncoder.h" #include "ContractCallDataEncoder.h"
#include "KeyEventManager.h"
#include "CodeModel.h" #include "CodeModel.h"
#include "AssemblyDebuggerModel.h"
using namespace dev::eth; using namespace dev::eth;
using namespace dev::mix; using namespace dev::mix;
@ -53,6 +50,8 @@ AssemblyDebuggerControl::AssemblyDebuggerControl(AppContext* _context): Extensio
connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)),
this, SLOT(updateGUI(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), Qt::QueuedConnection); this, SLOT(updateGUI(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)), Qt::QueuedConnection);
_context->appEngine()->rootContext()->setContextProperty("debugModel", this);
m_modelDebugger = std::unique_ptr<AssemblyDebuggerModel>(new AssemblyDebuggerModel); m_modelDebugger = std::unique_ptr<AssemblyDebuggerModel>(new AssemblyDebuggerModel);
} }
@ -68,24 +67,23 @@ QString AssemblyDebuggerControl::title() const
void AssemblyDebuggerControl::start() const void AssemblyDebuggerControl::start() const
{ {
//start to listen on F5
m_ctx->getKeyEventManager()->registerEvent(this, SLOT(keyPressed(int)));
} }
void AssemblyDebuggerControl::keyPressed(int _key) void AssemblyDebuggerControl::debugDeployment()
{ {
if (_key == Qt::Key_F5) deployContract();
{ }
QtConcurrent::run([this]()
{ void AssemblyDebuggerControl::debugTransaction(QObject* _transaction)
deployContract(); {
}); auto mo = _transaction->metaObject();
} auto p = mo->property(0);
else if (_key == Qt::Key_F6) }
{
m_modelDebugger->resetState(); void AssemblyDebuggerControl::resetState()
m_ctx->displayMessageDialog(QApplication::tr("State status"), QApplication::tr("State reseted ... need to redeploy contract")); {
} m_modelDebugger->resetState();
m_ctx->displayMessageDialog(QApplication::tr("State status"), QApplication::tr("State reseted ... need to redeploy contract"));
} }
void AssemblyDebuggerControl::callContract(TransactionSettings _tr, Address _contract) void AssemblyDebuggerControl::callContract(TransactionSettings _tr, Address _contract)

5
mix/AssemblyDebuggerControl.h

@ -65,8 +65,9 @@ private:
DebuggingContent m_previousDebugResult; //TODO: to be replaced in a more consistent struct. Used for now to keep the contract address in case of future transaction call. DebuggingContent m_previousDebugResult; //TODO: to be replaced in a more consistent struct. Used for now to keep the contract address in case of future transaction call.
public slots: public slots:
/// Handle key pressed. F5 deploy contract - F6 reset state. void debugDeployment();
void keyPressed(int); void debugTransaction(QObject* _transaction);
void resetState();
/// Update UI with machine states result. Display a modal dialog. /// Update UI with machine states result. Display a modal dialog.
void updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData()); void updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData());
/// Run the given transaction. /// Run the given transaction.

49
mix/KeyEventManager.cpp

@ -1,49 +0,0 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file KeyEventManager.cpp
* @author Yann yann@ethdev.com
* @date 2014
* Used as an event handler for all classes which need keyboard interactions.
* Can be improve by adding the possibility to register to a specific key.
*/
#include <QDebug>
#include <QKeySequence>
#include "KeyEventManager.h"
namespace dev
{
namespace mix
{
void KeyEventManager::registerEvent(const QObject* _receiver, const char* _slot)
{
QObject::connect(this, SIGNAL(onKeyPressed(int)), _receiver, _slot);
}
void KeyEventManager::unRegisterEvent(QObject* _receiver)
{
QObject::disconnect(_receiver);
}
void KeyEventManager::keyPressed(QVariant _event)
{
emit onKeyPressed(_event.toInt());
}
}
}

53
mix/KeyEventManager.h

@ -1,53 +0,0 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file KeyEventManager.h
* @author Yann yann@ethdev.com
* @date 2014
* Used as an event handler for all classes which need keyboard interactions
*/
#pragma once
#include <QObject>
namespace dev
{
namespace mix
{
class KeyEventManager: public QObject
{
Q_OBJECT
public:
KeyEventManager() {}
/// Allows _receiver to handle key pressed event.
void registerEvent(const QObject* _receiver, const char* _slot);
/// Unregister _receiver.
void unRegisterEvent(QObject* _receiver);
signals:
/// Emited when a key is pressed.
void onKeyPressed(int _event);
public slots:
/// Called when a key is pressed.
void keyPressed(QVariant _event);
};
}
}

2
mix/MixApplication.cpp

@ -32,8 +32,8 @@ MixApplication::MixApplication(int _argc, char* _argv[]):
{ {
qmlRegisterType<CodeEditorExtensionManager>("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); qmlRegisterType<CodeEditorExtensionManager>("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager");
QObject::connect(this, SIGNAL(lastWindowClosed()), context(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff QObject::connect(this, SIGNAL(lastWindowClosed()), context(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff
QObject::connect(engine(), SIGNAL(objectCreated(QObject*, QUrl)), context(), SLOT(resourceLoaded(QObject*, QUrl)));
m_engine->load(QUrl("qrc:/qml/main.qml")); m_engine->load(QUrl("qrc:/qml/main.qml"));
m_appContext->loadProject();
} }
MixApplication::~MixApplication() MixApplication::~MixApplication()

3
mix/qml.qrc

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

4
mix/qml/TransactionDialog.qml

@ -55,11 +55,8 @@ Window {
return; return;
paramsModel.clear(); paramsModel.clear();
if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) {
console.log(codeModel.code.contract.functions[functionComboBox.currentIndex]);
var func = codeModel.code.contract.functions[functionComboBox.currentIndex]; var func = codeModel.code.contract.functions[functionComboBox.currentIndex];
var parameters = func.parameters; var parameters = func.parameters;
console.log(parameters);
console.log(parameters.length);
for (var p = 0; p < parameters.length; p++) { for (var p = 0; p < parameters.length; p++) {
paramsModel.append({ name: parameters[p].name, type: parameters[p].type, value: parameters[p].value !== undefined ? parameters[p].value : "" }); paramsModel.append({ name: parameters[p].name, type: parameters[p].type, value: parameters[p].value !== undefined ? parameters[p].value : "" });
} }
@ -197,7 +194,6 @@ Window {
Connections { Connections {
target: loaderEditor.item target: loaderEditor.item
onTextChanged: { onTextChanged: {
console.log(styleData.row + " : " + styleData.role + " = " + loaderEditor.item.text );
if (styleData.role === "value" && styleData.row < paramsModel.count) if (styleData.role === "value" && styleData.row < paramsModel.count)
paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text); paramsModel.setProperty(styleData.row, styleData.role, loaderEditor.item.text);
} }

11
mix/qml/TransactionItem.qml

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

21
mix/qml/TransactionList.qml

@ -4,7 +4,6 @@ import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
Rectangle { Rectangle {
color: "transparent" color: "transparent"
id: transactionListContainer id: transactionListContainer
@ -14,6 +13,16 @@ Rectangle {
height: parent.height height: parent.height
width: parent.width width: parent.width
Connections {
target: appContext
onProjectLoaded: {
var items = JSON.parse(_json);
for(var i = 0; i < items.length; i++) {
transactionListModel.append(items[i]);
}
}
}
ListView { ListView {
anchors.top: parent.top anchors.top: parent.top
height: parent.height height: parent.height
@ -23,7 +32,8 @@ Rectangle {
id: transactionListModel id: transactionListModel
function runTransaction(index) { function runTransaction(index) {
console.log("runTransaction"); var item = transactionListModel.get(index);
debugModel.debugTransaction(item);
} }
} }
@ -67,6 +77,12 @@ Rectangle {
transactionListModel.set(transactionDialog.transactionIndex, item); transactionListModel.set(transactionDialog.transactionIndex, item);
else else
transactionListModel.append(item); transactionListModel.append(item);
var items = [];
for (var i = 0; i < transactionListModel.count; i++)
items.push(transactionListModel.get(i));
var json = JSON.stringify(items, function(key, value) { return key === "objectName" ? undefined : value; });
appContext.saveProject(json);
} }
} }
@ -113,3 +129,4 @@ Rectangle {
} }
} }
} }

21
mix/qml/main.qml

@ -3,7 +3,7 @@ import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Window 2.0 import QtQuick.Window 2.1
import CodeEditorExtensionManager 1.0 import CodeEditorExtensionManager 1.0
ApplicationWindow { ApplicationWindow {
@ -23,6 +23,11 @@ ApplicationWindow {
onTriggered: Qt.quit(); onTriggered: Qt.quit();
} }
} }
Menu {
title: qsTr("Debug")
MenuItem { action: debugRunAction }
MenuItem { action: debugResetStateAction }
}
} }
Component.onCompleted: { Component.onCompleted: {
setX(Screen.width / 2 - width / 2); setX(Screen.width / 2 - width / 2);
@ -41,4 +46,18 @@ ApplicationWindow {
objectName: "alertMessageDialog" objectName: "alertMessageDialog"
id: messageDialog id: messageDialog
} }
Action {
id: debugRunAction
text: "&Run"
shortcut: "F5"
onTriggered: debugModel.debugDeployment();
}
Action {
id: debugResetStateAction
text: "Reset &State"
shortcut: "F6"
onTriggered: debugModel.resetState();
}
} }

Loading…
Cancel
Save