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 <QQmlContext>
#include <QQmlApplicationEngine>
#include <QStandardPaths>
#include <QFile>
#include <QDir>
#include <libdevcrypto/FileSystem.h>
#include <libwebthree/WebThree.h>
#include "KeyEventManager.h"
#include "AppContext.h"
#include "CodeModel.h"
@ -38,37 +40,39 @@ using namespace dev::eth;
using namespace dev::solidity;
using namespace dev::mix;
const QString c_projectFileName = "project.mix";
AppContext::AppContext(QQmlApplicationEngine* _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_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get());
m_applicationEngine->rootContext()->setContextProperty("appContext", this);
}
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)
{
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()
QQmlApplicationEngine* AppContext::appEngine()
{
return m_keyEventManager.get();
return m_applicationEngine;
}
void AppContext::displayMessageDialog(QString _title, QString _message)
@ -84,8 +88,18 @@ void AppContext::displayMessageDialog(QString _title, QString _message)
QMetaObject::invokeMethod(dialogWin, "open");
}
void AppContext::resourceLoaded(QObject *_obj, QUrl _url)
void AppContext::saveProject(QString const& _json)
{
Q_UNUSED(_url);
initKeyEventManager(_obj);
QDir dirPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
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 KeyEventManager;
/**
* @brief Provides access to application scope variable.
*/
@ -60,26 +59,25 @@ public:
AppContext(QQmlApplicationEngine* _engine);
~AppContext();
QQmlApplicationEngine* appEngine();
/// Initialize KeyEventManager (used to handle key pressed event).
void initKeyEventManager(QObject* _obj);
/// Get the current KeyEventManager instance.
KeyEventManager* getKeyEventManager();
/// Get code model
CodeModel* codeModel() { return m_codeModel.get(); }
/// Display an alert message.
void displayMessageDialog(QString _title, QString _message);
/// Load project settings
void loadProject();
signals:
void projectLoaded(QString const& _json);
private:
QQmlApplicationEngine* m_applicationEngine; //owned by app
std::unique_ptr<dev::WebThreeDirect> m_webThree;
std::unique_ptr<KeyEventManager> m_keyEventManager;
std::unique_ptr<CodeModel> m_codeModel;
public slots:
/// Delete the current instance when application quit.
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 "AssemblyDebuggerModel.h"
#include "AssemblyDebuggerControl.h"
#include "KeyEventManager.h"
#include "AppContext.h"
#include "DebuggingStateWrapper.h"
#include "TransactionListModel.h"
#include "QContractDefinition.h"
#include "QVariableDeclaration.h"
#include "ContractCallDataEncoder.h"
#include "KeyEventManager.h"
#include "CodeModel.h"
#include "AssemblyDebuggerModel.h"
using namespace dev::eth;
using namespace dev::mix;
@ -53,6 +50,8 @@ AssemblyDebuggerControl::AssemblyDebuggerControl(AppContext* _context): Extensio
connect(this, SIGNAL(dataAvailable(bool, DebuggingStatusResult, QList<QVariableDefinition*>, QList<QObject*>, AssemblyDebuggerData)),
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);
}
@ -68,24 +67,23 @@ QString AssemblyDebuggerControl::title() 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)
{
QtConcurrent::run([this]()
{
deployContract();
});
}
else if (_key == Qt::Key_F6)
{
m_modelDebugger->resetState();
m_ctx->displayMessageDialog(QApplication::tr("State status"), QApplication::tr("State reseted ... need to redeploy contract"));
}
deployContract();
}
void AssemblyDebuggerControl::debugTransaction(QObject* _transaction)
{
auto mo = _transaction->metaObject();
auto p = mo->property(0);
}
void AssemblyDebuggerControl::resetState()
{
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)

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.
public slots:
/// Handle key pressed. F5 deploy contract - F6 reset state.
void keyPressed(int);
void debugDeployment();
void debugTransaction(QObject* _transaction);
void resetState();
/// Update UI with machine states result. Display a modal dialog.
void updateGUI(bool _success, DebuggingStatusResult const& _reason, QList<QVariableDefinition*> const& _returnParams = QList<QVariableDefinition*>(), QList<QObject*> const& _wStates = QList<QObject*>(), AssemblyDebuggerData const& _code = AssemblyDebuggerData());
/// Run the given transaction.

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");
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_appContext->loadProject();
}
MixApplication::~MixApplication()

3
mix/qml.qrc

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

4
mix/qml/TransactionDialog.qml

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

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.Layouts 1.1
Rectangle {
color: "transparent"
id: transactionListContainer
@ -14,6 +13,16 @@ Rectangle {
height: parent.height
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 {
anchors.top: parent.top
height: parent.height
@ -23,7 +32,8 @@ Rectangle {
id: transactionListModel
function runTransaction(index) {
console.log("runTransaction");
var item = transactionListModel.get(index);
debugModel.debugTransaction(item);
}
}
@ -67,6 +77,12 @@ Rectangle {
transactionListModel.set(transactionDialog.transactionIndex, item);
else
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.Dialogs 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import QtQuick.Window 2.1
import CodeEditorExtensionManager 1.0
ApplicationWindow {
@ -23,6 +23,11 @@ ApplicationWindow {
onTriggered: Qt.quit();
}
}
Menu {
title: qsTr("Debug")
MenuItem { action: debugRunAction }
MenuItem { action: debugResetStateAction }
}
}
Component.onCompleted: {
setX(Screen.width / 2 - width / 2);
@ -41,4 +46,18 @@ ApplicationWindow {
objectName: "alertMessageDialog"
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