some improvements in the scripting part
This commit is contained in:
parent
59047704ae
commit
e160ad9665
@ -15,6 +15,11 @@ CodeCompletion::CodeCompletion(QObject *parent):
|
|||||||
m_classes.insert("DeviceState", ClassInfo("DeviceState", {"id", "deviceId", "stateTypeId", "stateName", "value"}, {}, {"onValueChanged"}));
|
m_classes.insert("DeviceState", ClassInfo("DeviceState", {"id", "deviceId", "stateTypeId", "stateName", "value"}, {}, {"onValueChanged"}));
|
||||||
m_classes.insert("DeviceEvent", ClassInfo("DeviceEvent", {"id", "deviceId", "eventTypeId", "eventName"}, {}, {"onTriggered"}));
|
m_classes.insert("DeviceEvent", ClassInfo("DeviceEvent", {"id", "deviceId", "eventTypeId", "eventName"}, {}, {"onTriggered"}));
|
||||||
m_classes.insert("Timer", ClassInfo("Timer", {"id", "interval", "running", "repeat"}, {"start", "stop"}, {"onTriggered"}));
|
m_classes.insert("Timer", ClassInfo("Timer", {"id", "interval", "running", "repeat"}, {"start", "stop"}, {"onTriggered"}));
|
||||||
|
m_classes.insert("PropertyAnimation", ClassInfo("PropertyAnimation", {"id", "target", "targets", "property", "properties", "value", "from", "to", "easing", "exclude", "duration", "alwaysRunToEnd", "loops", "paused", "running"}, {"start", "stop", "pause", "resume", "complete"}, {"onStarted", "onStopped", "onFinished", "onRunningChanged"}));
|
||||||
|
m_classes.insert("ColorAnimation", ClassInfo("ColorAnimation", {"id", "target", "targets", "property", "properties", "value", "from", "to", "easing", "exclude", "duration", "alwaysRunToEnd", "loops", "paused", "running"}, {"start", "stop", "pause", "resume", "complete"}, {"onStarted", "onStopped", "onFinished", "onRunningChanged"}));
|
||||||
|
m_classes.insert("SequentialAnimation", ClassInfo("SequentialAnimation", {"id", "alwaysRunToEnd", "loops", "paused", "running"}, {"start", "stop", "pause", "resume", "complete"}, {"onStarted", "onStopped", "onFinished", "onRunningChanged"}));
|
||||||
|
m_classes.insert("ParallelAnimation", ClassInfo("ParallelAnimation", {"id", "alwaysRunToEnd", "loops", "paused", "running"}, {"start", "stop", "pause", "resume", "complete"}, {"onStarted", "onStopped", "onFinished", "onRunningChanged"}));
|
||||||
|
m_classes.insert("PauseAnimation", ClassInfo("PauseAnimation", {"id", "duration", "alwaysRunToEnd", "loops", "paused", "running"}, {"start", "stop", "pause", "resume", "complete"}, {"onStarted", "onStopped", "onFinished", "onRunningChanged"}));
|
||||||
|
|
||||||
m_attachedClasses.insert("Component", ClassInfo("Component", {}, {}, {"onCompleted", "onDestruction", "onDestroyed"}));
|
m_attachedClasses.insert("Component", ClassInfo("Component", {}, {}, {"onCompleted", "onDestruction", "onDestroyed"}));
|
||||||
|
|
||||||
@ -27,6 +32,7 @@ CodeCompletion::CodeCompletion(QObject *parent):
|
|||||||
m_genericJsSyntax.insert("do", "do ");
|
m_genericJsSyntax.insert("do", "do ");
|
||||||
m_genericJsSyntax.insert("if", "if ");
|
m_genericJsSyntax.insert("if", "if ");
|
||||||
m_genericJsSyntax.insert("else", "else ");
|
m_genericJsSyntax.insert("else", "else ");
|
||||||
|
m_genericJsSyntax.insert("print", "print");
|
||||||
|
|
||||||
m_jsClasses.insert("console", ClassInfo("console", {}, {"log", "warn"}));
|
m_jsClasses.insert("console", ClassInfo("console", {}, {"log", "warn"}));
|
||||||
m_jsClasses.insert("JSON", ClassInfo("JSON", {}, {"stringify", "parse", "hasOwnProperty", "isPrototypeOf", "toString", "valueOf", "toLocaleString", "propertyIsEnumerable"}));
|
m_jsClasses.insert("JSON", ClassInfo("JSON", {}, {"stringify", "parse", "hasOwnProperty", "isPrototypeOf", "toString", "valueOf", "toLocaleString", "propertyIsEnumerable"}));
|
||||||
@ -157,8 +163,10 @@ void CodeCompletion::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QRegExp stateNameExp(".*stateName: \"[a-zA-Z0-9-]*");
|
QRegExp stateNameExp(".*stateName: \"[a-zA-Z0-9-]*");
|
||||||
|
qDebug() << "block text" << blockText << stateNameExp.exactMatch(blockText);
|
||||||
if (stateNameExp.exactMatch(blockText)) {
|
if (stateNameExp.exactMatch(blockText)) {
|
||||||
BlockInfo info = getBlockInfo(m_cursor.position());
|
BlockInfo info = getBlockInfo(m_cursor.position());
|
||||||
|
qDebug() << "stateName block info" << info.name << info.properties;
|
||||||
if (!info.properties.contains("deviceId")) {
|
if (!info.properties.contains("deviceId")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -456,7 +464,6 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
|
|||||||
info.end = m_document->textDocument()->find("}", position).position();
|
info.end = m_document->textDocument()->find("}", position).position();
|
||||||
info.valid = true;
|
info.valid = true;
|
||||||
|
|
||||||
qDebug() << "Block strats at" << blockStart.position();
|
|
||||||
|
|
||||||
info.name = blockStart.block().text();
|
info.name = blockStart.block().text();
|
||||||
info.name.remove(QRegExp(" *\\{"));
|
info.name.remove(QRegExp(" *\\{"));
|
||||||
@ -464,25 +471,27 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
|
|||||||
info.name.remove(QRegExp(".* "));
|
info.name.remove(QRegExp(".* "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "Block starts at" << blockStart.position() << "contents:" << blockStart.block().text();
|
||||||
int childBlocks = 0;
|
int childBlocks = 0;
|
||||||
while (!blockStart.isNull() && blockStart.position() < position) {
|
while (!blockStart.isNull() && blockStart.position() < position) {
|
||||||
QTextCursor tmp = m_document->textDocument()->find(QRegExp("[{}\n]"), blockStart);
|
QString line = blockStart.block().text();
|
||||||
if (tmp.selectedText() == "{") {
|
if (line.endsWith("{")) {
|
||||||
blockStart = tmp;
|
blockStart.movePosition(QTextCursor::NextBlock);
|
||||||
childBlocks++;
|
childBlocks++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (tmp.selectedText() == "}") {
|
if (line.trimmed().startsWith("}")) {
|
||||||
blockStart = tmp;
|
blockStart.movePosition(QTextCursor::NextBlock);
|
||||||
childBlocks--;
|
childBlocks--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// \n
|
// \n
|
||||||
if (childBlocks > 0) { // Skip all stuff in child blocks
|
if (childBlocks > 1) { // Skip all stuff in child blocks
|
||||||
blockStart = tmp;
|
blockStart.movePosition(QTextCursor::NextBlock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach (const QString &statement, blockStart.block().text().split(";")) {
|
foreach (const QString &statement, blockStart.block().text().split(";")) {
|
||||||
|
qDebug() << "Have statement" << statement;
|
||||||
QStringList parts = statement.split(":");
|
QStringList parts = statement.split(":");
|
||||||
if (parts.length() != 2) {
|
if (parts.length() != 2) {
|
||||||
continue;
|
continue;
|
||||||
@ -492,7 +501,7 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
|
|||||||
qDebug() << "inserting:" << propName << "->" << propValue;
|
qDebug() << "inserting:" << propName << "->" << propValue;
|
||||||
info.properties.insert(propName, propValue);
|
info.properties.insert(propName, propValue);
|
||||||
}
|
}
|
||||||
blockStart = tmp;
|
blockStart.movePosition(QTextCursor::NextBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|||||||
@ -124,11 +124,16 @@ void ScriptManager::onNotificationReceived(const QVariantMap ¶ms)
|
|||||||
Script *script = new Script(scriptMap.value("id").toUuid());
|
Script *script = new Script(scriptMap.value("id").toUuid());
|
||||||
script->setName(scriptMap.value("name").toString());
|
script->setName(scriptMap.value("name").toString());
|
||||||
m_scripts->addScript(script);
|
m_scripts->addScript(script);
|
||||||
|
emit addScriptReply(params.value("id").toInt(),
|
||||||
|
params.value("params").toMap().value("scriptError").toString(),
|
||||||
|
params.value("params").toMap().value("scriptId").toUuid(),
|
||||||
|
params.value("params").toMap().value("errors").toStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (params.value("notification").toString() == "Scripts.ScriptRemoved") {
|
else if (params.value("notification").toString() == "Scripts.ScriptRemoved") {
|
||||||
QUuid id = params.value("params").toMap().value("scriptId").toUuid();
|
QUuid id = params.value("params").toMap().value("id").toUuid();
|
||||||
m_scripts->removeScript(id);
|
m_scripts->removeScript(id);
|
||||||
|
emit removeScriptReply(params.value("id").toInt(), params.value("params").toMap().value("scriptError").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (params.value("notification").toString() == "Scripts.ScriptChanged") {
|
else if (params.value("notification").toString() == "Scripts.ScriptChanged") {
|
||||||
|
|||||||
@ -28,7 +28,7 @@ Page {
|
|||||||
RuleTemplatesFilterModel {
|
RuleTemplatesFilterModel {
|
||||||
id: ruleTemplatesModel
|
id: ruleTemplatesModel
|
||||||
ruleTemplates: RuleTemplates {}
|
ruleTemplates: RuleTemplates {}
|
||||||
readonly property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(root.device.deviceClassId) : null
|
readonly property var deviceClass: root.device ? engine.deviceManager.deviceClasses.getDeviceClass(root.device.deviceClassId) : null
|
||||||
filterByDevices: DevicesProxy { engine: _engine }
|
filterByDevices: DevicesProxy { engine: _engine }
|
||||||
filterInterfaceNames: deviceClass ? deviceClass.interfaces : []
|
filterInterfaceNames: deviceClass ? deviceClass.interfaces : []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ Page {
|
|||||||
|
|
||||||
HeaderButton {
|
HeaderButton {
|
||||||
imageSource: "../images/save.svg"
|
imageSource: "../images/save.svg"
|
||||||
enabled: d.script.name !== nameTextField.text || d.oldContent !== scriptEdit.text
|
enabled: d.script && d.script.name !== nameTextField.text || d.oldContent !== scriptEdit.text
|
||||||
color: enabled ? app.accentColor : keyColor
|
color: enabled ? app.accentColor : keyColor
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
ToolTip.text: qsTr("Deploy script")
|
ToolTip.text: qsTr("Deploy script")
|
||||||
@ -90,6 +90,7 @@ Page {
|
|||||||
d.callId = -1;
|
d.callId = -1;
|
||||||
if (scriptError == "ScriptErrorNoError") {
|
if (scriptError == "ScriptErrorNoError") {
|
||||||
d.scriptId = scriptId;
|
d.scriptId = scriptId;
|
||||||
|
d.oldContent = scriptEdit.text;
|
||||||
}
|
}
|
||||||
errorModel.update(errors);
|
errorModel.update(errors);
|
||||||
}
|
}
|
||||||
@ -97,8 +98,10 @@ Page {
|
|||||||
onEditScriptReply: {
|
onEditScriptReply: {
|
||||||
print("edit reply", id, d.callId)
|
print("edit reply", id, d.callId)
|
||||||
if (id == d.callId) {
|
if (id == d.callId) {
|
||||||
d.oldContent = scriptEdit.text;
|
|
||||||
d.callId = -1;
|
d.callId = -1;
|
||||||
|
if (scriptError == "ScriptErrorNoError") {
|
||||||
|
d.oldContent = scriptEdit.text;
|
||||||
|
}
|
||||||
errorModel.update(errors)
|
errorModel.update(errors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,6 +144,7 @@ Page {
|
|||||||
|
|
||||||
LineNumbers {
|
LineNumbers {
|
||||||
id: lineNumbers
|
id: lineNumbers
|
||||||
|
textArea: scriptEdit
|
||||||
}
|
}
|
||||||
|
|
||||||
TextArea.flickable: TextArea {
|
TextArea.flickable: TextArea {
|
||||||
@ -217,6 +221,20 @@ Page {
|
|||||||
completionBox.show();
|
completionBox.show();
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
return;
|
return;
|
||||||
|
case Qt.Key_Plus:
|
||||||
|
if (event.modifiers & Qt.ControlModifier) {
|
||||||
|
scriptEdit.font.pixelSize++;
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt.Key_Minus:
|
||||||
|
if (event.modifiers & Qt.ControlModifier) {
|
||||||
|
scriptEdit.font.pixelSize--;
|
||||||
|
event.accepted = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Things to do only when we're autocompleting
|
// Things to do only when we're autocompleting
|
||||||
@ -289,8 +307,7 @@ Page {
|
|||||||
delegate: Label {
|
delegate: Label {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: model.line + ":" + model.column + ": " + model.message
|
text: model.line + ":" + model.column + ": " + model.message
|
||||||
font.pixelSize: app.extraSmallFont
|
font: scriptEdit.font
|
||||||
font.family: "Monospace"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,8 +341,7 @@ Page {
|
|||||||
delegate: Label {
|
delegate: Label {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: model.message
|
text: model.message
|
||||||
font.pixelSize: app.extraSmallFont
|
font: scriptEdit.font
|
||||||
font.family: "Monospace"
|
|
||||||
color: model.type === "ScriptMessageTypeWarning" ? "red" : app.foregroundColor
|
color: model.type === "ScriptMessageTypeWarning" ? "red" : app.foregroundColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ Page {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: engine.scriptManager
|
target: engine.scriptManager
|
||||||
onRemovScriptReply: {
|
onRemoveScriptReply: {
|
||||||
if (id == d.pendingAction) {
|
if (id == d.pendingAction) {
|
||||||
d.pendingAction = -1;
|
d.pendingAction = -1;
|
||||||
}
|
}
|
||||||
@ -48,6 +48,17 @@ Page {
|
|||||||
d.pendingAction = engine.scriptManager.removeScript(model.id);
|
d.pendingAction = engine.scriptManager.removeScript(model.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmptyViewPlaceholder {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
title: qsTr("No scripts are installed yet.")
|
||||||
|
text: qsTr("Press \"Add script\" to get started.")
|
||||||
|
imageSource: "../images/script.svg"
|
||||||
|
buttonText: qsTr("Add script")
|
||||||
|
onButtonClicked: {
|
||||||
|
pageStack.push("ScriptEditor.qml");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BusyOverlay {
|
BusyOverlay {
|
||||||
|
|||||||
@ -1,13 +1,21 @@
|
|||||||
import QtQuick 2.2
|
import QtQuick 2.4
|
||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: lineNumbers
|
id: root
|
||||||
|
|
||||||
|
property TextArea textArea: null
|
||||||
|
|
||||||
|
FontMetrics {
|
||||||
|
id: fontMetrics
|
||||||
|
font: textArea.font
|
||||||
|
}
|
||||||
|
|
||||||
width: {
|
width: {
|
||||||
var ret = 10;
|
var ret = fontMetrics.maximumCharacterWidth * 2;
|
||||||
var tmp = scriptEdit.lineCount
|
var tmp = scriptEdit.lineCount
|
||||||
while (tmp >= 10) {
|
while (tmp >= 10) {
|
||||||
ret += 10;
|
ret += fontMetrics.maximumCharacterWidth;
|
||||||
tmp /= 10;
|
tmp /= 10;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -25,11 +33,11 @@ Rectangle {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin: 8
|
anchors.topMargin: 8
|
||||||
Repeater {
|
Repeater {
|
||||||
model: scriptEdit.lineCount
|
model: root.textArea.lineCount
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: lineNumberDelegate
|
id: lineNumberDelegate
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: scriptEdit.contentHeight / scriptEdit.lineCount
|
height: root.textArea.contentHeight / root.textArea.lineCount
|
||||||
color: hasError ? "#FF0000" : "transparent"
|
color: hasError ? "#FF0000" : "transparent"
|
||||||
readonly property bool hasError: errorModel.errorLines.indexOf(index + 1) >= 0
|
readonly property bool hasError: errorModel.errorLines.indexOf(index + 1) >= 0
|
||||||
Label {
|
Label {
|
||||||
@ -38,8 +46,8 @@ Rectangle {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 3
|
anchors.rightMargin: 3
|
||||||
text: index + 1
|
text: index + 1
|
||||||
font.pixelSize: scriptEdit.font.pixelSize
|
font.pixelSize: root.textArea.font.pixelSize
|
||||||
font.family: scriptEdit.font.family
|
font.family: root.textArea.font.family
|
||||||
font.weight: Font.Light
|
font.weight: Font.Light
|
||||||
color: lineNumberDelegate.hasError ? "#FFFFFF" : "#808080"
|
color: lineNumberDelegate.hasError ? "#FFFFFF" : "#808080"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user