DiagramDesigner/diagramCavas/source/dataSourceDlg.cpp

649 lines
21 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "dataSourceDlg.h"
#include "ui_dataSourceDlg.h"
#include <QStandardItemModel>
#include <QStack>
#include "structDataSource.h"
#include "instance/extraPropertyManager.h"
#include "propertyType/dataSourceType.h"
#include <QTimer>
#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<ExtraPropertyLevelInfo> 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<int>(i)) {
foundChild = child;
break;
}
}
}
if (foundChild) {
currentParent = foundChild;
} else {
QStandardItem* newNode = new QStandardItem(displayText);
QVariantMap levelData;
levelData["levelIndex"] = static_cast<int>(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<ExtraProperty> properties = categoryData["properties"].value<QVector<ExtraProperty>>();
if (properties.isEmpty()) {
// 如果没有属性从DataManager重新获取
properties = getCategoryPropertiesFromDataManager(categoryData);
}
if (properties.isEmpty()) {
clearItems();
return;
}
QTimer::singleShot(50, this, [this,properties]() {
updatePropertyList(properties);
});
}
QVector<ExtraProperty> 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<ExtraProperty> 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<ExtraProperty> properties = categoryData["properties"].value<QVector<ExtraProperty>>();
// 检查属性是否已存在
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<ExtraProperty>());
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<ExtraProperty> 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<ExtraProperty> 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<QStandardItem*> 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>()) {
QVariantMap dataMap = itemData.toMap();
// 检查当前节点是否是category节点
QString levelType = dataMap.value("levelType", "").toString();
if (levelType == "category") {
// 检查category节点的properties列表
if (dataMap.contains("properties")) {
QVector<ExtraProperty> properties = dataMap["properties"].value<QVector<ExtraProperty>>();
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 "未知层级";
}
}