From 4ddaa9dd9483101aaef02055f0e6aeca310b4ff9 Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 25 Dec 2014 13:39:44 +0100 Subject: [PATCH] project save/load --- mix/AppContext.cpp | 54 +++++++++++++++++++++------------ mix/AppContext.h | 14 ++++----- mix/AssemblyDebuggerControl.cpp | 34 ++++++++++----------- mix/AssemblyDebuggerControl.h | 5 +-- mix/KeyEventManager.cpp | 49 ------------------------------ mix/KeyEventManager.h | 53 -------------------------------- mix/MixApplication.cpp | 2 +- mix/qml.qrc | 3 +- mix/qml/TransactionDialog.qml | 4 --- mix/qml/TransactionItem.qml | 11 ------- mix/qml/TransactionList.qml | 21 +++++++++++-- mix/qml/main.qml | 21 ++++++++++++- 12 files changed, 100 insertions(+), 171 deletions(-) delete mode 100644 mix/KeyEventManager.cpp delete mode 100644 mix/KeyEventManager.h delete mode 100644 mix/qml/TransactionItem.qml diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index e70d3d0b1..b97b1b265 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -27,9 +27,11 @@ #include #include #include +#include +#include +#include #include #include -#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(new KeyEventManager()); - m_webThree = std::unique_ptr(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(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(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("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; + } + } } diff --git a/mix/AppContext.h b/mix/AppContext.h index 432b1e976..d3aeb28c5 100644 --- a/mix/AppContext.h +++ b/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 m_webThree; - std::unique_ptr m_keyEventManager; std::unique_ptr 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); }; } diff --git a/mix/AssemblyDebuggerControl.cpp b/mix/AssemblyDebuggerControl.cpp index b6d839e25..43a36287d 100644 --- a/mix/AssemblyDebuggerControl.cpp +++ b/mix/AssemblyDebuggerControl.cpp @@ -26,16 +26,13 @@ #include #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, QList, AssemblyDebuggerData)), this, SLOT(updateGUI(bool, DebuggingStatusResult, QList, QList, AssemblyDebuggerData)), Qt::QueuedConnection); + _context->appEngine()->rootContext()->setContextProperty("debugModel", this); + m_modelDebugger = std::unique_ptr(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) diff --git a/mix/AssemblyDebuggerControl.h b/mix/AssemblyDebuggerControl.h index 69239f827..8a906d9f4 100644 --- a/mix/AssemblyDebuggerControl.h +++ b/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 const& _returnParams = QList(), QList const& _wStates = QList(), AssemblyDebuggerData const& _code = AssemblyDebuggerData()); /// Run the given transaction. diff --git a/mix/KeyEventManager.cpp b/mix/KeyEventManager.cpp deleted file mode 100644 index f7af8270b..000000000 --- a/mix/KeyEventManager.cpp +++ /dev/null @@ -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 . -*/ -/** @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 -#include -#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()); -} - -} -} diff --git a/mix/KeyEventManager.h b/mix/KeyEventManager.h deleted file mode 100644 index 2b538ea24..000000000 --- a/mix/KeyEventManager.h +++ /dev/null @@ -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 . -*/ -/** @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 - -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); -}; - -} -} diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp index e37296547..c2e856d8e 100644 --- a/mix/MixApplication.cpp +++ b/mix/MixApplication.cpp @@ -32,8 +32,8 @@ MixApplication::MixApplication(int _argc, char* _argv[]): { qmlRegisterType("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() diff --git a/mix/qml.qrc b/mix/qml.qrc index 2ab2989b9..1e2fe9983 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -11,8 +11,7 @@ qml/TransactionList.qml qml/ModalDialog.qml qml/AlertMessageDialog.qml - qml/StateItem.qml + qml/StateDialog.qml qml/StateList.qml - qml/TransactionItem.qml diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index a6f22b0ca..14b41bde1 100644 --- a/mix/qml/TransactionDialog.qml +++ b/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); } diff --git a/mix/qml/TransactionItem.qml b/mix/qml/TransactionItem.qml deleted file mode 100644 index 70b26b202..000000000 --- a/mix/qml/TransactionItem.qml +++ /dev/null @@ -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; -} diff --git a/mix/qml/TransactionList.qml b/mix/qml/TransactionList.qml index 2d4de02b5..fd85f0d7b 100644 --- a/mix/qml/TransactionList.qml +++ b/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 { } } } + diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 1e7542831..e44144f61 100644 --- a/mix/qml/main.qml +++ b/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(); + } }