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.
290 lines
6.7 KiB
290 lines
6.7 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
|
|
|
|
Item {
|
|
id: codeEditorView
|
|
property string currentDocumentId: ""
|
|
property int openDocCount: 0
|
|
signal documentEdit(string documentId)
|
|
signal breakpointsChanged(string documentId)
|
|
signal isCleanChanged(var isClean, string documentId)
|
|
signal loadComplete
|
|
|
|
|
|
function getDocumentText(documentId) {
|
|
for (var i = 0; i < openDocCount; i++) {
|
|
if (editorListModel.get(i).documentId === documentId) {
|
|
return editors.itemAt(i).item.getText();
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
function isDocumentOpen(documentId) {
|
|
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) {
|
|
for (var i = 0; i < openDocCount; i++)
|
|
if (editorListModel.get(i).documentId === document.documentId)
|
|
return; //already open
|
|
|
|
if (editorListModel.count <= openDocCount)
|
|
editorListModel.append(document);
|
|
else
|
|
{
|
|
editorListModel.set(openDocCount, document);
|
|
editors.itemAt(openDocCount).visible = true;
|
|
doLoadDocument(editors.itemAt(openDocCount).item, editorListModel.get(openDocCount))
|
|
}
|
|
openDocCount++;
|
|
|
|
}
|
|
|
|
function doLoadDocument(editor, document) {
|
|
var data = fileIo.readFile(document.path);
|
|
editor.onLoadComplete.connect(function() {
|
|
loadComplete();
|
|
});
|
|
editor.onEditorTextChanged.connect(function() {
|
|
documentEdit(document.documentId);
|
|
if (document.isContract)
|
|
codeModel.registerCodeChange(document.documentId, editor.getText());
|
|
});
|
|
editor.onBreakpointsChanged.connect(function() {
|
|
if (document.isContract)
|
|
breakpointsChanged(document.documentId);
|
|
});
|
|
editor.setText(data, document.syntaxMode);
|
|
editor.onIsCleanChanged.connect(function() {
|
|
isCleanChanged(editor.isClean, document.documentId);
|
|
});
|
|
}
|
|
|
|
function getEditor(documentId) {
|
|
for (var i = 0; i < openDocCount; i++)
|
|
{
|
|
if (editorListModel.get(i).documentId === documentId)
|
|
return editors.itemAt(i).item;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function highlightExecution(documentId, location)
|
|
{
|
|
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."));
|
|
}
|
|
|
|
function editingContract() {
|
|
for (var i = 0; i < openDocCount; i++)
|
|
if (editorListModel.get(i).documentId === currentDocumentId)
|
|
return editorListModel.get(i).isContract;
|
|
return false;
|
|
}
|
|
|
|
function getBreakpoints() {
|
|
var bpMap = {};
|
|
for (var i = 0; i < openDocCount; i++) {
|
|
var documentId = editorListModel.get(i).documentId;
|
|
var editor = editors.itemAt(i).item;
|
|
if (editor) {
|
|
bpMap[documentId] = editor.getBreakpoints();
|
|
}
|
|
}
|
|
return bpMap;
|
|
}
|
|
|
|
function toggleBreakpoint() {
|
|
var editor = getEditor(currentDocumentId);
|
|
if (editor)
|
|
editor.toggleBreakpoint();
|
|
}
|
|
|
|
function resetEditStatus(docId) {
|
|
var editor = getEditor(docId);
|
|
if (editor)
|
|
editor.changeGeneration();
|
|
}
|
|
|
|
Component.onCompleted: projectModel.codeEditor = codeEditorView;
|
|
|
|
Connections {
|
|
target: projectModel
|
|
onDocumentOpened: {
|
|
openDocument(document);
|
|
}
|
|
|
|
onProjectSaving: {
|
|
for (var i = 0; i < openDocCount; i++)
|
|
{
|
|
var doc = editorListModel.get(i);
|
|
var editor = editors.itemAt(i).item;
|
|
if (editor)
|
|
fileIo.writeFile(doc.path, editor.getText());
|
|
}
|
|
}
|
|
|
|
onProjectSaved: {
|
|
if (projectModel.appIsClosing || projectModel.projectIsClosing)
|
|
return;
|
|
for (var i = 0; i < openDocCount; i++)
|
|
{
|
|
var doc = editorListModel.get(i);
|
|
resetEditStatus(doc.documentId);
|
|
}
|
|
}
|
|
|
|
onProjectClosed: {
|
|
for (var i = 0; i < editorListModel.count; i++)
|
|
editors.itemAt(i).visible = false;
|
|
//editorListModel.clear();
|
|
currentDocumentId = "";
|
|
openDocCount = 0;
|
|
}
|
|
|
|
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);
|
|
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 < editorListModel.count && 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();
|
|
}
|
|
}
|
|
}
|
|
Component.onCompleted: {
|
|
loadIfNotLoaded()
|
|
}
|
|
onLoaded: {
|
|
doLoadDocument(loader.item, editorListModel.get(index))
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
function loadIfNotLoaded () {
|
|
if (visible && !active) {
|
|
active = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ListModel {
|
|
id: editorListModel
|
|
}
|
|
}
|
|
|