diff --git a/mix/ApplicationContext.cpp b/mix/ApplicationContext.cpp new file mode 100644 index 000000000..dcbb6d958 --- /dev/null +++ b/mix/ApplicationContext.cpp @@ -0,0 +1,33 @@ +#include "ApplicationContext.h" +#include + +ApplicationContext* ApplicationContext::m_instance = nullptr; + +ApplicationContext::ApplicationContext(QQmlApplicationEngine* _engine) +{ + m_applicationEngine = _engine; +} + +ApplicationContext::~ApplicationContext() +{ + delete m_applicationEngine; +} + +ApplicationContext* ApplicationContext::GetInstance() +{ + return m_instance; +} + +void ApplicationContext::SetApplicationContext(QQmlApplicationEngine* engine) +{ + m_instance = new ApplicationContext(engine); +} + +QQmlApplicationEngine* ApplicationContext::appEngine(){ + return m_applicationEngine; +} + +void ApplicationContext::QuitApplication() +{ + delete m_instance; +} diff --git a/mix/ApplicationContext.h b/mix/ApplicationContext.h new file mode 100644 index 000000000..154a4120e --- /dev/null +++ b/mix/ApplicationContext.h @@ -0,0 +1,23 @@ +#ifndef APPLICATIONCONTEXT_H +#define APPLICATIONCONTEXT_H + +#include + +class ApplicationContext : public QObject +{ + Q_OBJECT + +public: + ApplicationContext(QQmlApplicationEngine*); + ~ApplicationContext(); + QQmlApplicationEngine* appEngine(); + static ApplicationContext* GetInstance(); + static void SetApplicationContext(QQmlApplicationEngine*); +private: + static ApplicationContext* m_instance; + QQmlApplicationEngine* m_applicationEngine; +public slots: + void QuitApplication(); +}; + +#endif // APPLICATIONCONTEXT_H diff --git a/mix/BasicContent.qml b/mix/BasicContent.qml new file mode 100644 index 000000000..a61ee8b8f --- /dev/null +++ b/mix/BasicContent.qml @@ -0,0 +1,36 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 + +Rectangle { + anchors.fill: parent + width: parent.width + height: parent.height + color: "lightgray" + Text { + font.pointSize: 7 + anchors.left: parent.left + anchors.top: parent.top + anchors.topMargin: 3 + anchors.leftMargin: 3 + height: 9 + font.family: "Sego UI light" + objectName: "status" + id: status + } + + TextArea{ + readOnly: true + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.top: status.bottom + anchors.topMargin: 3 + font.pointSize: 7 + font.family: "Sego UI light" + height: parent.height * 0.8 + width: parent.width - 20 + wrapMode: Text.Wrap + backgroundVisible: false + objectName: "content" + id: content + } +} diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt new file mode 100644 index 000000000..7272c4d99 --- /dev/null +++ b/mix/CMakeLists.txt @@ -0,0 +1,94 @@ +set(CMAKE_INCLUDE_CURRENT_DIR ON) +aux_source_directory(. SRC_LIST) +include_directories(..) + +if (APPLE) + # Add homebrew path for qt5 + set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) + include_directories(/usr/local/opt/qt5/include /usr/local/include) +elseif ("${TARGET_PLATFORM}" STREQUAL "w64") + set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) + include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) +elseif (UNIX) + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake" /opt/Qt5.3.2/5.3/gcc_64/lib/cmake/Qt5Declarative) +endif () + +find_package(Qt5Core REQUIRED) +find_package(Qt5Gui REQUIRED) +find_package(Qt5Quick REQUIRED) +find_package(Qt5Qml REQUIRED) +find_package(Qt5Network REQUIRED) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5WebKit REQUIRED) +find_package(Qt5WebKitWidgets REQUIRED) +find_package(Qt5Declarative REQUIRED) + +#qt5_wrap_ui(ui_Main.h Main.ui) + +qt5_add_resources(UI_RESOURCES qml.qrc) + +# Set name of binary and add_executable() +file(GLOB HEADERS "*.h") +if (APPLE) + set(EXECUTEABLE mix) + set(BIN_INSTALL_DIR ".") + set(DOC_INSTALL_DIR ".") + + set(PROJECT_VERSION "${ETH_VERSION}") + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") + set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) + set(MACOSX_BUNDLE_ICON_FILE mix) + include(BundleUtilities) + + add_executable(${EXECUTEABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) + set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") + +else () + set(EXECUTEABLE mix) + add_executable(${EXECUTEABLE} ${SRC_LIST} ${HEADERS} ${UI_RESOURCES}) +endif () + +qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) +target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) + +if (APPLE) + # First have qt5 install plugins and frameworks + add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD + COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app + WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # This tool and next will inspect linked libraries in order to determine which dependencies are required + if (${CMAKE_CFG_INTDIR} STREQUAL ".") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app") + else () + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app") + endif () + install(CODE " + include(BundleUtilities) + set(BU_CHMOD_BUNDLE_ITEMS 1) + fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") + " COMPONENT RUNTIME ) + # Cleanup duplicate libs from macdeployqt + install(CODE " + file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") + if (LINGER_RM) + file(REMOVE \${LINGER_RM}) + endif () + ") +elseif (UNIX) +else () + target_link_libraries(${EXECUTEABLE} boost_system) + target_link_libraries(${EXECUTEABLE} boost_filesystem) + find_package(Threads REQUIRED) + target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) + install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) +endif () + +qt5_use_modules(${EXECUTEABLE} Core Gui Declarative) diff --git a/mix/CodeEditorExtensionMan.cpp b/mix/CodeEditorExtensionMan.cpp new file mode 100644 index 000000000..1c845dbbf --- /dev/null +++ b/mix/CodeEditorExtensionMan.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include +#include "CodeEditorExtensionMan.h" +#include "ConstantCompilation.h" +#include "features.h" +#include "ApplicationContext.h" +#include +using namespace dev; + +CodeEditorExtensionManager::CodeEditorExtensionManager() +{ +} + +void CodeEditorExtensionManager::loadEditor(QQuickItem* _editor) +{ + if (!_editor) + return; + try{ + QVariant doc = _editor->property("textDocument"); + if (doc.canConvert()) { + QQuickTextDocument* qqdoc = doc.value(); + if (qqdoc) { + m_doc = qqdoc->textDocument(); + } + } + } + catch (dev::Exception const& exception){ + qDebug() << "unable to load editor: "; + qDebug() << exception.what(); + } +} + +void CodeEditorExtensionManager::initExtensions() +{ + try{ + //only one for now + ConstantCompilation* compil = new ConstantCompilation(m_doc); + if (compil->tabUrl() != "") + compil->addContentOn(m_tabView); + compil->start(); + } + catch (dev::Exception const& exception){ + qDebug() << "unable to load extensions: "; + qDebug() << exception.what(); + } +} + +void CodeEditorExtensionManager::setEditor(QQuickItem* _editor){ + this->loadEditor(_editor); + this->initExtensions(); +} + +void CodeEditorExtensionManager::setTabView(QQuickItem* _tabView){ + m_tabView = _tabView; +} diff --git a/mix/CodeEditorExtensionMan.h b/mix/CodeEditorExtensionMan.h new file mode 100644 index 000000000..cfe505c09 --- /dev/null +++ b/mix/CodeEditorExtensionMan.h @@ -0,0 +1,28 @@ +#ifndef CODEEDITOREXTENSIONMANAGER_H +#define CODEEDITOREXTENSIONMANAGER_H + +#include +#include +#include "Feature.h" + +class CodeEditorExtensionManager : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QQuickItem* editor MEMBER m_editor WRITE setEditor) + Q_PROPERTY(QQuickItem* tabView MEMBER m_tabView WRITE setTabView) + +public: + CodeEditorExtensionManager(); + void initExtensions(); + void setEditor(QQuickItem*); + void setTabView(QQuickItem*); + +private: + QQuickItem* m_editor; + QQuickItem* m_tabView; + QTextDocument* m_doc; + void loadEditor(QQuickItem*); +}; + +#endif // CODEEDITOREXTENSIONMANAGER_H diff --git a/mix/ConstantCompilation.cpp b/mix/ConstantCompilation.cpp new file mode 100644 index 000000000..76fbd1546 --- /dev/null +++ b/mix/ConstantCompilation.cpp @@ -0,0 +1,88 @@ +#include "ConstantCompilation.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +using namespace dev; +using namespace dev::eth; + +ConstantCompilation::ConstantCompilation(QTextDocument* _doc) +{ + m_editor = _doc; +} + +QString ConstantCompilation::tabUrl(){ + return QStringLiteral("qrc:/BasicContent.qml"); +} + +void ConstantCompilation::start() +{ + connect(m_editor, SIGNAL(contentsChange(int,int,int)), this, SLOT(compile())); +} + +QString ConstantCompilation::title() +{ + return "compilation"; +} + +void ConstantCompilation::compile() +{ + QString codeContent = m_editor->toPlainText(); + if (codeContent == ""){ + this->writeOutPut(true, codeContent); + return; + } + dev::solidity::CompilerStack compiler; + dev::bytes m_data; + QString content; + try + { + m_data = compiler.compile(codeContent.toStdString(), true); + content = QString::fromStdString(dev::eth::disassemble(m_data)); + this->writeOutPut(true, content); + } + catch (dev::Exception const& exception) + { + ostringstream error; + solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler.getScanner()); + content = QString::fromStdString(error.str()).toHtmlEscaped(); + this->writeOutPut(false, content); + } + catch (...) + { + content = "Uncaught exception."; + this->writeOutPut(false, content); + } + +} +void ConstantCompilation::writeOutPut(bool _success, QString _content){ + QObject* status = m_view->findChild("status", Qt::FindChildrenRecursively); + QObject* content = m_view->findChild("content", Qt::FindChildrenRecursively); + if (_content == ""){ + status->setProperty("text", ""); + content->setProperty("text", ""); + } + else if (_success){ + status->setProperty("text", "compile successfull"); + status->setProperty("color", "green"); + content->setProperty("text", _content); + qDebug() << QString("compile suceeded " + _content); + } + else { + status->setProperty("text", "compile failed"); + status->setProperty("color", "red"); + content->setProperty("text", _content); + qDebug() << QString("compile failed " + _content); + } +} + + + + diff --git a/mix/ConstantCompilation.h b/mix/ConstantCompilation.h new file mode 100644 index 000000000..c3c93b8aa --- /dev/null +++ b/mix/ConstantCompilation.h @@ -0,0 +1,26 @@ +#ifndef CONSTANTCOMPILATION_H +#define CONSTANTCOMPILATION_H + +#include +#include "Feature.h" + +class ConstantCompilation : public Feature +{ + Q_OBJECT + +public: + ConstantCompilation(QTextDocument* doc); + void start(); + QString title(); + QString tabUrl(); + +private: + QTextDocument* m_editor; + void writeOutPut(bool success, QString content); + +public Q_SLOTS: + void compile(); + +}; + +#endif // CONSTANTCOMPILATION_H diff --git a/mix/ContextualTabs.qml b/mix/ContextualTabs.qml new file mode 100644 index 000000000..d32e6c3af --- /dev/null +++ b/mix/ContextualTabs.qml @@ -0,0 +1,5 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 + + + diff --git a/mix/Feature.cpp b/mix/Feature.cpp new file mode 100644 index 000000000..028dca8bd --- /dev/null +++ b/mix/Feature.cpp @@ -0,0 +1,33 @@ +#include "Feature.h" +#include "ApplicationContext.h" +#include +#include +#include +using namespace dev; + +Feature::Feature() +{ +} + +void Feature::addContentOn(QObject* tabView) { + try{ + if (tabUrl() == "") + return; + + QVariant returnValue; + QQmlComponent* component = new QQmlComponent( + ApplicationContext::GetInstance()->appEngine(), + QUrl(this->tabUrl())); + + QMetaObject::invokeMethod(tabView, "addTab", + Q_RETURN_ARG(QVariant, returnValue), + Q_ARG(QVariant, this->title()), + Q_ARG(QVariant, QVariant::fromValue(component))); + + m_view = qvariant_cast(returnValue); + } + catch (dev::Exception const& exception){ + qDebug() << exception.what(); + } +} + diff --git a/mix/Feature.h b/mix/Feature.h new file mode 100644 index 000000000..5a51f928d --- /dev/null +++ b/mix/Feature.h @@ -0,0 +1,21 @@ +#ifndef FEATURE_H +#define FEATURE_H + +#include +#include + +class Feature : public QObject +{ + Q_OBJECT + +public: + Feature(); + virtual QString tabUrl() { return ""; } + virtual QString title() { return ""; } + void addContentOn(QObject* tabView); + +protected: + QObject* m_view; +}; + +#endif // FEATURE_H diff --git a/mix/MainContent.qml b/mix/MainContent.qml new file mode 100644 index 000000000..d1170b185 --- /dev/null +++ b/mix/MainContent.qml @@ -0,0 +1,47 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.0 +import QtQuick.Controls.Styles 1.2 +import CodeEditorExtensionManager 1.0 + +Rectangle { + anchors.fill: parent + height: parent.height + width: parent.width; + id:root + SplitView { + anchors.fill: parent + orientation: Qt.Vertical + Rectangle { + anchors.top : parent.top + id: contentView + width: parent.width + height: parent.height * 0.7 + TextArea { + id: codeEditor + height: parent.height + font.family: "Verdana" + font.pointSize: 9 + width: parent.width + anchors.centerIn: parent + } + } + Rectangle { + anchors.bottom: parent.bottom + id: contextualView + width: parent.width + Layout.minimumHeight: 20 + height: parent.height * 0.3 + TabView { + id: contextualTabs + antialiasing: true + anchors.fill: parent + style: TabStyle{} + } + } + CodeEditorExtensionManager{ + tabView: contextualTabs + editor: codeEditor + } + } +} diff --git a/mix/Qt47supp.txt b/mix/Qt47supp.txt new file mode 100644 index 000000000..1da4f51bf --- /dev/null +++ b/mix/Qt47supp.txt @@ -0,0 +1,29 @@ +{ + + Memcheck:Cond + fun:_ZN20QSharedMemoryPrivate6detachEv + fun:_ZN13QSharedMemory6detachEv + fun:_ZN13QSharedMemory6setKeyERK7QString + fun:_ZN13QSharedMemoryD1Ev + fun:_ZN20QRasterWindowSurface5flushEP7QWidgetRK7QRegionRK6QPoint + fun:_Z8qt_flushP7QWidgetRK7QRegionP14QWindowSurfaceS0_RK6QPoint + fun:_ZN19QWidgetBackingStore5flushEP7QWidgetP14QWindowSurface + fun:_ZN19QWidgetBackingStore8endPaintERK7QRegionP14QWindowSurfaceP14BeginPaintInfo + fun:_ZN19QWidgetBackingStore4syncEv + fun:_ZN14QWidgetPrivate16syncBackingStoreEv + fun:_ZN7QWidget5eventEP6QEvent + fun:_ZN11QMainWindow5eventEP6QEvent +} +{ + + Memcheck:Leak + fun:_Znwm + fun:_ZN18QtSimulatorPrivate15connectToServerEv + fun:_ZN18QtSimulatorPrivate19SimulatorConnection18connectToSimulatorEv + fun:_ZN18QtSimulatorPrivate19SimulatorConnection8instanceEv + fun:_ZN9QColormap10initializeEv + fun:_Z7qt_initP19QApplicationPrivatei + fun:_ZN19QApplicationPrivate9constructEv + fun:_ZN12QApplicationC1ERiPPci + fun:main +} diff --git a/mix/TabStyle.qml b/mix/TabStyle.qml new file mode 100644 index 000000000..df31f9910 --- /dev/null +++ b/mix/TabStyle.qml @@ -0,0 +1,24 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 + +TabViewStyle { + frameOverlap: 1 + tabBar: Rectangle { + color: "lightgray" + } + tab: Rectangle { + + color: "lightsteelblue" + implicitWidth: Math.max(text.width + 4, 80) + implicitHeight: 20 + radius: 2 + Text { + id: text + anchors.centerIn: parent + text: styleData.title + color: styleData.selected ? "white" : "black" + } + } + frame: Rectangle { color: "steelblue" } +} diff --git a/mix/main.cpp b/mix/main.cpp new file mode 100644 index 000000000..3aa0cb85a --- /dev/null +++ b/mix/main.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include "CodeEditorExtensionMan.h" +#include "ApplicationContext.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QQmlApplicationEngine* engine = new QQmlApplicationEngine(); + qmlRegisterType("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager"); + + ApplicationContext::SetApplicationContext(engine); + QObject::connect(&app, SIGNAL(lastWindowClosed()), ApplicationContext::GetInstance(), SLOT(QuitApplication())); //use to kill ApplicationContext and other stuff + + engine->load(QUrl(QStringLiteral("qrc:/main.qml"))); + return app.exec(); +} + diff --git a/mix/main.qml b/mix/main.qml new file mode 100644 index 000000000..6486c1dfd --- /dev/null +++ b/mix/main.qml @@ -0,0 +1,27 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +import CodeEditorExtensionManager 1.0 + +ApplicationWindow { + + visible: true + width: 1000 + height: 480 + minimumWidth: 400 + minimumHeight: 300 + title: qsTr("mix") + + menuBar: MenuBar { + Menu { + title: qsTr("File") + MenuItem { + text: qsTr("Exit") + onTriggered: Qt.quit(); + } + } + } + + MainContent{ + } +} diff --git a/mix/mix.pro b/mix/mix.pro new file mode 100644 index 000000000..6595db37f --- /dev/null +++ b/mix/mix.pro @@ -0,0 +1,19 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp \ + CodeEditorExtensionManager.cpp \ + ConstantCompilation.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + +HEADERS += \ + CodeEditorExtensionManager.h \ + ConstantCompilation.h diff --git a/mix/qml.qrc b/mix/qml.qrc new file mode 100644 index 000000000..65dc7f826 --- /dev/null +++ b/mix/qml.qrc @@ -0,0 +1,8 @@ + + + main.qml + BasicContent.qml + TabStyle.qml + MainContent.qml + +