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("DeviceEvent", ClassInfo("DeviceEvent", {"id", "deviceId", "eventTypeId", "eventName"}, {}, {"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"}));
|
||||
|
||||
@ -27,6 +32,7 @@ CodeCompletion::CodeCompletion(QObject *parent):
|
||||
m_genericJsSyntax.insert("do", "do ");
|
||||
m_genericJsSyntax.insert("if", "if ");
|
||||
m_genericJsSyntax.insert("else", "else ");
|
||||
m_genericJsSyntax.insert("print", "print");
|
||||
|
||||
m_jsClasses.insert("console", ClassInfo("console", {}, {"log", "warn"}));
|
||||
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-]*");
|
||||
qDebug() << "block text" << blockText << stateNameExp.exactMatch(blockText);
|
||||
if (stateNameExp.exactMatch(blockText)) {
|
||||
BlockInfo info = getBlockInfo(m_cursor.position());
|
||||
qDebug() << "stateName block info" << info.name << info.properties;
|
||||
if (!info.properties.contains("deviceId")) {
|
||||
return;
|
||||
}
|
||||
@ -456,7 +464,6 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
|
||||
info.end = m_document->textDocument()->find("}", position).position();
|
||||
info.valid = true;
|
||||
|
||||
qDebug() << "Block strats at" << blockStart.position();
|
||||
|
||||
info.name = blockStart.block().text();
|
||||
info.name.remove(QRegExp(" *\\{"));
|
||||
@ -464,25 +471,27 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
|
||||
info.name.remove(QRegExp(".* "));
|
||||
}
|
||||
|
||||
qDebug() << "Block starts at" << blockStart.position() << "contents:" << blockStart.block().text();
|
||||
int childBlocks = 0;
|
||||
while (!blockStart.isNull() && blockStart.position() < position) {
|
||||
QTextCursor tmp = m_document->textDocument()->find(QRegExp("[{}\n]"), blockStart);
|
||||
if (tmp.selectedText() == "{") {
|
||||
blockStart = tmp;
|
||||
QString line = blockStart.block().text();
|
||||
if (line.endsWith("{")) {
|
||||
blockStart.movePosition(QTextCursor::NextBlock);
|
||||
childBlocks++;
|
||||
continue;
|
||||
}
|
||||
if (tmp.selectedText() == "}") {
|
||||
blockStart = tmp;
|
||||
if (line.trimmed().startsWith("}")) {
|
||||
blockStart.movePosition(QTextCursor::NextBlock);
|
||||
childBlocks--;
|
||||
continue;
|
||||
}
|
||||
// \n
|
||||
if (childBlocks > 0) { // Skip all stuff in child blocks
|
||||
blockStart = tmp;
|
||||
if (childBlocks > 1) { // Skip all stuff in child blocks
|
||||
blockStart.movePosition(QTextCursor::NextBlock);
|
||||
continue;
|
||||
}
|
||||
foreach (const QString &statement, blockStart.block().text().split(";")) {
|
||||
qDebug() << "Have statement" << statement;
|
||||
QStringList parts = statement.split(":");
|
||||
if (parts.length() != 2) {
|
||||
continue;
|
||||
@ -492,7 +501,7 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
|
||||
qDebug() << "inserting:" << propName << "->" << propValue;
|
||||
info.properties.insert(propName, propValue);
|
||||
}
|
||||
blockStart = tmp;
|
||||
blockStart.movePosition(QTextCursor::NextBlock);
|
||||
}
|
||||
|
||||
return info;
|
||||
|
||||
@ -124,11 +124,16 @@ void ScriptManager::onNotificationReceived(const QVariantMap ¶ms)
|
||||
Script *script = new Script(scriptMap.value("id").toUuid());
|
||||
script->setName(scriptMap.value("name").toString());
|
||||
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") {
|
||||
QUuid id = params.value("params").toMap().value("scriptId").toUuid();
|
||||
QUuid id = params.value("params").toMap().value("id").toUuid();
|
||||
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") {
|
||||
|
||||
@ -28,7 +28,7 @@ Page {
|
||||
RuleTemplatesFilterModel {
|
||||
id: ruleTemplatesModel
|
||||
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 }
|
||||
filterInterfaceNames: deviceClass ? deviceClass.interfaces : []
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ Page {
|
||||
|
||||
HeaderButton {
|
||||
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
|
||||
hoverEnabled: true
|
||||
ToolTip.text: qsTr("Deploy script")
|
||||
@ -90,6 +90,7 @@ Page {
|
||||
d.callId = -1;
|
||||
if (scriptError == "ScriptErrorNoError") {
|
||||
d.scriptId = scriptId;
|
||||
d.oldContent = scriptEdit.text;
|
||||
}
|
||||
errorModel.update(errors);
|
||||
}
|
||||
@ -97,8 +98,10 @@ Page {
|
||||
onEditScriptReply: {
|
||||
print("edit reply", id, d.callId)
|
||||
if (id == d.callId) {
|
||||
d.oldContent = scriptEdit.text;
|
||||
d.callId = -1;
|
||||
if (scriptError == "ScriptErrorNoError") {
|
||||
d.oldContent = scriptEdit.text;
|
||||
}
|
||||
errorModel.update(errors)
|
||||
}
|
||||
}
|
||||
@ -141,6 +144,7 @@ Page {
|
||||
|
||||
LineNumbers {
|
||||
id: lineNumbers
|
||||
textArea: scriptEdit
|
||||
}
|
||||
|
||||
TextArea.flickable: TextArea {
|
||||
@ -217,6 +221,20 @@ Page {
|
||||
completionBox.show();
|
||||
event.accepted = true;
|
||||
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
|
||||
@ -289,8 +307,7 @@ Page {
|
||||
delegate: Label {
|
||||
width: parent.width
|
||||
text: model.line + ":" + model.column + ": " + model.message
|
||||
font.pixelSize: app.extraSmallFont
|
||||
font.family: "Monospace"
|
||||
font: scriptEdit.font
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,8 +341,7 @@ Page {
|
||||
delegate: Label {
|
||||
width: parent.width
|
||||
text: model.message
|
||||
font.pixelSize: app.extraSmallFont
|
||||
font.family: "Monospace"
|
||||
font: scriptEdit.font
|
||||
color: model.type === "ScriptMessageTypeWarning" ? "red" : app.foregroundColor
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ Page {
|
||||
|
||||
Connections {
|
||||
target: engine.scriptManager
|
||||
onRemovScriptReply: {
|
||||
onRemoveScriptReply: {
|
||||
if (id == d.pendingAction) {
|
||||
d.pendingAction = -1;
|
||||
}
|
||||
@ -48,6 +48,17 @@ Page {
|
||||
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 {
|
||||
|
||||
@ -1,13 +1,21 @@
|
||||
import QtQuick 2.2
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.2
|
||||
|
||||
Rectangle {
|
||||
id: lineNumbers
|
||||
id: root
|
||||
|
||||
property TextArea textArea: null
|
||||
|
||||
FontMetrics {
|
||||
id: fontMetrics
|
||||
font: textArea.font
|
||||
}
|
||||
|
||||
width: {
|
||||
var ret = 10;
|
||||
var ret = fontMetrics.maximumCharacterWidth * 2;
|
||||
var tmp = scriptEdit.lineCount
|
||||
while (tmp >= 10) {
|
||||
ret += 10;
|
||||
ret += fontMetrics.maximumCharacterWidth;
|
||||
tmp /= 10;
|
||||
}
|
||||
return ret;
|
||||
@ -25,11 +33,11 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 8
|
||||
Repeater {
|
||||
model: scriptEdit.lineCount
|
||||
model: root.textArea.lineCount
|
||||
delegate: Rectangle {
|
||||
id: lineNumberDelegate
|
||||
width: parent.width
|
||||
height: scriptEdit.contentHeight / scriptEdit.lineCount
|
||||
height: root.textArea.contentHeight / root.textArea.lineCount
|
||||
color: hasError ? "#FF0000" : "transparent"
|
||||
readonly property bool hasError: errorModel.errorLines.indexOf(index + 1) >= 0
|
||||
Label {
|
||||
@ -38,8 +46,8 @@ Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 3
|
||||
text: index + 1
|
||||
font.pixelSize: scriptEdit.font.pixelSize
|
||||
font.family: scriptEdit.font.family
|
||||
font.pixelSize: root.textArea.font.pixelSize
|
||||
font.family: root.textArea.font.family
|
||||
font.weight: Font.Light
|
||||
color: lineNumberDelegate.hasError ? "#FFFFFF" : "#808080"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user