Browse Source

refactored code to use native qml object hierarchy instead of forcing

object properties from c++
cl-refactor
arkpar 10 years ago
parent
commit
b3d43bd511
  1. 122
      mix/AppContext.cpp
  2. 88
      mix/AppContext.h
  3. 26
      mix/ClientModel.cpp
  4. 10
      mix/ClientModel.h
  5. 39
      mix/Clipboard.cpp
  6. 29
      mix/Clipboard.h
  7. 88
      mix/CodeEditorExtensionManager.cpp
  8. 71
      mix/CodeEditorExtensionManager.h
  9. 3
      mix/CodeModel.cpp
  10. 2
      mix/CodeModel.h
  11. 82
      mix/Extension.cpp
  12. 75
      mix/Extension.h
  13. 42
      mix/MixApplication.cpp
  14. 4
      mix/MixApplication.h
  15. 3
      mix/QContractDefinition.cpp
  16. 4
      mix/qml/ContractLibrary.qml
  17. 2
      mix/qml/DebugInfoList.qml
  18. 2
      mix/qml/DeploymentDialog.qml
  19. 4
      mix/qml/LogsPane.qml
  20. 4
      mix/qml/MainContent.qml
  21. 5
      mix/qml/ProjectModel.qml
  22. 2
      mix/qml/TransactionLog.qml
  23. 4
      mix/qml/WebCodeEditor.qml
  24. 11
      mix/qml/WebPreview.qml
  25. 37
      mix/qml/main.qml

122
mix/AppContext.cpp

@ -1,122 +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 AppContext.cpp
* @author Yann yann@ethdev.com
* @date 2014
* Provides access to the current QQmlApplicationEngine which is used to add QML file on the fly.
* In the future this class can be extended to add more variable related to the context of the application.
* For now AppContext provides reference to:
* - QQmlApplicationEngine
* - dev::WebThreeDirect (and dev::eth::Client)
* - KeyEventManager
*/
#include <QMessageBox>
#include <QClipboard>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <QWindow>
#include "CodeModel.h"
#include "FileIo.h"
#include "ClientModel.h"
#include "CodeEditorExtensionManager.h"
#include "Exceptions.h"
#include "QEther.h"
#include "QVariableDefinition.h"
#include "HttpServer.h"
#include "AppContext.h"
#include "SortFilterProxyModel.h"
using namespace dev;
using namespace dev::eth;
using namespace dev::mix;
const QString c_projectFileName = "project.mix";
AppContext::AppContext(QQmlApplicationEngine* _engine)
{
m_applicationEngine = _engine;
m_codeModel.reset(new CodeModel(this));
m_clientModel.reset(new ClientModel(this));
m_fileIo.reset(new FileIo());
connect(QApplication::clipboard(), &QClipboard::dataChanged, [this] { emit clipboardChanged();});
}
AppContext::~AppContext()
{
}
void AppContext::load()
{
m_applicationEngine->rootContext()->setContextProperty("appContext", this);
QFont f;
m_applicationEngine->rootContext()->setContextProperty("systemPointSize", f.pointSize());
qmlRegisterType<FileIo>("org.ethereum.qml", 1, 0, "FileIo");
m_applicationEngine->rootContext()->setContextProperty("codeModel", m_codeModel.get());
m_applicationEngine->rootContext()->setContextProperty("fileIo", m_fileIo.get());
qmlRegisterType<QEther>("org.ethereum.qml.QEther", 1, 0, "QEther");
qmlRegisterType<QBigInt>("org.ethereum.qml.QBigInt", 1, 0, "QBigInt");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration");
qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry");
qmlRegisterType<SortFilterProxyModel>("org.ethereum.qml.SortFilterProxyModel", 1, 0, "SortFilterProxyModel");
qmlRegisterType<QSolidityType>("org.ethereum.qml.QSolidityType", 1, 0, "QSolidityType");
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>("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager");
qmlRegisterType<HttpServer>("HttpServer", 1, 0, "HttpServer");
m_applicationEngine->load(QUrl("qrc:/qml/main.qml"));
QWindow *window = qobject_cast<QWindow*>(m_applicationEngine->rootObjects().at(0));
window->setIcon(QIcon(":/res/mix_256x256x32.png"));
appLoaded();
}
QQmlApplicationEngine* AppContext::appEngine()
{
return m_applicationEngine;
}
void AppContext::displayMessageDialog(QString _title, QString _message)
{
// TODO : move to a UI dedicated layer.
QObject* dialogWin = m_applicationEngine->rootObjects().at(0)->findChild<QObject*>("alertMessageDialog", Qt::FindChildrenRecursively);
QObject* dialogWinComponent = m_applicationEngine->rootObjects().at(0)->findChild<QObject*>("alertMessageDialogContent", Qt::FindChildrenRecursively);
dialogWinComponent->setProperty("source", QString("qrc:/qml/BasicMessage.qml"));
dialogWin->setProperty("title", _title);
dialogWin->setProperty("width", "250");
dialogWin->setProperty("height", "100");
dialogWin->findChild<QObject*>("messageContent", Qt::FindChildrenRecursively)->setProperty("text", _message);
QMetaObject::invokeMethod(dialogWin, "open");
}
QString AppContext::clipboard() const
{
QClipboard *clipboard = QApplication::clipboard();
return clipboard->text();
}
void AppContext::toClipboard(QString _text)
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(_text);
}

