443 lines
13 KiB
C++
443 lines
13 KiB
C++
#include "ui_piqt_connection_edit.h"
|
|
#include "piqt_connection_edit.h"
|
|
#include "piqt_connection_view.h"
|
|
#include "piqt_highlighter.h"
|
|
#include "piqt.h"
|
|
#include "picodeinfo.h"
|
|
#include <QSqlQuery>
|
|
#include <QSqlError>
|
|
#include <QSqlRecord>
|
|
#include <QMessageBox>
|
|
|
|
|
|
ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
|
|
ui = new Ui::ConnectionEdit();
|
|
ui->setupUi(this);
|
|
new ConfigHighlighter(ui->codeEdit->document());
|
|
loading = false;
|
|
connect(ui->blockView, SIGNAL(actionEvent(BlockItemBase::Action,QList<QGraphicsItem*>)), this, SLOT(recreateRequest()));
|
|
connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
|
conn = 0;
|
|
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
|
|
if (ei) {
|
|
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
|
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
|
}
|
|
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
|
|
ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode");
|
|
if (ei) {
|
|
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
|
ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
|
}
|
|
udevicenum = 0;
|
|
}
|
|
|
|
|
|
ConnectionEdit::~ConnectionEdit() {
|
|
if (conn) delete conn;
|
|
}
|
|
|
|
|
|
void ConnectionEdit::accept() {
|
|
//bool ok = false;
|
|
QList<BlockItem * > bl = ui->blockView->allDevices();
|
|
foreach (BlockItem * i, bl)
|
|
foreach (BlockItem * j, bl)
|
|
if (i != j)
|
|
if (((DeviceItem*)i)->name() == ((DeviceItem*)j)->name()) {
|
|
QMessageBox::critical(this, windowTitle() + " - " + tr("error") + "!", tr("Equal devices names: \"%1\"!").arg(((DeviceItem*)i)->name()));
|
|
return;
|
|
}
|
|
QDialog::accept();
|
|
}
|
|
|
|
|
|
QString ConnectionEdit::configuration() const {
|
|
if (!conn) return QString();
|
|
return PI2QString(conn->makeConfig());
|
|
}
|
|
|
|
|
|
QByteArray ConnectionEdit::model() const {
|
|
QByteArray ret;
|
|
QDataStream s(&ret, QIODevice::ReadWrite);
|
|
QString cn = PI2QString(conn ? conn->name() : PIString());
|
|
s << cn;
|
|
QList<BlockBusItem*> busl = ui->blockView->buses();
|
|
s << busl.size();
|
|
foreach (BlockBusItem * b, busl)
|
|
s << b->save();
|
|
QList<BlockItem*> blockl = ui->blockView->blocks();
|
|
s << blockl.size();
|
|
foreach (BlockItem * b, blockl) {
|
|
int type = b->propertyByName("__type").value.toInt();
|
|
s << type;
|
|
switch (type) {
|
|
case __CV_Device:
|
|
case __CV_Filter:
|
|
case __CV_Sender:
|
|
s << b->save();
|
|
break;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
QString ConnectionEdit::name() const {
|
|
if (!conn) return QString();
|
|
return PI2QString(conn->name());
|
|
}
|
|
|
|
|
|
void ConnectionEdit::setName(const QString & name) {
|
|
ui->lineName->setText(name);
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::addDevice(const QString & name, const QString & path) {
|
|
ui->blockView->addDevice(name, path);
|
|
}
|
|
|
|
|
|
void ConnectionEdit::setModel(const QByteArray & m) {
|
|
loading = true;
|
|
ui->blockView->removeAll();
|
|
QDataStream s(m);
|
|
QString cn;
|
|
s >> cn;
|
|
if (conn) delete conn;
|
|
conn = new PIConnection(Q2PIString(cn));
|
|
ui->lineName->setText(cn);
|
|
int sz;
|
|
s >> sz;
|
|
for (int i = 0; i < sz; ++i) {
|
|
BlockBusItem * b = new BlockBusItem();
|
|
QByteArray ba; s >> ba; b->load(ba);
|
|
ui->blockView->addItem(b);
|
|
}
|
|
s >> sz;
|
|
for (int i = 0; i < sz; ++i) {
|
|
int type(0);
|
|
BlockItem * b(0);
|
|
QByteArray ba;
|
|
s >> type;
|
|
switch (type) {
|
|
case __CV_Device:
|
|
b = new DeviceItem();
|
|
s >> ba; b->load(ba);
|
|
((DeviceItem*)b)->rename();
|
|
break;
|
|
case __CV_Filter:
|
|
b = new FilterItem();
|
|
s >> ba; b->load(ba);
|
|
((FilterItem*)b)->rename();
|
|
break;
|
|
case __CV_Sender:
|
|
b = new SenderItem();
|
|
s >> ba; b->load(ba);
|
|
((SenderItem*)b)->rename();
|
|
break;
|
|
}
|
|
if (b)
|
|
ui->blockView->addItem(b);
|
|
}
|
|
ui->blockView->reconnectAll();
|
|
loading = false;
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::selectionChanged() {
|
|
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
|
ui->buttonRemove->setEnabled(!si.isEmpty());
|
|
ui->buttonDeviceModify->setEnabled(false);
|
|
ui->buttonFilterModify->setEnabled(false);
|
|
ui->buttonSenderModify->setEnabled(false);
|
|
if (si.size() != 1) return;
|
|
BlockItem * b = qgraphicsitem_cast<BlockItem*>(si[0]);
|
|
if (!b) return;
|
|
int type = b->propertyByName("__type").value.toInt();
|
|
if (type == __CV_Device) {
|
|
ui->tabWidget->setCurrentIndex(0);
|
|
DeviceItem * di = (DeviceItem*)b;
|
|
ui->buttonDeviceModify->setEnabled(true);
|
|
for (int i = 0; i < ui->comboMode->count(); ++i)
|
|
if (ui->comboMode->itemData(i).toInt() == di->mode()) {
|
|
ui->comboMode->setCurrentIndex(i);
|
|
break;
|
|
}
|
|
ui->lineDevice->setText(di->name());
|
|
ui->linePath->setEditText(di->path());
|
|
ui->spinDeviceDT->setValue(di->disconnectTimeout());
|
|
}
|
|
if (type == __CV_Filter) {
|
|
ui->tabWidget->setCurrentIndex(1);
|
|
FilterItem * fi = (FilterItem*)b;
|
|
ui->buttonFilterModify->setEnabled(true);
|
|
for (int i = 0; i < ui->comboSplit->count(); ++i)
|
|
if (ui->comboSplit->itemData(i).toInt() == fi->mode()) {
|
|
ui->comboSplit->setCurrentIndex(i);
|
|
break;
|
|
}
|
|
ui->lineFilter->setText(fi->name());
|
|
ui->lineHeader->setText(fi->header());
|
|
ui->lineFooter->setText(fi->footer());
|
|
ui->spinTimeout->setValue(fi->timeout());
|
|
ui->spinSize->setValue(fi->packetSize());
|
|
ui->spinFilterDT->setValue(fi->disconnectTimeout());
|
|
}
|
|
if (type == __CV_Sender) {
|
|
ui->tabWidget->setCurrentIndex(2);
|
|
SenderItem * si = (SenderItem*)b;
|
|
ui->buttonSenderModify->setEnabled(true);
|
|
ui->lineSender->setText(si->name());
|
|
ui->lineData->setText(si->data());
|
|
ui->spinFrequency->setValue(si->frequency());
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void ConnectionEdit::applyFilter(FilterItem * b) {
|
|
b->setName(ui->lineFilter->text());
|
|
b->setMode(PIPacketExtractor::SplitMode(ui->comboSplit->itemData(ui->comboSplit->currentIndex()).toInt()));
|
|
b->setHeader(ui->lineHeader->text());
|
|
b->setFooter(ui->lineFooter->text());
|
|
b->setTimeout(ui->spinTimeout->value());
|
|
b->setPacketSize(ui->spinSize->value());
|
|
b->setDisconnectTimeout(ui->spinFilterDT->value());
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::applyDevice(DeviceItem * b) {
|
|
QString n = ui->lineDevice->text();
|
|
if (n.isEmpty()) {
|
|
n = "device" + QString::number(udevicenum);
|
|
}
|
|
b->setName(n);
|
|
b->setMode(PIIODevice::DeviceMode(ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt()));
|
|
b->setPath(ui->linePath->currentText());
|
|
b->setDisconnectTimeout(ui->spinDeviceDT->value());
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::applySender(SenderItem * b) {
|
|
b->setName(ui->lineSender->text());
|
|
b->setData(ui->lineData->text());
|
|
b->setFrequency(ui->spinFrequency->value());
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::recreateConnection() {
|
|
//qDebug() << "recreate";
|
|
if (loading) return;
|
|
ui->blockView->reconnectAll();
|
|
if (conn) delete conn;
|
|
PIString cn = Q2PIString(ui->lineName->text());
|
|
if (cn.isEmpty()) conn = new PIConnection();
|
|
else conn = new PIConnection(cn);
|
|
QList<BlockItem*> devs = ui->blockView->allDevices();
|
|
foreach (BlockItem * b, devs) {
|
|
DeviceItem * di = (DeviceItem*)b;
|
|
//qDebug() << di->path();
|
|
PIIODevice * dev = conn->addDevice(Q2PIString(di->path()), di->mode());
|
|
if (!dev) continue;
|
|
conn->setDeviceName(dev, Q2PIString(di->name()));
|
|
PIDiagnostics * diag = conn->diagnostic(dev);
|
|
if (diag) diag->setDisconnectTimeout(di->disconnectTimeout());
|
|
BlockItemPin * p = b->pinByText("read");
|
|
if (!p) continue;
|
|
QList<BlockBusItem*> buses = p->connectedBuses(), nbuses;
|
|
QSet<BlockBusItem*> pbuses;
|
|
while (!buses.isEmpty()) {
|
|
nbuses.clear();
|
|
foreach (BlockBusItem * bus, buses) {
|
|
QList<BlockItem*> cb = bus->connectedBlocks();
|
|
if (cb.size() != 2) continue;
|
|
FilterItem * fi_t(0);
|
|
BlockItem * bi_f(0);
|
|
if (cb[0]->pinAtBus(bus)->text() == "in") {
|
|
fi_t = (FilterItem*)(cb[0]);
|
|
bi_f = (cb[1]);
|
|
} else if (cb[1]->pinAtBus(bus)->text() == "in") {
|
|
fi_t = (FilterItem*)(cb[1]);
|
|
bi_f = (cb[0]);
|
|
}
|
|
if (!fi_t || !bi_f) continue;
|
|
QString name_from;
|
|
int type = bi_f->propertyByName("__type").value.toInt();
|
|
if (type == __CV_Device) name_from = ((DeviceItem*)bi_f)->path();
|
|
if (type == __CV_Filter) name_from = ((FilterItem*)bi_f)->name();
|
|
if (name_from.isEmpty()) continue;
|
|
PIPacketExtractor * pe = conn->addFilter(Q2PIString(fi_t->name()), Q2PIString(name_from), fi_t->mode());
|
|
if (!pe) continue;
|
|
pe->setHeader(PIByteArray::fromString(Q2PIString(fi_t->header())));
|
|
pe->setFooter(PIByteArray::fromString(Q2PIString(fi_t->footer())));
|
|
pe->setTimeout(fi_t->timeout());
|
|
pe->setPacketSize(fi_t->packetSize());
|
|
pe->setPayloadSize(fi_t->packetSize());
|
|
diag = conn->diagnostic(pe);
|
|
if (diag) diag->setDisconnectTimeout(fi_t->disconnectTimeout());
|
|
QList<BlockBusItem*> nb = fi_t->pinByText("out")->connectedBuses();
|
|
foreach (BlockBusItem * b_, nb)
|
|
if (!pbuses.contains(b_)) {
|
|
pbuses << b_;
|
|
nbuses << b_;
|
|
}
|
|
}
|
|
buses = nbuses;
|
|
}
|
|
}
|
|
foreach (BlockItem * b, devs) {
|
|
BlockItemPin * p = b->pinByText("write");
|
|
if (!p) continue;
|
|
QList<BlockBusItem*> buses = p->connectedBuses();
|
|
foreach (BlockBusItem * bus, buses) {
|
|
QList<BlockItem*> cb = bus->connectedBlocks();
|
|
if (cb.size() != 2) continue;
|
|
BlockItem * bi_f(0);
|
|
DeviceItem * di_t(0);
|
|
if (cb[0]->pinAtBus(bus)->text() == "write") {
|
|
di_t = (DeviceItem*)(cb[0]);
|
|
bi_f = (cb[1]);
|
|
} else if (cb[1]->pinAtBus(bus)->text() == "write") {
|
|
di_t = (DeviceItem*)(cb[1]);
|
|
bi_f = (cb[0]);
|
|
}
|
|
if (!bi_f || !di_t) continue;
|
|
QString name_from;
|
|
int type = bi_f->propertyByName("__type").value.toInt();
|
|
if (type == __CV_Sender) {
|
|
SenderItem * si = ((SenderItem*)bi_f);
|
|
si->name();
|
|
conn->addSender(Q2PIString(si->name()), Q2PIString(di_t->path()), si->frequency());
|
|
if (!si->data().isEmpty())
|
|
conn->setSenderFixedData(Q2PIString(si->name()), PIByteArray::fromString(Q2PIString(si->data())));
|
|
} else {
|
|
if (type == __CV_Device) name_from = ((DeviceItem*)bi_f)->path();
|
|
if (type == __CV_Filter) name_from = ((FilterItem*)bi_f)->name();
|
|
if (name_from.isEmpty()) continue;
|
|
conn->addChannel(Q2PIString(name_from), Q2PIString(di_t->path()));
|
|
}
|
|
}
|
|
}
|
|
ui->codeEdit->setText(PI2QString(conn->makeConfig()));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonRemove_clicked() {
|
|
ui->blockView->removeSelected();
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonClear_clicked() {
|
|
ui->blockView->removeAll();
|
|
recreateConnection();
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonFilterAdd_clicked() {
|
|
if (!conn) return;
|
|
applyFilter(ui->blockView->addFilter(ui->lineFilter->text()));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonFilterModify_clicked() {
|
|
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
|
if (si.isEmpty()) return;
|
|
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
|
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter)
|
|
return;
|
|
applyFilter(qgraphicsitem_cast<FilterItem*>(si[0]));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonDeviceAdd_clicked() {
|
|
if (!conn) return;
|
|
QString n = ui->lineDevice->text();
|
|
if (n.isEmpty()) {
|
|
udevicenum++;
|
|
n = "device" + QString::number(udevicenum);
|
|
}
|
|
QString p = ui->linePath->currentText();
|
|
if (ui->linePath->findText(p) < 0) ui->linePath->addItem(p);
|
|
qDebug() << "add:" << n;
|
|
applyDevice(ui->blockView->addDevice(n, ui->linePath->currentText()));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonDeviceModify_clicked() {
|
|
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
|
if (si.isEmpty()) return;
|
|
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
|
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Device)
|
|
return;
|
|
applyDevice(qgraphicsitem_cast<DeviceItem*>(si[0]));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonSenderAdd_clicked() {
|
|
if (!conn) return;
|
|
applySender(ui->blockView->addSender(ui->lineSender->text()));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_buttonSenderModify_clicked() {
|
|
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
|
if (si.isEmpty()) return;
|
|
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
|
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender)
|
|
return;
|
|
applySender(qgraphicsitem_cast<SenderItem*>(si[0]));
|
|
}
|
|
|
|
|
|
void ConnectionEdit::on_comboSplit_currentIndexChanged(int index) {
|
|
int mode = ui->comboSplit->itemData(index).toInt();
|
|
switch (mode) {
|
|
case PIPacketExtractor::None:
|
|
ui->widgetHeader->setEnabled(false);
|
|
ui->widgetFooter->setEnabled(false);
|
|
ui->widgetTimeout->setEnabled(false);
|
|
ui->widgetSize->setEnabled(false);
|
|
break;
|
|
case PIPacketExtractor::Header:
|
|
ui->widgetHeader->setEnabled(true);
|
|
ui->widgetFooter->setEnabled(false);
|
|
ui->widgetTimeout->setEnabled(false);
|
|
ui->widgetSize->setEnabled(true);
|
|
break;
|
|
case PIPacketExtractor::Footer:
|
|
ui->widgetHeader->setEnabled(false);
|
|
ui->widgetFooter->setEnabled(true);
|
|
ui->widgetTimeout->setEnabled(false);
|
|
ui->widgetSize->setEnabled(true);
|
|
break;
|
|
case PIPacketExtractor::HeaderAndFooter:
|
|
ui->widgetHeader->setEnabled(true);
|
|
ui->widgetFooter->setEnabled(true);
|
|
ui->widgetTimeout->setEnabled(false);
|
|
ui->widgetSize->setEnabled(false);
|
|
break;
|
|
case PIPacketExtractor::Timeout:
|
|
ui->widgetHeader->setEnabled(false);
|
|
ui->widgetFooter->setEnabled(false);
|
|
ui->widgetTimeout->setEnabled(true);
|
|
ui->widgetSize->setEnabled(false);
|
|
break;
|
|
case PIPacketExtractor::Size:
|
|
ui->widgetHeader->setEnabled(false);
|
|
ui->widgetFooter->setEnabled(false);
|
|
ui->widgetTimeout->setEnabled(false);
|
|
ui->widgetSize->setEnabled(true);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|