You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

375 lines
8.6 KiB

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
import QtQuick.Dialogs 1.1
import Qt.labs.settings 1.0
Item {
id: codeEditorView
property string currentDocumentId: ""
property string sourceInError
10 years ago
property int openDocCount: 0
signal documentEdit(string documentId)
10 years ago
signal breakpointsChanged(string documentId)
signal isCleanChanged(var isClean, string documentId)
signal loadComplete
function getDocumentText(documentId) {
10 years ago
for (var i = 0; i < openDocCount; i++) {
if (editorListModel.get(i).documentId === documentId) {
return editors.itemAt(i).item.getText();
}
}
return "";
}
function isDocumentOpen(documentId) {
10 years ago
for (var i = 0; i < openDocCount; i++)
if (editorListModel.get(i).documentId === documentId &&
editors.itemAt(i).item)
return true;
return false;
}
function openDocument(document) {
loadDocument(document);
currentDocumentId = document.documentId;
}
function loadDocument(document) {
10 years ago
for (var i = 0; i < openDocCount; i++)
if (editorListModel.get(i).documentId === document.documentId)
return; //already open
10 years ago
if (editorListModel.count <= openDocCount)
editorListModel.append(document);
else
{
editorListModel.set(openDocCount, document);
doLoadDocument(editors.itemAt(openDocCount).item, editorListModel.get(openDocCount), false)
loadComplete();
10 years ago
}
openDocCount++;
}
function doLoadDocument(editor, document, create) {
var data = fileIo.readFile(document.path);
if (create)
{
editor.onLoadComplete.connect(function() {
codeEditorView.loadComplete();
});
editor.onEditorTextChanged.connect(function() {
documentEdit(editor.document.documentId);
if (editor.document.isContract)
codeModel.registerCodeChange(editor.document.documentId, editor.getText());
});
editor.onBreakpointsChanged.connect(function() {
if (editor.document.isContract)
breakpointsChanged(editor.document.documentId);
});
editor.onIsCleanChanged.connect(function() {
isCleanChanged(editor.isClean, editor.document.documentId);
});
}
editor.document = document;
editor.setFontSize(editorSettings.fontSize);
10 years ago
editor.sourceName = document.documentId;
editor.setText(data, document.syntaxMode);
editor.changeGeneration();
}
10 years ago
function getEditor(documentId) {
10 years ago
for (var i = 0; i < openDocCount; i++)
{
10 years ago
if (editorListModel.get(i).documentId === documentId)
return editors.itemAt(i).item;
}
10 years ago
return null;
}
function highlightExecution(documentId, location)
{
10 years ago
var editor = getEditor(documentId);
if (editor)
{
if (documentId !== location.sourceName)
findAndHightlight(location.start, location.end, location.sourceName)
else
editor.highlightExecution(location);
}
}
// Execution is not in the current document. Try:
// Open targeted document and hightlight (TODO) or
// Warn user that file is not available
function findAndHightlight(start, end, sourceName)
{
var editor = getEditor(currentDocumentId);
if (editor)
editor.showWarning(qsTr("Currently debugging in " + sourceName + ". Source not available."));
10 years ago
}
function editingContract() {
10 years ago
for (var i = 0; i < openDocCount; i++)
10 years ago
if (editorListModel.get(i).documentId === currentDocumentId)
return editorListModel.get(i).isContract;
return false;
}
function getBreakpoints() {
var bpMap = {};
10 years ago
for (var i = 0; i < openDocCount; i++) {
10 years ago
var documentId = editorListModel.get(i).documentId;
var editor = editors.itemAt(i).item;
if (editor) {
bpMap[documentId] = editor.getBreakpoints();
}
10 years ago
}
return bpMap;
}
function toggleBreakpoint() {
var editor = getEditor(currentDocumentId);
if (editor)
editor.toggleBreakpoint();
}
function resetEditStatus(docId) {
var editor = getEditor(docId);
if (editor)
editor.changeGeneration();
}
10 years ago
function goToCompilationError() {
if (sourceInError === "")
return;
if (currentDocumentId !== sourceInError)
projectModel.openDocument(sourceInError);
10 years ago
for (var i = 0; i < openDocCount; i++)
{
var doc = editorListModel.get(i);
if (doc.isContract && doc.documentId === sourceInError)
10 years ago
{
var editor = editors.itemAt(i).item;
if (editor)
editor.goToCompilationError();
break;
}
}
}
10 years ago
function setFontSize(size) {
if (size <= 10 || size >= 48)
return;
editorSettings.fontSize = size;
for (var i = 0; i < editors.count; i++)
editors.itemAt(i).item.setFontSize(size);
}
function displayGasEstimation(checked)
{
var editor = getEditor(currentDocumentId);
if (editor)
editor.displayGasEstimation(checked);
}
Component.onCompleted: projectModel.codeEditor = codeEditorView;
Connections {
target: codeModel
onCompilationError: {
sourceInError = _firstErrorLoc.source;
}
onCompilationComplete: {
sourceInError = "";
10 years ago
var gasCosts = codeModel.gasCostByDocumentId(currentDocumentId);
var editor = getEditor(currentDocumentId);
if (editor)
editor.setGasCosts(gasCosts);
}
}
Connections {
target: projectModel
onDocumentOpened: {
openDocument(document);
}
onProjectSaving: {
10 years ago
for (var i = 0; i < openDocCount; i++)
{
var doc = editorListModel.get(i);
if (editors.itemAt(i))
{
var editor = editors.itemAt(i).item;
if (editor)
fileIo.writeFile(doc.path, editor.getText());
}
10 years ago
}
}
onProjectSaved: {
10 years ago
if (projectModel.appIsClosing || projectModel.projectIsClosing)
10 years ago
return;
10 years ago
for (var i = 0; i < openDocCount; i++)
10 years ago
{
var doc = editorListModel.get(i);
resetEditStatus(doc.documentId);
}
}
onProjectClosed: {
currentDocumentId = "";
10 years ago
openDocCount = 0;
}
10 years ago
onDocumentSaved: {
resetEditStatus(documentId);
}
onContractSaved: {
resetEditStatus(documentId);
}
onDocumentSaving: {
for (var i = 0; i < editorListModel.count; i++)
{
var doc = editorListModel.get(i);
if (doc.path === document.path)
{
fileIo.writeFile(document.path, editors.itemAt(i).item.getText());
break;
}
}
}
}
CodeEditorStyle
{
id: style;
}
MessageDialog
{
id: messageDialog
title: qsTr("File Changed")
text: qsTr("This file has been changed outside of the editor. Do you want to reload it?")
standardButtons: StandardButton.Yes | StandardButton.No
property variant item
property variant doc
onYes: {
doLoadDocument(item, doc, false);
resetEditStatus(doc.documentId);
}
}
Repeater {
id: editors
model: editorListModel
onItemRemoved: {
item.item.unloaded = true;
}
delegate: Loader {
id: loader
active: false
asynchronous: true
anchors.fill: parent
source: appService.haveWebEngine ? "WebCodeEditor.qml" : "CodeEditor.qml"
visible: (index >= 0 && index < openDocCount && currentDocumentId === editorListModel.get(index).documentId)
property bool changed: false
onVisibleChanged: {
loadIfNotLoaded()
if (visible && item)
{
loader.item.setFocus();
if (changed)
{
changed = false;
messageDialog.item = loader.item;
messageDialog.doc = editorListModel.get(index);
messageDialog.open();
}
10 years ago
loader.item.displayGasEstimation(gasEstimationAction.checked);
}
}
Component.onCompleted: {
loadIfNotLoaded()
}
onLoaded: {
doLoadDocument(loader.item, editorListModel.get(index), true)
}
Connections
{
target: projectModel
onDocumentChanged: {
if (!item)
return;
var current = editorListModel.get(index);
if (documentId === current.documentId)
{
if (currentDocumentId === current.documentId)
{
messageDialog.item = loader.item;
messageDialog.doc = editorListModel.get(index);
messageDialog.open();
}
else
changed = true
}
}
onDocumentUpdated: {
var document = projectModel.getDocument(documentId);
for (var i = 0; i < editorListModel.count; i++)
if (editorListModel.get(i).documentId === documentId)
{
editorListModel.set(i, document);
break;
}
}
onDocumentRemoved: {
for (var i = 0; i < editorListModel.count; i++)
if (editorListModel.get(i).documentId === documentId)
{
editorListModel.remove(i);
openDocCount--;
break;
}
}
}
function loadIfNotLoaded () {
if (visible && !active) {
active = true;
}
}
}
}
ListModel {
id: editorListModel
}
Action {
id: increaseFontSize
text: qsTr("Increase Font Size")
shortcut: "Ctrl+="
onTriggered: setFontSize(editorSettings.fontSize + 1)
}
Action {
id: decreaseFontSize
text: qsTr("Decrease Font Size")
shortcut: "Ctrl+-"
onTriggered: setFontSize(editorSettings.fontSize - 1)
}
Settings {
id: editorSettings
property int fontSize: 12;
}
}