88
mix/AppContext.h

@ -1,88 +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 AppContext.h
* @author Yann yann@ethdev.com
* @date 2014
* Provides access to the current QQmlApplicationEngine which is used to add QML file on the fly.
* In the future this class can be extended to add more variable related to the context of the application.
* For now AppContext provides reference to:
* - QQmlApplicationEngine
* - dev::WebThreeDirect (and dev::eth::Client)
* - KeyEventManager
*/
#pragma once
#include <memory>
#include <QUrl>
#include <QObject>
class QQmlApplicationEngine;
namespace dev
{
namespace mix
{
class CodeModel;
class ClientModel;
class FileIo;
/**
* @brief Provides access to application scope variable.
*/
class AppContext: public QObject
{
Q_OBJECT
Q_PROPERTY(QString clipboard READ clipboard WRITE toClipboard NOTIFY clipboardChanged)
public:
AppContext(QQmlApplicationEngine* _engine);
virtual ~AppContext();
/// Load the UI from qml files
void load();
/// Get the current QQMLApplicationEngine instance.
QQmlApplicationEngine* appEngine();
/// Get code model
CodeModel* codeModel() { return m_codeModel.get(); }
/// Get client model
ClientModel* clientModel() { return m_clientModel.get(); }
/// Display an alert message.
void displayMessageDialog(QString _title, QString _message);
/// Copy text to clipboard
Q_INVOKABLE void toClipboard(QString _text);
/// Get text from clipboard
QString clipboard() const;
signals:
/// Triggered once components have been loaded
void appLoaded();
void clipboardChanged();
private:
QQmlApplicationEngine* m_applicationEngine; //owned by app
std::unique_ptr<CodeModel> m_codeModel;
std::unique_ptr<ClientModel> m_clientModel;
std::unique_ptr<FileIo> m_fileIo;
public slots:
/// Delete the current instance when application quit.
void quitApplication() {}
};
}
}

26
mix/ClientModel.cpp

