Autocomplete action parameters in script editor

This commit is contained in:
Michael Zanetti 2020-08-30 12:53:34 +02:00
parent f29d3ce2a0
commit 72fd175ea9
4 changed files with 83 additions and 17 deletions

View File

@ -43,7 +43,7 @@ DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
m_vendors(new Vendors(this)),
m_plugins(new Plugins(this)),
m_devices(new Devices(this)),
m_deviceClasses(new DeviceClasses(this)),
m_thingClasses(new DeviceClasses(this)),
m_ioConnections(new IOConnections(this)),
m_jsonClient(jsonclient)
{
@ -53,7 +53,7 @@ DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
void DeviceManager::clear()
{
m_devices->clearModel();
m_deviceClasses->clearModel();
m_thingClasses->clearModel();
m_vendors->clearModel();
m_plugins->clearModel();
m_ioConnections->clearModel();
@ -133,7 +133,12 @@ Devices *DeviceManager::things() const
DeviceClasses *DeviceManager::deviceClasses() const
{
return m_deviceClasses;
return m_thingClasses;
}
DeviceClasses *DeviceManager::thingClasses() const
{
return m_thingClasses;
}
IOConnections *DeviceManager::ioConnections() const
@ -170,7 +175,7 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
// qDebug() << "Device state changed for:" << dev->name() << "State name:" << dev->thingClass()->stateTypes()->getStateType(stateTyoeId) << "value:" << value;
dev->setStateValue(stateTyoeId, value);
} else if (notification == "Devices.DeviceAdded") {
Device *dev = JsonTypes::unpackDevice(this, data.value("params").toMap().value("device").toMap(), m_deviceClasses);
Device *dev = JsonTypes::unpackDevice(this, data.value("params").toMap().value("device").toMap(), m_thingClasses);
if (!dev) {
qWarning() << "Cannot parse json device:" << data;
return;
@ -200,7 +205,7 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
qWarning() << "Received a device changed notification for a device we don't know";
return;
}
if (!JsonTypes::unpackDevice(this, data.value("params").toMap().value("device").toMap(), m_deviceClasses, oldDevice)) {
if (!JsonTypes::unpackDevice(this, data.value("params").toMap().value("device").toMap(), m_thingClasses, oldDevice)) {
qWarning() << "Error parsing device changed notification";
return;
}
@ -279,7 +284,7 @@ void DeviceManager::getSupportedDevicesResponse(const QVariantMap &params)
QVariantList deviceClassList = params.value("params").toMap().value("deviceClasses").toList();
foreach (QVariant deviceClassVariant, deviceClassList) {
DeviceClass *deviceClass = JsonTypes::unpackDeviceClass(deviceClassVariant.toMap(), deviceClasses());
m_deviceClasses->addDeviceClass(deviceClass);
m_thingClasses->addDeviceClass(deviceClass);
}
}
m_jsonClient->sendCommand("Devices.GetConfiguredDevices", this, "getConfiguredDevicesResponse");
@ -333,7 +338,7 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap &params)
if (params.value("params").toMap().keys().contains("devices")) {
QVariantList deviceList = params.value("params").toMap().value("devices").toList();
foreach (QVariant deviceVariant, deviceList) {
Device *device = JsonTypes::unpackDevice(this, deviceVariant.toMap(), m_deviceClasses);
Device *device = JsonTypes::unpackDevice(this, deviceVariant.toMap(), m_thingClasses);
if (!device) {
qWarning() << "Error unpacking device" << deviceVariant.toMap().value("name").toString();
continue;
@ -378,7 +383,7 @@ void DeviceManager::addDeviceResponse(const QVariantMap &params)
qWarning() << "Failed to add the device:" << params.value("params").toMap().value("deviceError").toString();
} else if (params.value("params").toMap().keys().contains("device")) {
QVariantMap deviceVariant = params.value("params").toMap().value("device").toMap();
Device *device = JsonTypes::unpackDevice(this, deviceVariant, m_deviceClasses);
Device *device = JsonTypes::unpackDevice(this, deviceVariant, m_thingClasses);
if (!device) {
qWarning() << "Couldn't parse json in addDeviceResponse";
return;

View File

@ -81,6 +81,7 @@ public:
Devices* devices() const;
Devices* things() const;
DeviceClasses* deviceClasses() const;
DeviceClasses* thingClasses() const;
IOConnections* ioConnections() const;
bool fetchingData() const;
@ -156,7 +157,7 @@ private:
Vendors *m_vendors;
Plugins *m_plugins;
Devices *m_devices;
DeviceClasses *m_deviceClasses;
DeviceClasses *m_thingClasses;
IOConnections *m_ioConnections;
bool m_fetchingData = false;

View File

@ -427,7 +427,41 @@ void CodeCompletion::update()
entries.append(CompletionModel::Entry(property, property, "property"));
}
foreach (const QString &method, m_classes.value(type).methods) {
entries.append(CompletionModel::Entry(method + "(", method, "method", "", ")"));
QString paramString;
if (method == "execute") {
int blockposition = getBlockPosition(id);
qDebug() << "Blockposition:" << blockposition;
if (blockposition >= 0) {
BlockInfo info = getBlockInfo(blockposition);
qDebug() << "actionType" << info.properties.keys() << info.properties.value("actionName") << info.properties.value("actionTypeId");
if (info.valid) {
QString thingId = info.properties.value("thingId");
if (thingId.isEmpty()) {
thingId = info.properties.value("deviceId");
}
Device *d = m_engine->thingManager()->things()->getDevice(QUuid(thingId));
if (d) {
ActionType *at = nullptr;
if (info.properties.contains("actionTypeId")) {
at = d->thingClass()->actionTypes()->getActionType(info.properties.value("actionTypeId"));
} else if (info.properties.contains("actionName")) {
at = d->thingClass()->actionTypes()->findByName(info.properties.value("actionName"));
}
if (at) {
QStringList params;
QStringList nonEscapeTypes = {"Int", "Bool", "Double"};
for (int i = 0; i < at->paramTypes()->rowCount(); i++) {
ParamType *pt = at->paramTypes()->get(i);
QString escapeChar = nonEscapeTypes.contains(pt->type()) ? "" : "\"";
params.append("\"" + pt->name() + "\": " + escapeChar + pt->defaultValue().toString() + escapeChar);
}
paramString = "{" + params.join(", ") + "}";
}
}
}
}
}
entries.append(CompletionModel::Entry(method + "(", method, "method", "", paramString + ")"));
}
// Attached classes/properties
foreach (const QString &property, m_attachedClasses.value(id).properties) {
@ -537,6 +571,7 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
{
BlockInfo info;
// Find start of block
QTextCursor blockStart = m_document->textDocument()->find("{", position, QTextDocument::FindBackward);
QTextCursor blockEnd = m_document->textDocument()->find("}", position, QTextDocument::FindBackward);
while (blockEnd.position() > blockStart.position() && !blockStart.isNull()) {
@ -548,21 +583,26 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
return info;
}
// Find end of block
QTextCursor tmp = blockStart;
blockEnd = blockStart;
while (!tmp.isNull() && blockEnd >= tmp) {
tmp = m_document->textDocument()->find("{", tmp.position());
blockEnd = m_document->textDocument()->find("}", blockEnd.position());
}
info.start = blockStart.position();
info.end = m_document->textDocument()->find("}", position).position();
info.end = blockEnd.position(); //m_document->textDocument()->find("}", position).position();
info.valid = true;
qDebug() << "block name" << blockStart.block().text();
info.name = blockStart.block().text();
info.name.remove(QRegExp(" *\\{ *"));
qDebug() << "stripped klammer" << info.name;
while (info.name.contains(" ")) {
info.name.remove(QRegExp(".* "));
}
qDebug() << "final name" << info.name;
int childBlocks = 0;
while (!blockStart.isNull() && blockStart.position() < position) {
while (!blockStart.isNull() && blockStart.position() < info.end) {
QString line = blockStart.block().text();
if (line.endsWith("{")) {
childBlocks++;
@ -584,14 +624,12 @@ CodeCompletion::BlockInfo CodeCompletion::getBlockInfo(int position) const
continue;
}
foreach (const QString &statement, blockStart.block().text().split(";")) {
// qDebug() << "Have statement" << statement;
QStringList parts = statement.split(":");
if (parts.length() != 2) {
continue;
}
QString propName = parts.first().trimmed();
QString propValue = parts.last().split("//").first().trimmed().remove("\"");
// qDebug() << "inserting:" << propName << "->" << propValue;
info.properties.insert(propName, propValue);
}
if (!blockStart.movePosition(QTextCursor::NextBlock)) {
@ -836,3 +874,24 @@ void CodeCompletion::moveCursor(CodeCompletion::MoveOperation moveOperation, int
}
}
}
int CodeCompletion::getBlockPosition(const QString &id) const
{
// Find block with id "id" in the doc
QTextCursor tmp = QTextCursor(m_document->textDocument());
while (!tmp.atEnd()) {
tmp.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
tmp.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
QString word = tmp.selectedText();
if (word == "id") {
tmp.movePosition(QTextCursor::NextWord, QTextCursor::MoveAnchor);
tmp.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
QString idName = tmp.selectedText();
if (idName == id) {
return tmp.position();
}
}
tmp.movePosition(QTextCursor::NextWord);
}
return -1;
}

View File

@ -113,6 +113,7 @@ private:
QStringList events;
};
int getBlockPosition(const QString &id) const;
BlockInfo getBlockInfo(int postition) const;
QList<CompletionModel::Entry> getIds() const;
QHash<QString, QString> getIdTypes() const;