diff --git a/mix/AppContext.cpp b/mix/AppContext.cpp index 4c8e61510..cd47e5b95 100644 --- a/mix/AppContext.cpp +++ b/mix/AppContext.cpp @@ -22,7 +22,6 @@ * - KeyEventManager */ -#include #include #include #include @@ -30,8 +29,10 @@ #include "CodeModel.h" #include "FileIo.h" #include "ClientModel.h" +#include "CodeEditorExtensionManager.h" +#include "Exceptions.h" #include "AppContext.h" -#include +#include //this needs to be last because it pulls windows.h through libp2p/boost_asio using namespace dev; using namespace dev::eth; @@ -46,18 +47,33 @@ AppContext::AppContext(QQmlApplicationEngine* _engine) m_codeModel.reset(new CodeModel(this)); m_clientModel.reset(new ClientModel(this)); m_fileIo.reset(new FileIo()); - m_applicationEngine->rootContext()->setContextProperty("appContext", this); - qmlRegisterType("org.ethereum.qml", 1, 0, "FileIo"); - qmlRegisterSingletonType(QUrl("qrc:/qml/ProjectModel.qml"), "org.ethereum.qml.ProjectModel", 1, 0, "ProjectModel"); - m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get()); - m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get()); - } AppContext::~AppContext() { } +void AppContext::load() +{ + m_applicationEngine->rootContext()->setContextProperty("appContext", this); + qmlRegisterType("org.ethereum.qml", 1, 0, "FileIo"); + m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get()); + m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get()); + QQmlComponent projectModelComponent(m_applicationEngine, QUrl("qrc:/qml/ProjectModel.qml")); + QObject* projectModel = projectModelComponent.create(); + if (projectModelComponent.isError()) + { + QmlLoadException exception; + for (auto const& e : projectModelComponent.errors()) + exception << QmlErrorInfo(e); + BOOST_THROW_EXCEPTION(exception); + } + m_applicationEngine->rootContext()->setContextProperty("projectModel", projectModel); + qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); + m_applicationEngine->load(QUrl("qrc:/qml/main.qml")); + appLoaded(); +} + QQmlApplicationEngine* AppContext::appEngine() { return m_applicationEngine; diff --git a/mix/AppContext.h b/mix/AppContext.h index dec3b319e..e959397f7 100644 --- a/mix/AppContext.h +++ b/mix/AppContext.h @@ -60,6 +60,8 @@ class AppContext: public QObject public: AppContext(QQmlApplicationEngine* _engine); virtual ~AppContext(); + /// Load the UI from qml files + void load(); /// Get the current QQMLApplicationEngine instance. QQmlApplicationEngine* appEngine(); /// Get code model diff --git a/mix/Exceptions.cpp b/mix/Exceptions.cpp new file mode 100644 index 000000000..08f59f7ef --- /dev/null +++ b/mix/Exceptions.cpp @@ -0,0 +1,31 @@ +/* + 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 Exceptions.cpp + * @author Arkadiy Paronyan arkadiy@ethdev.com + * @date 2015 + * Ethereum IDE client. + */ + +#include +#include +#include "Exceptions.h" + +std::ostream& operator<<(std::ostream& _out, QQmlError const& _error) +{ + _out << _error.toString().toStdString(); + return _out; +} diff --git a/mix/Exceptions.h b/mix/Exceptions.h new file mode 100644 index 000000000..2a3d813eb --- /dev/null +++ b/mix/Exceptions.h @@ -0,0 +1,45 @@ +/* + 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 Exceptions.h + * @author Arkadiy Paronyan arkadiy@ethdev.com + * @date 2015 + * Ethereum IDE client. + */ + +#pragma once + +#include +#include + +class QTextDocument; +class QQmlError; + +namespace dev +{ +namespace mix +{ + +struct QmlLoadException: virtual Exception {}; +struct FileIoException: virtual Exception {}; + +typedef boost::error_info QmlErrorInfo; +typedef boost::error_info FileError; + +} +} + +std::ostream& operator<<(std::ostream& _out, QQmlError const& _error); diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp index fed9909e6..e5a3e5364 100644 --- a/mix/FileIo.cpp +++ b/mix/FileIo.cpp @@ -20,7 +20,6 @@ * Ethereum IDE client. */ -#include #include #include #include diff --git a/mix/MixApplication.cpp b/mix/MixApplication.cpp index 2cdc4b30d..3b5cfe85d 100644 --- a/mix/MixApplication.cpp +++ b/mix/MixApplication.cpp @@ -21,7 +21,6 @@ #include #include -#include "CodeEditorExtensionManager.h" #include "MixApplication.h" #include "AppContext.h" @@ -32,10 +31,8 @@ using namespace dev::mix; MixApplication::MixApplication(int _argc, char* _argv[]): QApplication(_argc, _argv), m_engine(new QQmlApplicationEngine()), m_appContext(new AppContext(m_engine.get())) { - qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); QObject::connect(this, SIGNAL(lastWindowClosed()), context(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff - m_engine->load(QUrl("qrc:/qml/main.qml")); - m_appContext->appLoaded(); + m_appContext->load(); } MixApplication::~MixApplication() diff --git a/mix/main.cpp b/mix/main.cpp index 90099555f..4f2c901b4 100644 --- a/mix/main.cpp +++ b/mix/main.cpp @@ -20,11 +20,24 @@ * Ethereum IDE client. */ +#include #include "MixApplication.h" +#include "Exceptions.h" using namespace dev::mix; int main(int _argc, char* _argv[]) { - MixApplication app(_argc, _argv); - return app.exec(); + try + { + MixApplication app(_argc, _argv); + return app.exec(); + } + catch (boost::exception const& _e) + { + std::cerr << boost::diagnostic_information(_e); + } + catch (std::exception const& _e) + { + std::cerr << _e.what(); + } } diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 4e95bd49c..c84d89bfe 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -2,7 +2,6 @@ import QtQuick 2.0 import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 -import org.ethereum.qml.ProjectModel 1.0 Item { @@ -40,7 +39,7 @@ Item { } Connections { - target: ProjectModel + target: projectModel onDocumentOpened: { openDocument(document); } diff --git a/mix/qml/ProjectList.qml b/mix/qml/ProjectList.qml index af3f4b155..34eaf3286 100644 --- a/mix/qml/ProjectList.qml +++ b/mix/qml/ProjectList.qml @@ -2,7 +2,6 @@ import QtQuick 2.0 import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 -import org.ethereum.qml.ProjectModel 1.0 Item { property bool renameMode: false; @@ -11,16 +10,16 @@ Item { Text { Layout.fillWidth: true color: "blue" - text: ProjectModel.projectData ? ProjectModel.projectData.title : "" + text: projectModel.projectData ? projectModel.projectData.title : "" horizontalAlignment: Text.AlignHCenter - visible: !ProjectModel.isEmpty; + visible: !projectModel.isEmpty; } ListView { id: projectList Layout.fillWidth: true Layout.fillHeight: true - model: ProjectModel.listModel + model: projectModel.listModel delegate: renderDelegate highlight: Rectangle { @@ -31,8 +30,8 @@ Item { clip: true onCurrentIndexChanged: { - if (currentIndex >= 0 && currentIndex < ProjectModel.listModel.count) - ProjectModel.openDocument(ProjectModel.listModel.get(currentIndex).documentId); + if (currentIndex >= 0 && currentIndex < projectModel.listModel.count) + projectModel.openDocument(projectModel.listModel.get(currentIndex).documentId); } } Menu { @@ -46,7 +45,7 @@ Item { MenuItem { text: qsTr("Delete") onTriggered: { - ProjectModel.removeDocument(projectList.model.get(projectList.currentIndex).documentId); + projectModel.removeDocument(projectList.model.get(projectList.currentIndex).documentId); } } } @@ -103,7 +102,7 @@ Item { function close(accept) { renameMode = false; if (accept) - ProjectModel.renameDocument(projectList.model.get(projectList.currentIndex).documentId, textInput.text); + projectModel.renameDocument(projectList.model.get(projectList.currentIndex).documentId, textInput.text); } } MouseArea { @@ -119,7 +118,7 @@ Item { } } Connections { - target: ProjectModel + target: projectModel onProjectLoaded: { projectList.currentIndex = 0; } diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 5337e2780..91a4a97ca 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -1,5 +1,3 @@ -pragma Singleton - import QtQuick 2.0 import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 @@ -46,7 +44,7 @@ Item { target: appContext onAppLoaded: { if (projectSettings.lastProjectPath) - loadProject(projectSettings.lastProjectPath) + projectModel.loadProject(projectSettings.lastProjectPath) } } diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index 519e533d5..cdd48017a 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -3,7 +3,6 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 -import org.ethereum.qml.ProjectModel 1.0 Rectangle { color: "#ededed" @@ -16,7 +15,7 @@ Rectangle { property var stateList: [] Connections { - target: ProjectModel + target: projectModel onProjectClosed: { stateListModel.clear(); } @@ -91,7 +90,7 @@ Rectangle { } function save() { - ProjectModel.saveProject(); + projectModel.saveProject(); } } diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 469a6d1f4..e234d6344 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -5,7 +5,6 @@ import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 import CodeEditorExtensionManager 1.0 -import org.ethereum.qml.ProjectModel 1.0 ApplicationWindow { id: mainApplication @@ -101,7 +100,7 @@ ApplicationWindow { text: qsTr("&New project") shortcut: "Ctrl+N" enabled: true; - onTriggered: ProjectModel.createProject(); + onTriggered: projectModel.createProject(); } Action { @@ -109,54 +108,54 @@ ApplicationWindow { text: qsTr("&Open project") shortcut: "Ctrl+O" enabled: true; - onTriggered: ProjectModel.browseProject(); + onTriggered: projectModel.browseProject(); } Action { id: addNewJsFileAction text: qsTr("New JavaScript file") shortcut: "Ctrl+Alt+J" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.newJsFile(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.newJsFile(); } Action { id: addNewHtmlFileAction text: qsTr("New HTML file") shortcut: "Ctrl+Alt+H" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.newHtmlFile(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.newHtmlFile(); } Action { id: addNewContractAction text: qsTr("New contract") shortcut: "Ctrl+Alt+C" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.newContract(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.newContract(); } Action { id: addExistingFileAction text: qsTr("Add existing file") shortcut: "Ctrl+Alt+A" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.addExistingFile(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.addExistingFile(); } Action { id: saveAllFilesAction text: qsTr("Save all") shortcut: "Ctrl+S" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.saveAll(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.saveAll(); } Action { id: closeProjectAction text: qsTr("Close project") shortcut: "Ctrl+W" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.closeProject(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.closeProject(); } }