#include "dataSourceDlg.h" #include "ui_dataSourceDlg.h" #include #include #include "structDataSource.h" #include "instance/extraPropertyManager.h" #include "propertyType/dataSourceType.h" #include #include "global.h" DataSourceDlg::DataSourceDlg(QWidget *parent) : QDialog(parent) , ui(new Ui::dataSourceDlg) ,_treeModel(nullptr) ,m_currentCategoryItem(nullptr) ,_pExtraProManager(nullptr) ,_curProperty(nullptr) { ui->setupUi(this); setModal(true); this->setWindowFlags(Qt::FramelessWindowHint | windowFlags()); //setAttribute(Qt::WA_DeleteOnClose); initial(); } DataSourceDlg::~DataSourceDlg() { delete ui; } void DataSourceDlg::initial() { connect(ui->btn_ok,&QPushButton::clicked,this,&DataSourceDlg::onOkClicked); connect(ui->btn_cancel,&QPushButton::clicked,this,&DataSourceDlg::onCancelClicked); m_dataSource = new StructDataSource(this); _treeModel = new QStandardItemModel(this); _treeModel->setHorizontalHeaderLabels(QStringList() << "属性层级结构"); ui->treeView->setModel(_treeModel); connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &DataSourceDlg::onTreeSelectionChanged); connect(ui->listWidget, &QListWidget::itemClicked, this,&DataSourceDlg::onListWidgetClicked); _pExtraProManager = new ExtraPropertyManager(this); _pExtraProManager->initial(); loadData(); connect(this, &DataSourceDlg::listWidgetUpdated, this, [this]() { if (!m_targetPropertyCode.isEmpty()) { for (int i = 0; i < ui->listWidget->count(); ++i) { QListWidgetItem* listItem = ui->listWidget->item(i); if (listItem && listItem->text() == m_targetPropertyCode) { ui->listWidget->setCurrentRow(i); ui->listWidget->scrollToItem(listItem, QAbstractItemView::EnsureVisible); emit ui->listWidget->itemClicked(listItem); m_targetPropertyCode.clear(); break; } } } }); } void DataSourceDlg::loadData() { if(_pExtraProManager) m_dataSource->loadExtrapro(_pExtraProManager->geAlltProperty()); } void DataSourceDlg::showDlg(DataSourceType tpe) { if(_pExtraProManager) { //show(); clearItems(); auto& mapExtra = m_dataSource->allProperties; QStandardItem* root = _treeModel->invisibleRootItem(); for(auto& pro:mapExtra){ QStandardItem* propertyItem = new QStandardItem(); addItemToView(pro,"name",root,propertyItem); } ui->treeView->expandAll(); if(!tpe.sCode.isEmpty()){ expandToNodeByCode(tpe.sCode,_treeModel); } } } DataSourceType DataSourceDlg::getCurData() { DataSourceType type; if(_curProperty){ type.sPara = _curProperty->data(Qt::UserRole).toString(); type.sCode = _curProperty->data(Qt::UserRole+1).toString(); } return type; } void DataSourceDlg::addItemToView(const ExtraProperty& property, const QString& displayMode, // "name" 或 "tag" QStandardItem* root, QStandardItem* pItem) { // 设置叶子节点的显示文本(使用name或tag) if (displayMode == "name") { pItem->setText(property.name.isEmpty() ? "未命名属性" : property.name); } else { pItem->setText(property.tag.isEmpty() ? "unknown_property" : property.tag); } // 在叶子节点存储完整的属性信息 QVariantMap propertyData; propertyData["property"] = QVariant::fromValue(property); propertyData["displayMode"] = displayMode; propertyData["code"] = property.code; pItem->setData(propertyData, Qt::UserRole + 1); QVector levels = { {(displayMode == "name") ? property.grid_name : property.grid_tag, property.grid_name, property.grid_tag, true, (displayMode == "name") ? "未命名电网" : "unknown_grid"}, {(displayMode == "name") ? property.zone_name : property.zone_tag, property.zone_name, property.zone_tag, true, (displayMode == "name") ? "未命名区域" : "unknown_zone"}, {(displayMode == "name") ? property.station_name : property.station_tag, property.station_name, property.station_tag, true, (displayMode == "name") ? "未命名站点" : "unknown_station"}, {property.currentLevel, property.currentLevel, property.currentLevel, false, (displayMode == "name") ? "通用层级" : "common_level"}, {(displayMode == "name") ? property.bay_name : property.bay_tag, property.bay_name, property.bay_tag, false, (displayMode == "name") ? "间隔" : "bay"}, {property.component_name.isEmpty() ? (displayMode == "name") ? "未命名设备" : property.component_uuid.toString() : (displayMode == "name") ? property.component_name : property.component_uuid.toString(), property.component_name, property.component_uuid.toString(), true, (displayMode == "name") ? "未命名设备" : "unknown_component"} }; QStandardItem* currentParent = root; for (size_t i = 0; i < levels.size(); ++i) { const auto& level = levels[i]; bool isRequired = level.isRequired; bool isEmpty = (displayMode == "name") ? (level.nameValue.isEmpty() && level.displayText.isEmpty()) : (level.tagValue.isEmpty() && level.displayText.isEmpty()); if (!isRequired && isEmpty) { continue; } // 确定显示文本 QString displayText = level.displayText; bool isMissing = false; if (displayText.isEmpty()) { if (isRequired) { displayText = level.placeholder; isMissing = true; } else { // 可选层级为空,跳过 continue; } } // 查找当前层级是否已存在 QStandardItem* foundChild = nullptr; for (int row = 0; row < currentParent->rowCount(); ++row) { QStandardItem* child = currentParent->child(row, 0); if (child && child->text() == displayText) { // 检查是否为同一层级 QVariantMap childData = child->data(Qt::UserRole + 1).toMap(); int childLevelIndex = childData["levelIndex"].toInt(); if (childLevelIndex == static_cast(i)) { foundChild = child; break; } } } if (foundChild) { currentParent = foundChild; } else { QStandardItem* newNode = new QStandardItem(displayText); QVariantMap levelData; levelData["levelIndex"] = static_cast(i); levelData["levelType"] = getLevelType(i); newNode->setData(levelData, Qt::UserRole + 1); currentParent->appendRow(newNode); currentParent = newNode; } } // 现在currentParent是component节点 // 处理group层级(第7层) QStandardItem* groupItem = processGroupLevel(currentParent, property); // 处理category层级(在group下) processCategoryLevel(groupItem, property); } void DataSourceDlg::onOkClicked() { /*if(_curTargetHandel){ if(_curProperty){ DataSourceType type; _curTargetHandel->setVar(QVariant::fromValue(type)); } }*/ accept(); } void DataSourceDlg::onCancelClicked() { reject(); } void DataSourceDlg::onTreeSelectionChanged(const QModelIndex& current, const QModelIndex& previous) { Q_UNUSED(previous); clearPropertyList(); if (!current.isValid()) { return; } QStandardItem* item = _treeModel->itemFromIndex(current); if (!item) { return; } QVariantMap itemData = item->data(Qt::UserRole + 1).toMap(); QString levelType = itemData.value("levelType", "").toString(); if (levelType == "category") { // 点击分类节点,从category节点获取属性 loadCategoryProperties(item); // 检查是否需要选中特定的listWidgetItem if (!m_targetPropertyCode.isEmpty()) { // 在listWidget中查找并选中对应的item for (int i = 0; i < ui->listWidget->count(); ++i) { QListWidgetItem* listItem = ui->listWidget->item(i); if (listItem && listItem->text() == m_targetPropertyCode) { ui->listWidget->setCurrentRow(i); ui->listWidget->scrollToItem(listItem, QAbstractItemView::EnsureVisible); // 触发listWidget的itemClicked信号 emit ui->listWidget->itemClicked(listItem); break; } } } } else { m_targetPropertyCode.clear(); // 清空目标code } } void DataSourceDlg::onListWidgetClicked(QListWidgetItem* pItem) { QString sPara = pItem->data(Qt::UserRole).toString(); ui->listWidget_select->clear(); QListWidgetItem* pCur = new QListWidgetItem(pItem->text()+":"+sPara); pCur->setData(Qt::UserRole,sPara); pCur->setData(Qt::UserRole+1,pItem->text()); ui->listWidget_select->addItem(pCur); _curProperty = pCur; } void DataSourceDlg::clearPropertyList() { ui->listWidget->clear(); ui->listWidget_select->clear(); m_currentCategoryItem = nullptr; } void DataSourceDlg::loadCategoryProperties(QStandardItem* categoryItem) { m_currentCategoryItem = categoryItem; // 从category节点获取属性列表 QVariantMap categoryData = categoryItem->data(Qt::UserRole + 1).toMap(); QVector properties = categoryData["properties"].value>(); if (properties.isEmpty()) { // 如果没有属性,从DataManager重新获取 properties = getCategoryPropertiesFromDataManager(categoryData); } if (properties.isEmpty()) { clearItems(); return; } QTimer::singleShot(50, this, [this,properties]() { updatePropertyList(properties); }); } QVector DataSourceDlg::getCategoryPropertiesFromDataManager(const QVariantMap& categoryData) { QString groupTag = categoryData.value("groupTag").toString(); QString modelName = categoryData.value("modelName").toString(); QString paraType = categoryData.value("paraType").toString(); QString sourceType = categoryData.value("sourceType").toString(); QString componentUuid = categoryData.value("component_uuid").toString(); QVector result; for (auto it = m_dataSource->allProperties.begin(); it != m_dataSource->allProperties.end(); ++it) { const ExtraProperty& prop = it.value(); bool match = (prop.group_tag == groupTag) && (prop.sourceType == sourceType) && (prop.type_tag == paraType) && (prop.component_uuid.toString() == componentUuid); if (sourceType == "property") { match = match && (prop.sourceConfig.value("modelName").toString() == modelName); } if (match) { result.append(prop); } } return result; } void DataSourceDlg::updateCategoryProperties(QStandardItem* categoryItem, const ExtraProperty& property) { QVariantMap categoryData = categoryItem->data(Qt::UserRole + 1).toMap(); QVector properties = categoryData["properties"].value>(); // 检查属性是否已存在 bool exists = false; for (const auto& prop : properties) { if (prop.code == property.code) { exists = true; break; } } if (!exists) { properties.append(property); categoryData["properties"] = QVariant::fromValue(properties); int newCount = properties.size(); categoryData["propertyCount"] = newCount; // 更新显示文本 QString baseName = property.type_name; categoryItem->setText(QString("%1 (%2)").arg(baseName).arg(newCount)); // 更新工具提示 QString tooltip = QString("属性数量: %1") .arg(newCount); categoryItem->setToolTip(tooltip); categoryItem->setData(categoryData, Qt::UserRole + 1); } } QStandardItem* DataSourceDlg::processGroupLevel(QStandardItem* componentItem, const ExtraProperty& property) { QString groupDisplayText = (property.group_name.isEmpty() ? property.group_tag : property.group_name); if (groupDisplayText.isEmpty()) { groupDisplayText = "未命名分组"; } // 查找group节点 for (int row = 0; row < componentItem->rowCount(); ++row) { QStandardItem* child = componentItem->child(row, 0); if (child) { QVariantMap childData = child->data(Qt::UserRole + 1).toMap(); QString levelType = childData.value("levelType").toString(); if (levelType == "group") { // 检查是否是同一个group QString existingGroupTag = childData.value("groupTag", "").toString(); QString existingModelName = childData.value("modelName", "").toString(); QString propertyModelName = property.sourceConfig.value("modelName").toString(); if (existingGroupTag == property.group_tag) { if (property.sourceType == "property") { // 对于property类型,还需要检查modelName if (existingModelName == propertyModelName) { return child; } } else { // 对于measurement类型,只需要groupTag匹配 return child; } } } } } // 创建新的group节点 QStandardItem* groupItem = new QStandardItem(groupDisplayText); QVariantMap groupData; groupData["levelIndex"] = 6; // 第7层 groupData["levelType"] = "group"; groupData["groupName"] = property.group_name; groupData["groupTag"] = property.group_tag; groupData["sourceType"] = property.sourceType; if (property.sourceType == "property") { groupData["modelName"] = property.sourceConfig.value("modelName"); } groupData["properties"] = QVariant::fromValue(QVector()); groupItem->setData(groupData, Qt::UserRole + 1); // 设置工具提示 QString tooltip = QString("分组: %1\n类型: %2") .arg(groupDisplayText) .arg(property.sourceType == "property" ? "属性" : "量测"); groupItem->setToolTip(tooltip); componentItem->appendRow(groupItem); return groupItem; } // 处理category层级 void DataSourceDlg::processCategoryLevel(QStandardItem* groupItem, const ExtraProperty& property) { QString categoryName = property.type_name; QString paraType = property.type_tag; if (categoryName.isEmpty() || paraType.isEmpty()) { qWarning() << "Invalid category or paraType for property:" << property.code; return; } // 查找category节点 for (int row = 0; row < groupItem->rowCount(); ++row) { QStandardItem* child = groupItem->child(row, 0); if (child) { QVariantMap childData = child->data(Qt::UserRole + 1).toMap(); QString levelType = childData.value("levelType").toString(); QString childParaType = childData.value("paraType", "").toString(); if (levelType == "category" && childParaType == paraType) { // 找到对应的category节点,更新属性列表 updateCategoryProperties(child, property); return; } } } // 创建新的category节点 QStandardItem* categoryItem = new QStandardItem(categoryName); QVariantMap categoryData; categoryData["levelType"] = "category"; categoryData["paraType"] = paraType; categoryData["sourceType"] = property.sourceType; categoryData["groupTag"] = property.group_tag; categoryData["groupName"] = property.group_name; if (property.sourceType == "property") { categoryData["modelName"] = property.sourceConfig.value("modelName"); } // 初始化属性列表 QVector properties; properties.append(property); categoryData["properties"] = QVariant::fromValue(properties); categoryData["propertyCount"] = 1; categoryItem->setData(categoryData, Qt::UserRole + 1); // 设置显示文本(包含数量) categoryItem->setText(QString("%1 (1)").arg(categoryName)); // 设置工具提示 QString tooltip = QString("分类: %1\n参量类型: %2\n属性数量: 1") .arg(categoryName) .arg(categoryName); categoryItem->setToolTip(tooltip); groupItem->appendRow(categoryItem); } void DataSourceDlg::updatePropertyList(QVector vec) { ui->listWidget->clear(); for(auto& pro:vec){ QListWidgetItem* pItem = new QListWidgetItem(pro.code); pItem->setData(Qt::UserRole, pro.connect_para); ui->listWidget->addItem(pItem); } QTimer::singleShot(50, this, [this]() { emit listWidgetUpdated(); }); } void DataSourceDlg::expandToNodeByCode(const QString& code, QStandardItemModel* model) { if (!model || code.isEmpty()) { return; } // 设置目标code m_targetPropertyCode = code; // 查找节点 QStandardItem* targetNode = findCategoryNodeByPropertyCode(model->invisibleRootItem(), code); if (!targetNode) { qDebug() << "未找到code为" << code << "的节点"; m_targetPropertyCode.clear(); return; } // 展开路径 QList path; QStandardItem* current = targetNode; while (current && current != model->invisibleRootItem()) { path.prepend(current); current = current->parent(); } for (QStandardItem* item : path) { QModelIndex index = model->indexFromItem(item); if (index.isValid()) { ui->treeView->expand(index); } } // 🔴 关键:阻塞currentChanged信号 QItemSelectionModel* selectionModel = ui->treeView->selectionModel(); if (selectionModel) { selectionModel->blockSignals(true); } QModelIndex targetIndex = model->indexFromItem(targetNode); // 设置当前项(这会触发currentChanged,但信号被阻塞了) selectionModel->setCurrentIndex(targetIndex, QItemSelectionModel::ClearAndSelect); // 手动调用处理函数 onTreeSelectionChanged(targetIndex, QModelIndex()); // 恢复信号 if (selectionModel) { selectionModel->blockSignals(false); } // 滚动 ui->treeView->scrollTo(targetIndex, QAbstractItemView::EnsureVisible); } void DataSourceDlg::selectListItemByCode(const QString& code) { for (int i = 0; i < ui->listWidget->count(); ++i) { QListWidgetItem* listItem = ui->listWidget->item(i); if (listItem && listItem->text() == code) { ui->listWidget->setCurrentRow(i); ui->listWidget->scrollToItem(listItem, QAbstractItemView::EnsureVisible); return; } } } QStandardItem* DataSourceDlg::findCategoryNodeByPropertyCode(QStandardItem* item, const QString& code) { if (!item) { return nullptr; } QVariant itemData = item->data(Qt::UserRole + 1); if (itemData.isValid() && itemData.canConvert()) { QVariantMap dataMap = itemData.toMap(); // 检查当前节点是否是category节点 QString levelType = dataMap.value("levelType", "").toString(); if (levelType == "category") { // 检查category节点的properties列表 if (dataMap.contains("properties")) { QVector properties = dataMap["properties"].value>(); for (int i = 0; i < properties.size(); ++i) { if (properties[i].code == code) { return item; // 找到包含该属性的category节点 } } } } } // 递归搜索子节点 for (int row = 0; row < item->rowCount(); ++row) { QStandardItem* child = item->child(row, 0); QStandardItem* found = findCategoryNodeByPropertyCode(child, code); if (found) { return found; } } return nullptr; } void DataSourceDlg::clearItems() { if(_treeModel){ QStandardItem *root = _treeModel->invisibleRootItem(); //先清空model int rowCount = root->rowCount(); if (rowCount > 0) { _treeModel->removeRows(0, rowCount); } } } QString DataSourceDlg::getLevelType(int index) { switch (index) { case 0: return "电网"; case 1: return "区域"; case 2: return "站点"; case 3: return "电压等级"; case 4: return "间隔"; case 5: return "设备"; case 6: return "分组"; default: return "未知层级"; } }