2026-01-09 17:43:58 +08:00
|
|
|
#include "structDataMeasurementModel.h"
|
|
|
|
|
#include "structDataSource.h"
|
|
|
|
|
#include "global.h"
|
|
|
|
|
|
|
|
|
|
StructDataMeasurementModel::StructDataMeasurementModel(StructDataSource* dataManager, QObject* parent)
|
|
|
|
|
: QAbstractTableModel(parent)
|
|
|
|
|
, m_dataManager(dataManager)
|
|
|
|
|
{
|
|
|
|
|
connect(m_dataManager, &StructDataSource::propertyUpdated,
|
|
|
|
|
this, &StructDataMeasurementModel::onPropertyUpdated);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StructDataMeasurementModel::setPropertyCodes(const QStringList& codes) {
|
|
|
|
|
beginResetModel();
|
|
|
|
|
m_propertyCodes = codes;
|
|
|
|
|
endResetModel();
|
|
|
|
|
|
|
|
|
|
emit propertiesLoaded(m_propertyCodes.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StructDataMeasurementModel::setProperties(const QVector<ExtraProperty>& properties) {
|
|
|
|
|
QStringList codes;
|
|
|
|
|
for (const auto& prop : properties) {
|
|
|
|
|
if (!prop.code.isEmpty()) {
|
|
|
|
|
codes.append(prop.code);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setPropertyCodes(codes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int StructDataMeasurementModel::rowCount(const QModelIndex& parent) const {
|
|
|
|
|
return parent.isValid() ? 0 : m_propertyCodes.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int StructDataMeasurementModel::columnCount(const QModelIndex& parent) const {
|
|
|
|
|
return parent.isValid() ? 0 : ColumnCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant StructDataMeasurementModel::data(const QModelIndex& index, int role) const {
|
|
|
|
|
if (!index.isValid() || index.row() >= m_propertyCodes.size()) {
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ExtraProperty* prop = getProperty(index.row());
|
|
|
|
|
if (!prop) {
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int col = index.column();
|
|
|
|
|
|
|
|
|
|
if (role == Qt::DisplayRole || role == Qt::EditRole) {
|
|
|
|
|
switch (col) {
|
|
|
|
|
case ColName: return prop->name;
|
|
|
|
|
case ColTag: return prop->tag;
|
|
|
|
|
case ColCode: return prop->code;
|
|
|
|
|
case ColSourceType: return "量测";
|
|
|
|
|
case ColConnectPara: return prop->connect_para;
|
2026-01-16 18:40:46 +08:00
|
|
|
default: return getMeasurementData(*prop, col ,role);
|
2026-01-09 17:43:58 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (role == Qt::UserRole) {
|
|
|
|
|
return QVariant::fromValue(*prop);
|
|
|
|
|
}
|
|
|
|
|
else if (role == Qt::UserRole + 1) {
|
|
|
|
|
return prop->code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool StructDataMeasurementModel::setData(const QModelIndex& index, const QVariant& value, int role) {
|
|
|
|
|
if (!index.isValid() || index.row() >= m_propertyCodes.size() || role != Qt::EditRole) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ExtraProperty* prop = getProperty(index.row());
|
|
|
|
|
if (!prop) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int col = index.column();
|
|
|
|
|
bool changed = false;
|
|
|
|
|
ExtraProperty updatedProp = *prop;
|
|
|
|
|
|
|
|
|
|
if (col == ColConnectPara) {
|
|
|
|
|
if (updatedProp.connect_para != value.toString()) {
|
|
|
|
|
updatedProp.connect_para = value.toString();
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
MeasurementInfo* data = m_dataManager->getMeasurementData(updatedProp);
|
|
|
|
|
if (data) {
|
2026-01-16 18:40:46 +08:00
|
|
|
changed = updateMeasurementData(data, col, value, role);
|
2026-01-09 17:43:58 +08:00
|
|
|
if (changed) {
|
|
|
|
|
emit m_dataManager->dataChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (changed) {
|
2026-01-16 18:40:46 +08:00
|
|
|
updatedProp.bDataChanged = true;
|
2026-01-09 17:43:58 +08:00
|
|
|
if (m_dataManager->updateProperty(updatedProp)) {
|
|
|
|
|
emit dataChanged(index, index, {role});
|
|
|
|
|
emit propertyModified(index.row(), updatedProp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Qt::ItemFlags StructDataMeasurementModel::flags(const QModelIndex& index) const {
|
|
|
|
|
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
|
|
|
|
|
|
|
|
|
int col = index.column();
|
2026-01-16 18:40:46 +08:00
|
|
|
if (col == ColConnectPara || ColType || ColSize || ColSource || ColStation || ColEquipment || ColChannel || ColPacket || ColOffset || ColEnable || ColCause) {
|
2026-01-09 17:43:58 +08:00
|
|
|
flags |= Qt::ItemIsEditable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant StructDataMeasurementModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
|
|
|
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
|
|
|
|
QStringList headers = {
|
|
|
|
|
"名称", "标签", "编码", "类型", "连接参数",
|
2026-01-16 18:40:46 +08:00
|
|
|
"量测类型", "数据包size", "数据来源", "子站", "设备", "通道号","包号(104)","偏移量(104)","开启事件","事件原因","执行动作","动作参数"
|
2026-01-09 17:43:58 +08:00
|
|
|
};
|
|
|
|
|
return headers.value(section, "");
|
|
|
|
|
}
|
|
|
|
|
return QAbstractTableModel::headerData(section, orientation, role);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVector<ExtraProperty> StructDataMeasurementModel::getDisplayedProperties() const {
|
|
|
|
|
QVector<ExtraProperty> result;
|
|
|
|
|
for (const QString& code : m_propertyCodes) {
|
|
|
|
|
ExtraProperty* prop = m_dataManager->getPropertyByCode(code);
|
|
|
|
|
if (prop) {
|
|
|
|
|
result.append(*prop);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList StructDataMeasurementModel::getDisplayedCodes() const {
|
|
|
|
|
return m_propertyCodes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int StructDataMeasurementModel::findRowByCode(const QString& code) const {
|
|
|
|
|
return m_propertyCodes.indexOf(code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StructDataMeasurementModel::refreshRow(const QString& code) {
|
|
|
|
|
int row = findRowByCode(code);
|
|
|
|
|
if (row >= 0) {
|
|
|
|
|
QModelIndex start = index(row, 0);
|
|
|
|
|
QModelIndex end = index(row, columnCount() - 1);
|
|
|
|
|
emit dataChanged(start, end);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StructDataMeasurementModel::onPropertyUpdated(const ExtraProperty& updatedProp, bool isNew) {
|
|
|
|
|
Q_UNUSED(isNew);
|
|
|
|
|
int row = findRowByCode(updatedProp.code);
|
|
|
|
|
if (row >= 0) {
|
|
|
|
|
refreshRow(updatedProp.code);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ExtraProperty* StructDataMeasurementModel::getProperty(int displayRow) const {
|
|
|
|
|
if (displayRow < 0 || displayRow >= m_propertyCodes.size()) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return m_dataManager->getPropertyByCode(m_propertyCodes[displayRow]);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 18:40:46 +08:00
|
|
|
QVariant StructDataMeasurementModel::getMeasurementData(const ExtraProperty& prop, int col, int role) const {
|
2026-01-09 17:43:58 +08:00
|
|
|
MeasurementInfo* data = m_dataManager->getMeasurementData(prop);
|
|
|
|
|
if (!data) return QVariant();
|
|
|
|
|
|
|
|
|
|
switch (col) {
|
|
|
|
|
case ColType: return getTypeText(data->type);
|
|
|
|
|
case ColSize: return data->size;
|
|
|
|
|
case ColSource: return getSourceText(data->nSource);
|
|
|
|
|
case ColStation: return data->sStation;
|
|
|
|
|
case ColEquipment: return data->sDevice;
|
|
|
|
|
case ColChannel: return data->sChannel;
|
|
|
|
|
case ColPacket: return data->nPacket;
|
|
|
|
|
case ColOffset: return data->nOffset;
|
|
|
|
|
case ColEnable: return data->bEnable ? "启用" : "禁用";
|
2026-01-16 18:40:46 +08:00
|
|
|
case ColCause:
|
|
|
|
|
if(data->type == 0){
|
|
|
|
|
if(role == Qt::EditRole){
|
|
|
|
|
return QVariant::fromValue(data->mapTE);
|
|
|
|
|
}
|
|
|
|
|
else if(role == Qt::DisplayRole){
|
|
|
|
|
if (data->mapTE.isEmpty()) {
|
|
|
|
|
return "(空)";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList parts;
|
|
|
|
|
for (auto it = data->mapTE.begin(); it != data->mapTE.end(); ++it) {
|
|
|
|
|
parts << QString("%1: %2").arg(it.key()).arg(it.value(), 0, 'f', 1);
|
|
|
|
|
}
|
|
|
|
|
return parts.join("; ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return data->sEdge;
|
|
|
|
|
case ColCommand: return data->sCommand;
|
|
|
|
|
case ColParameters:{
|
|
|
|
|
if(role == Qt::EditRole){
|
|
|
|
|
return data->lstParameter;
|
|
|
|
|
}
|
|
|
|
|
else if(role == Qt::DisplayRole){
|
|
|
|
|
if (data->lstParameter.isEmpty()) {
|
|
|
|
|
return "(空)";
|
|
|
|
|
}
|
|
|
|
|
return data->lstParameter.join(",");
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-09 17:43:58 +08:00
|
|
|
}
|
2026-01-16 18:40:46 +08:00
|
|
|
|
2026-01-09 17:43:58 +08:00
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 18:40:46 +08:00
|
|
|
bool StructDataMeasurementModel::updateMeasurementData(MeasurementInfo* data, int col, const QVariant& value,int role) {
|
2026-01-09 17:43:58 +08:00
|
|
|
switch (col) {
|
|
|
|
|
case ColType:
|
|
|
|
|
if (data->type != value.toInt()) {
|
|
|
|
|
data->type = value.toInt();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColSize:
|
|
|
|
|
if (data->size != value.toInt()) {
|
|
|
|
|
data->size = value.toInt();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColSource:
|
|
|
|
|
if (getSourceText(data->nSource) != value.toString()) {
|
|
|
|
|
data->nSource = getSourceInt(value.toString());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColStation:
|
|
|
|
|
if (data->sStation != value.toString()) {
|
|
|
|
|
data->sStation = value.toString();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColEquipment:
|
|
|
|
|
if (data->sDevice != value.toString()) {
|
|
|
|
|
data->sDevice = value.toString();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColChannel:
|
|
|
|
|
if (data->sChannel != value.toString()) {
|
|
|
|
|
data->sChannel = value.toString();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColEnable:
|
|
|
|
|
if (data->bEnable != value.toBool()) {
|
|
|
|
|
data->bEnable = value.toBool();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2026-01-16 18:40:46 +08:00
|
|
|
case ColCause:
|
|
|
|
|
if(data->type == 0)
|
|
|
|
|
{
|
|
|
|
|
if(role == Qt::EditRole){
|
|
|
|
|
if (data->mapTE != value.value<QMap<QString,double>>()) {
|
|
|
|
|
data->mapTE = value.value<QMap<QString,double>>();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
if (data->sEdge != value.toString()) {
|
|
|
|
|
data->sEdge = value.toString();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColCommand:
|
|
|
|
|
if (data->sCommand != value.toString()) {
|
|
|
|
|
data->sCommand = value.toString();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ColParameters:
|
|
|
|
|
if(role == Qt::EditRole){
|
|
|
|
|
if (data->lstParameter != value.toStringList()) {
|
|
|
|
|
data->lstParameter = value.toStringList();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2026-01-09 17:43:58 +08:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString StructDataMeasurementModel::getTypeText(int type) const {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 0: return "遥测";
|
|
|
|
|
case 1: return "遥信";
|
|
|
|
|
case 2: return "遥控";
|
|
|
|
|
default: return QString::number(type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString StructDataMeasurementModel::getSourceText(int source) const {
|
|
|
|
|
switch (source) {
|
|
|
|
|
case 1: return "cl3611";
|
|
|
|
|
case 2: return "104";
|
|
|
|
|
default: return QString::number(source);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int StructDataMeasurementModel::getSourceInt(QString sType) const {
|
|
|
|
|
if(sType == "cl3611"){
|
2026-01-16 18:40:46 +08:00
|
|
|
return 1;
|
2026-01-09 17:43:58 +08:00
|
|
|
}
|
|
|
|
|
else if(sType == "104"){
|
2026-01-16 18:40:46 +08:00
|
|
|
return 2;
|
2026-01-09 17:43:58 +08:00
|
|
|
}
|
|
|
|
|
else {
|
2026-01-16 18:40:46 +08:00
|
|
|
return 3;
|
2026-01-09 17:43:58 +08:00
|
|
|
}
|
|
|
|
|
}
|