@ -21,6 +21,7 @@
// Make sure boost/asio.hpp is included before windows.h.
#include <boost/asio.hpp>
#include "ClientModel.h"
#include <QtConcurrent/QtConcurrent>
#include <QDebug>
#include <QQmlContext>
@ -29,7 +30,6 @@
#include <jsonrpccpp/server.h>
#include <libethcore/CommonJS.h>
#include <libethereum/Transaction.h>
#include "AppContext.h"
#include "DebuggingStateWrapper.h"
#include "Exceptions.h"
#include "QContractDefinition.h"
@ -39,7 +39,6 @@
#include "CodeModel.h"
#include "QEther.h"
#include "Web3Server.h"
#include "ClientModel.h"
#include "MixClient.h"
using namespace dev;
@ -67,8 +66,8 @@ private:
};
ClientModel::ClientModel(AppContext* _context):
m_context(_context), m_running(false), m_rpcConnector(new RpcConnector())
ClientModel::ClientModel():
m_running(false), m_rpcConnector(new RpcConnector())
{
qRegisterMetaType<QBigInt*>("QBigInt*");
qRegisterMetaType<QVariableDefinition*>("QVariableDefinition*");
@ -87,7 +86,6 @@ ClientModel::ClientModel(AppContext* _context):
m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), m_client->userAccounts(), m_client.get()));
connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection);
_context->appEngine()->rootContext()->setContextProperty("clientModel", this);
}
ClientModel::~ClientModel()
@ -184,8 +182,8 @@ void ClientModel::setupState(QVariantMap _state)
}
else
{
if (contractId.isEmpty() && m_context->codeModel()->hasContract()) //TODO: This is to support old project files, remove later
contractId = m_context->codeModel()->contracts().keys()[0];
if (contractId.isEmpty() && m_codeModel->hasContract()) //TODO: This is to support old project files, remove later
contractId = m_codeModel->contracts().keys()[0];
TransactionSettings transactionSettings(contractId, functionId, value, gas, gasPrice, Secret(sender.toStdString()));
transactionSettings.parameterValues = transaction.value("parameters").toMap();
@ -220,7 +218,7 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
if (!transaction.stdContractUrl.isEmpty())
{
//std contract
dev::bytes const& stdContractCode = m_context->codeModel()->getStdContractCode(transaction.contractId, transaction.stdContractUrl);
dev::bytes const& stdContractCode = m_codeModel->getStdContractCode(transaction.contractId, transaction.stdContractUrl);
TransactionSettings stdTransaction = transaction;
stdTransaction.gas = 500000;// TODO: get this from std contracts library
Address address = deployContract(stdContractCode, stdTransaction);
@ -230,7 +228,7 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
else
{
//encode data
CompiledContract const& compilerRes = m_context->codeModel()->contract(transaction.contractId);
CompiledContract const& compilerRes = m_codeModel->contract(transaction.contractId);
QFunctionDefinition const* f = nullptr;
bytes contractCode = compilerRes.bytes();
std::shared_ptr<QContractDefinition> contractDef = compilerRes.sharedContract();
@ -320,7 +318,7 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t)
auto nameIter = m_contractNames.find(code.address);
if (nameIter != m_contractNames.end())
{
CompiledContract const& compilerRes = m_context->codeModel()->contract(nameIter->second);
CompiledContract const& compilerRes = m_codeModel->contract(nameIter->second);
eth::AssemblyItems assemblyItems = !_t.isConstructor() ? compilerRes.assemblyItems() : compilerRes.constructorAssemblyItems();
codes.back()->setDocument(compilerRes.documentId());
codeItems.push_back(std::move(assemblyItems));
@ -439,12 +437,6 @@ void ClientModel::debugRecord(unsigned _index)
showDebuggerForTransaction(e);
}
void ClientModel::showDebugError(QString const& _error)
{
//TODO: change that to a signal
m_context->displayMessageDialog(tr("Debugger"), _error);
}
Address ClientModel::deployContract(bytes const& _code, TransactionSettings const& _ctrTransaction)
{
Address newAddress = m_client->transact(_ctrTransaction.sender, _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice);
@ -527,7 +519,7 @@ void ClientModel::onNewTransaction()
auto contractAddressIter = m_contractNames.find(contractAddress);
if (contractAddressIter != m_contractNames.end())
{
CompiledContract const& compilerRes = m_context->codeModel()->contract(contractAddressIter->second);
CompiledContract const& compilerRes = m_codeModel->contract(contractAddressIter->second);
const QContractDefinition* def = compilerRes.contract();
contract = def->name();
if (abi)

10
mix/ClientModel.h

@ -34,13 +34,13 @@ namespace dev
namespace mix
{
class AppContext;
class Web3Server;
class RpcConnector;
class QEther;
class QDebugData;
class MixClient;
class QVariableDefinition;
class CodeModel;
struct SolidityType;
/// Backend transaction config class
@ -127,7 +127,7 @@ class ClientModel: public QObject
Q_OBJECT
public:
ClientModel(AppContext* _context);
ClientModel();
~ClientModel();
/// @returns true if currently executing contract code
Q_PROPERTY(bool running MEMBER m_running NOTIFY runStateChanged)
@ -143,6 +143,8 @@ public:
Q_INVOKABLE QString apiCall(QString const& _message);
/// Simulate mining. Creates a new block
Q_INVOKABLE void mine();
/// Get/set code model. Should be set from qml
Q_PROPERTY(CodeModel* codeModel MEMBER m_codeModel)
public slots:
/// Setup state, run transaction sequence, show debugger for the last transaction
@ -157,8 +159,6 @@ public slots:
private slots:
/// Update UI with machine states result. Display a modal dialog.
void showDebugger();
/// Update UI with transaction run error.
void showDebugError(QString const& _error);
signals:
/// Transaction execution started
@ -201,7 +201,6 @@ private:
void showDebuggerForTransaction(ExecutionResult const& _t);
QVariant formatValue(SolidityType const& _type, dev::u256 const& _value);
AppContext* m_context;
std::atomic<bool> m_running;
std::atomic<bool> m_mining;
std::unique_ptr<MixClient> m_client;
@ -211,6 +210,7 @@ private:
std::map<Address, QString> m_contractNames;
std::map<QString, Address> m_stdContractAddresses;
std::map<Address, QString> m_stdContractNames;
CodeModel* m_codeModel = nullptr;
};
}

39
mix/StatusPane.cpp → mix/Clipboard.cpp

@ -1,55 +1,40 @@
/*
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 ConstantCompilationControl.cpp
/** @file Clipboard.cpp
* @author Yann yann@ethdev.com
* @date 2014
* Ethereum IDE client.
* @date 2015
*/
#include <QQmlContext>
#include <QQuickItem>
#include <QtCore/QFileInfo>
#include "Clipboard.h"
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtCore/QtCore>
#include <QDebug>
#include "StatusPane.h"
#include "QContractDefinition.h"
#include "AppContext.h"
#include "CodeModel.h"
#include <QClipboard>
using namespace dev::mix;
StatusPane::StatusPane(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::HeaderView)
Clipboard::Clipboard()
{
_context->appEngine()->rootContext()->setContextProperty("statusPane", this);
connect(QApplication::clipboard(), &QClipboard::dataChanged, [this] { emit clipboardChanged();});
}
QString StatusPane::contentUrl() const
QString Clipboard::text() const
{
return QStringLiteral("qrc:/qml/StatusPane.qml");
QClipboard *clipboard = QApplication::clipboard();
return clipboard->text();
}
QString StatusPane::title() const
void Clipboard::setText(QString _text)
{
return QApplication::tr("compiler");
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(_text);
}
void StatusPane::start() const
{
}

29
mix/StatusPane.h → mix/Clipboard.h

@ -1,25 +1,27 @@
/*
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 ConstantCompilationControl.h
/** @file Clipboard.h
* @author Yann yann@ethdev.com
* @date 2014
* Ethereum IDE client.
* @date 2015
*/
#pragma once
#include "Extension.h"
#include <QObject>
namespace dev
{
@ -27,20 +29,23 @@ namespace mix
{
/**
* @brief Extension which display assembly code of the contract being edited.
* @brief Provides access to system clipboard
*/
class StatusPane: public Extension
class Clipboard: public QObject
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY clipboardChanged)
public:
StatusPane(AppContext* _appContext);
~StatusPane() {}
void start() const override;
QString title() const override;
QString contentUrl() const override;
Clipboard();
/// Copy text to clipboard
void setText(QString _text);
/// Get text from clipboard
QString text() const;
public slots:
signals:
void clipboardChanged();
};
}

88
mix/CodeEditorExtensionManager.cpp

@ -1,88 +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 CodeEditorExtensionManager.cpp
* @author Yann yann@ethdev.com
* @date 2014
* Ethereum IDE client.
*/
#include <QQuickItem>
#include <QGraphicsObject>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQuickTextDocument>
#include "StatusPane.h"
#include "AppContext.h"
#include "MixApplication.h"
#include "CodeModel.h"
#include "ClientModel.h"
#include "CodeHighlighter.h"
#include "CodeEditorExtensionManager.h"
using namespace dev::mix;
CodeEditorExtensionManager::CodeEditorExtensionManager():
m_appContext(static_cast<MixApplication*>(QApplication::instance())->context())
{
}
CodeEditorExtensionManager::~CodeEditorExtensionManager()
{
m_features.clear();
}
void CodeEditorExtensionManager::loadEditor(QQuickItem* _editor)
{
if (!_editor)
return;
}
void CodeEditorExtensionManager::initExtension(std::shared_ptr<Extension> _ext)
{
if (!_ext->contentUrl().isEmpty())
{
try
{
if (_ext->getDisplayBehavior() == ExtensionDisplayBehavior::RightView)
_ext->addTabOn(m_rightView);
if (_ext->getDisplayBehavior() == ExtensionDisplayBehavior::HeaderView)
_ext->addTabOn(m_headerView);
}
catch (...)
{
qDebug() << "Exception when adding tab into view.";
return;
}
}
_ext->start();
m_features.append(_ext);
}
void CodeEditorExtensionManager::applyCodeHighlight()
{
//TODO: reimplement
}
void CodeEditorExtensionManager::setRightView(QQuickItem* _rightView)
{
m_rightView = _rightView;
}
void CodeEditorExtensionManager::setHeaderView(QQuickItem* _headerView)
{
m_headerView = _headerView;
}

71
mix/CodeEditorExtensionManager.h

@ -1,71 +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 CodeEditorExtensionManager.h
* @author Yann yann@ethdev.com
* @date 2014
* Ethereum IDE client.
*/
#pragma once
#include <memory>
#include <QQuickItem>
#include <QTextDocument>
#include <QVector>
#include "StatusPane.h"
namespace dev
{
namespace mix
{
class AppContext;
/**
* @brief Init and provides connection between extensions.
*/
class CodeEditorExtensionManager: public QObject
{
Q_OBJECT
Q_PROPERTY(QQuickItem* headerView MEMBER m_headerView WRITE setHeaderView)
Q_PROPERTY(QQuickItem* rightView MEMBER m_rightView WRITE setRightView)
public:
CodeEditorExtensionManager();
~CodeEditorExtensionManager();
/// Initialize extension.
void initExtension(std::shared_ptr<Extension>);
/// Set current tab view
void setHeaderView(QQuickItem*);
/// Set current right tab view.
void setRightView(QQuickItem*);
private slots:
void applyCodeHighlight();
private:
QVector<std::shared_ptr<Extension>> m_features;
QQuickItem* m_headerView;
QQuickItem* m_rightView;
AppContext* m_appContext;
void loadEditor(QQuickItem* _editor);
};
}
}

3
mix/CodeModel.cpp

@ -129,8 +129,7 @@ QString CompiledContract::codeHex() const
return QString::fromStdString(toJS(m_bytes));
}
CodeModel::CodeModel(QObject* _parent):
QObject(_parent),
CodeModel::CodeModel():
m_compiling(false),
m_codeHighlighterSettings(new CodeHighlighterSettings()),
m_backgroundWorker(this),

2
mix/CodeModel.h

@ -125,7 +125,7 @@ class CodeModel: public QObject
Q_OBJECT
public:
CodeModel(QObject* _parent);
CodeModel();
~CodeModel();
Q_PROPERTY(QVariantMap contracts READ contracts NOTIFY codeChanged)

82
mix/Extension.cpp

@ -1,82 +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 Extension.cpp
* @author Yann yann@ethdev.com
* @date 2014
* Ethereum IDE client.
*/
#include <QMessageBox>
#include <QDebug>
#include <QQmlApplicationEngine>
#include <libevm/VM.h>
#include <libwebthree/WebThree.h>
#include "Extension.h"
#include "AppContext.h"
using namespace dev;
using namespace dev::mix;
Extension::Extension(AppContext* _context)
{
init(_context);
}
Extension::Extension(AppContext* _context, ExtensionDisplayBehavior _displayBehavior)
{
init(_context);
m_displayBehavior = _displayBehavior;
}
void Extension::init(AppContext* _context)
{
m_ctx = _context;
m_appEngine = m_ctx->appEngine();
}
void Extension::addTabOn(QObject* _view)
{
if (contentUrl() == "")
return;
QVariant returnValue;
QQmlComponent* component = new QQmlComponent(
m_appEngine,
QUrl(contentUrl()), _view);
QMetaObject::invokeMethod(_view, "addTab",
Q_RETURN_ARG(QVariant, returnValue),
Q_ARG(QVariant, this->title()),
Q_ARG(QVariant, QVariant::fromValue(component)));
m_view = qvariant_cast<QObject*>(returnValue);
}
void Extension::addContentOn(QObject* _view)
{
Q_UNUSED(_view);
if (m_displayBehavior == ExtensionDisplayBehavior::ModalDialog)
{
QQmlComponent* component = new QQmlComponent(m_appEngine, QUrl(contentUrl()), _view);
QObject* dialogWin = m_appEngine->rootObjects().at(0)->findChild<QObject*>("dialog", Qt::FindChildrenRecursively);
QObject* dialogWinComponent = m_appEngine->rootObjects().at(0)->findChild<QObject*>("modalDialogContent", Qt::FindChildrenRecursively);
dialogWinComponent->setProperty("sourceComponent", QVariant::fromValue(component));
dialogWin->setProperty("title", title());
QMetaObject::invokeMethod(dialogWin, "open");
}
//TODO add more view type.
}

75
mix/Extension.h

@ -1,75 +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 Extension.h
* @author Yann yann@ethdev.com
* @date 2014
* Ethereum IDE client.
*/
#pragma once
#include <QApplication>
#include <QQmlComponent>
class QQmlApplicationEngine;
namespace dev
{
namespace mix
{
class AppContext;
enum ExtensionDisplayBehavior
{
HeaderView,
RightView,
ModalDialog
};
class Extension: public QObject
{
Q_OBJECT
public:
Extension(AppContext* _context);
Extension(AppContext* _context, ExtensionDisplayBehavior _displayBehavior);
/// Return the QML url of the view to display.
virtual QString contentUrl() const { return ""; }
/// Return the title of this extension.
virtual QString title() const { return ""; }
/// Initialize extension.
virtual void start() const {}
/// Add the view define in contentUrl() in the _view QObject.
void addContentOn(QObject* _view);
/// Add the view define in contentUrl() in the _view QObject (_view has to be a tab).
void addTabOn(QObject* _view);
/// Modify the display behavior of this extension.
void setDisplayBehavior(ExtensionDisplayBehavior _displayBehavior) { m_displayBehavior = _displayBehavior; }
/// Get the display behavior of thi extension.
ExtensionDisplayBehavior getDisplayBehavior() { return m_displayBehavior; }
protected:
QObject* m_view;
ExtensionDisplayBehavior m_displayBehavior;
AppContext* m_ctx;
QQmlApplicationEngine* m_appEngine;
private:
void init(AppContext* _context);
};
}
}

42
mix/MixApplication.cpp

@ -19,22 +19,26 @@
* @date 2014
*/
#include <QDebug>
#include "MixApplication.h"
#include <QQmlApplicationEngine>
#include <QUrl>
#include <QIcon>
#ifdef ETH_HAVE_WEBENGINE
#include <QtWebEngine/QtWebEngine>
#endif
#include "MixApplication.h"
#include "AppContext.h"
#include <QMenuBar>
#include "CodeModel.h"
#include "ClientModel.h"
#include "FileIo.h"
#include "QEther.h"
#include "QVariableDeclaration.h"
#include "SortFilterProxyModel.h"
#include "Clipboard.h"
#include "HttpServer.h"
using namespace dev::mix;
MixApplication::MixApplication(int& _argc, char* _argv[]):
QApplication(_argc, _argv), m_engine(new QQmlApplicationEngine()), m_appContext(new AppContext(m_engine.get()))
QApplication(_argc, _argv), m_engine(new QQmlApplicationEngine())
{
setOrganizationName(tr("Ethereum"));
setOrganizationDomain(tr("ethereum.org"));
@ -43,8 +47,26 @@ MixApplication::MixApplication(int& _argc, char* _argv[]):
#ifdef ETH_HAVE_WEBENGINE
QtWebEngine::initialize();
#endif
QObject::connect(this, SIGNAL(lastWindowClosed()), context(), SLOT(quitApplication())); //use to kill ApplicationContext and other stuff
m_appContext->load();
QFont f;
m_engine->rootContext()->setContextProperty("systemPointSize", f.pointSize());
qmlRegisterType<CodeModel>("org.ethereum.qml.CodeModel", 1, 0, "CodeModel");
qmlRegisterType<ClientModel>("org.ethereum.qml.ClientModel", 1, 0, "ClientModel");
qmlRegisterType<FileIo>("org.ethereum.qml.FileIo", 1, 0, "FileIo");
qmlRegisterType<QEther>("org.ethereum.qml.QEther", 1, 0, "QEther");
qmlRegisterType<QBigInt>("org.ethereum.qml.QBigInt", 1, 0, "QBigInt");
qmlRegisterType<QVariableDeclaration>("org.ethereum.qml.QVariableDeclaration", 1, 0, "QVariableDeclaration");
qmlRegisterType<RecordLogEntry>("org.ethereum.qml.RecordLogEntry", 1, 0, "RecordLogEntry");
qmlRegisterType<SortFilterProxyModel>("org.ethereum.qml.SortFilterProxyModel", 1, 0, "SortFilterProxyModel");
qmlRegisterType<QSolidityType>("org.ethereum.qml.QSolidityType", 1, 0, "QSolidityType");
qmlRegisterType<Clipboard>("org.ethereum.qml.Clipboard", 1, 0, "Clipboard");
qmlRegisterType<HttpServer>("HttpServer", 1, 0, "HttpServer");
qRegisterMetaType<CodeModel*>("CodeModel*");
qRegisterMetaType<ClientModel*>("ClientModel*");
m_engine->load(QUrl("qrc:/qml/main.qml"));
QWindow *window = qobject_cast<QWindow*>(m_engine->rootObjects().at(0));
window->setIcon(QIcon(":/res/mix_256x256x32.png"));
}
MixApplication::~MixApplication()

4
mix/MixApplication.h

@ -33,8 +33,6 @@ namespace dev
namespace mix
{
class AppContext;
class MixApplication: public QApplication
{
Q_OBJECT
@ -42,12 +40,10 @@ class MixApplication: public QApplication
public:
MixApplication(int& _argc, char* _argv[]);
virtual ~MixApplication();
AppContext* context() { return m_appContext.get(); }
QQmlApplicationEngine* engine() { return m_engine.get(); }
private:
std::unique_ptr<QQmlApplicationEngine> m_engine;
std::unique_ptr<AppContext> m_appContext;
};
}

3
mix/QContractDefinition.cpp

@ -21,14 +21,13 @@
#include <QObject>
#include "QContractDefinition.h"
#include <libsolidity/CompilerStack.h>
#include <libsolidity/AST.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/NameAndTypeResolver.h>
#include "AppContext.h"
#include "QContractDefinition.h"
using namespace dev::solidity;
using namespace dev::mix;

4
mix/qml/ContractLibrary.qml

@ -5,8 +5,8 @@ Item {
property alias model: contractListModel;
Connections {
target: appContext
Component.onCompleted: {
target: mainApplication
onLoaded: {
//TODO: load a list, dependencies, ets, from external files
contractListModel.append({

2
mix/qml/DebugInfoList.qml

@ -136,7 +136,7 @@ ColumnLayout {
var str = "";
for (var i = 0; i < listModel.length; i++)
str += listModel[i] + "\n";
appContext.toClipboard(str);
clipboard.text = str;
}
}

2
mix/qml/DeploymentDialog.qml

@ -223,7 +223,7 @@ Window {
enabled: deploymentDialog.packageBase64 !== ""
tooltip: qsTr("Copy Base64 conversion to ClipBoard")
onTriggered: {
appContext.toClipboard(deploymentDialog.packageBase64);
clipboard.text = deploymentDialog.packageBase64;
}
}

4
mix/qml/LogsPane.qml

@ -67,7 +67,7 @@ Rectangle
var log = logsModel.get(k);
content += log.type + "\t" + log.level + "\t" + log.date + "\t" + log.content + "\n";
}
appContext.toClipboard(content);
clipboard.text = content;
}
}
@ -207,7 +207,7 @@ Rectangle
{
var log = logsModel.get(logsTable.currentRow);
if (log)
appContext.toClipboard(log.type + "\t" + log.level + "\t" + log.date + "\t" + log.content);
clipboard.text = (log.type + "\t" + log.level + "\t" + log.date + "\t" + log.content);
}
model: SortFilterProxyModel {

4
mix/qml/MainContent.qml

@ -2,7 +2,6 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1
import CodeEditorExtensionManager 1.0
import Qt.labs.settings 1.0
import org.ethereum.qml.QEther 1.0
import "js/QEtherHelper.js" as QEtherHelper
@ -101,9 +100,6 @@ Rectangle {
rightView.displayCompilationErrorIfAny();
}
CodeEditorExtensionManager {
}
Settings {
id: mainSettings
property alias codeWebOrientation: codeWebSplitter.orientation

5
mix/qml/ProjectModel.qml

@ -69,8 +69,8 @@ Item {
function formatAppUrl() { ProjectModelCode.formatAppUrl(url); }
Connections {
target: appContext
onAppLoaded: {
target: mainApplication
onLoaded: {
if (projectSettings.lastProjectPath && projectSettings.lastProjectPath !== "")
projectModel.loadProject(projectSettings.lastProjectPath)
}
@ -173,7 +173,6 @@ Item {
{
target: projectModel
onProjectClosed: {
projectSettings.lastProjectPath = "";
projectPath = "";
}
}

2
mix/qml/TransactionLog.qml

@ -163,7 +163,7 @@ Item {
Keys.onPressed: {
if ((event.modifiers & Qt.ControlModifier) && event.key === Qt.Key_C && currentRow >=0 && currentRow < logTable.model.count) {
var item = logTable.model.get(currentRow);
appContext.toClipboard(item.returned);
clipboard.text = item.returned;
}
}
}

4
mix/qml/WebCodeEditor.qml

@ -34,7 +34,7 @@ Item {
function syncClipboard() {
if (Qt.platform.os == "osx") {
var text = appContext.clipboard;
var text = clipboard.text;
editorBrowser.runJavaScript("setClipboardBase64(\"" + Qt.btoa(text) + "\")");
}
}
@ -59,7 +59,7 @@ Item {
}
Connections {
target: appContext
target: clipboard
onClipboardChanged: syncClipboard()
}

11
mix/qml/WebPreview.qml

@ -58,16 +58,11 @@ Item {
function changePage() {
setPreviewUrl(urlInput.text);
/*if (pageCombo.currentIndex >= 0 && pageCombo.currentIndex < pageListModel.count) {
urlInput.text = httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId;
setPreviewUrl(httpServer.url + "/" + pageListModel.get(pageCombo.currentIndex).documentId);
} else {
setPreviewUrl("");
}*/
}
Connections {
target: appContext
onAppLoaded: {
target: mainApplication
onLoaded: {
//We need to load the container using file scheme so that web security would allow loading local files in iframe
var containerPage = fileIo.readFile("qrc:///qml/html/WebContainer.html");
webView.loadHtml(containerPage, httpServer.url + "/WebContainer.html")

37
mix/qml/main.qml

@ -7,9 +7,15 @@ import QtQuick.Window 2.1
import QtQuick.PrivateWidgets 1.1
import Qt.labs.settings 1.0
import org.ethereum.qml.QEther 1.0
import org.ethereum.qml.CodeModel 1.0
import org.ethereum.qml.ClientModel 1.0
import org.ethereum.qml.FileIo 1.0
import org.ethereum.qml.Clipboard 1.0
ApplicationWindow {
id: mainApplication
signal loaded;
visible: true
width: 1200
height: 800
@ -17,8 +23,28 @@ ApplicationWindow {
minimumHeight: 300
title: qsTr("Mix")
Connections
{
CodeModel {
id: codeModel
}
ClientModel {
id: clientModel
codeModel: codeModel
}
ProjectModel {
id: projectModel
}
FileIo {
id: fileIo
}
Clipboard {
id: clipboard
}
Connections {
target: mainApplication
onClosing:
{
@ -27,8 +53,11 @@ ApplicationWindow {
}
}
function close()
{
Component.onCompleted: {
loaded();
}
function close() {
projectModel.appIsClosing = true;
if (projectModel.projectPath !== "")
projectModel.closeProject(function() { Qt.quit(); })

Loading…
Cancel
Save