#include "DialogDataLink.h"
#include "PouManager.h"
#include "UiManager.h"
#include "GvlManager.h"
#include "vpControls/VControlObject.h"
#include "vpControls/VImageControl.h"
#include "vpControls/VPieChart.h"
//#include "vpControls/VWaveChart.h"
#include "vpControls/VTableControl.h"
DialogDataLink::DialogDataLink(
const QString& strPropertyName,
VControlObject* pCurrentObject,
const DataLink& value,
QWidget *parent
)
: m_strPropertyName(strPropertyName)
, m_strPropertyShortName(strPropertyName)
, m_pControlObject(pCurrentObject)
, QDialog(parent)
, m_DataLink(value)
{
ui.setupUi(this);
// 特殊需要额外处理的属性名称
m_propertiesNameToType.insert(IMAGE_PROPERTY_EX_MAINLINK_NAME, VALUE_TYPE::Type_HImage);
m_propertiesNameToType.insert(IMAGE_PROPERTY_EX_LINK1_NAME, VALUE_TYPE::Type_HObject);
m_propertiesNameToType.insert(IMAGE_PROPERTY_EX_LINK3_NAME, VALUE_TYPE::Type_HTuple);
m_propertiesNameToType.insert(IMAGE_PROPERTY_EX_LINK5_NAME, VALUE_TYPE::Type_HObject);
m_propertiesNameToType.insert(IMAGE_PROPERTY_EX_LINK7_NAME, VALUE_TYPE::Type_String);
m_propertiesNameToType.insert(IMAGE_PROPERTY_EX_LINK8_NAME, VALUE_TYPE::Type_String);
// 把属性名字后面的数字去掉便于匹配
for (int i = m_strPropertyShortName.size() - 1; i >= 0; i--)
{
QChar c = m_strPropertyShortName[i];
if (c >= '0' && c <= '9')
{
m_strPropertyShortName.remove(c);
}
else
{
break;
}
}
// 对话框初始化
initUI();
// qDebug() << "DialogDataLink::DialogDataLink() - bind m_pControlObject->m_pWidget:" << m_pControlObject->m_pWidget;
}
DialogDataLink::~DialogDataLink()
{
}
///
/// 对话框初始化
///
void DialogDataLink::initUI()
{
this->setWindowTitle(("Data Link"));
this->setAttribute(Qt::WA_QuitOnClose);
this->setWindowModality(Qt::ApplicationModal);
// this->setFocusPolicy(Qt::StrongFocus);
// 去掉帮助提示框
this->setWindowFlags(this->windowFlags() & (~Qt::WindowContextHelpButtonHint));
// 根据不同的控件类型
this->initComboGroup();
// Tree
// 1列
ui.treeTool->setColumnCount(1);
// 隐藏表头
ui.treeTool->setHeaderHidden(true);
// 显示虚线
ui.treeTool->setStyle(QStyleFactory::create("windows"));
// 槽函数
connect(ui.selectButton, SIGNAL(clicked()), this, SLOT(onButtonSelectClicked()));
connect(ui.clearButton, SIGNAL(clicked()), this, SLOT(onButtonClearClicked()));
connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
connect(ui.comboValueGroup, SIGNAL(currentIndexChanged(int)), this, SLOT(onComboGroupChanged(int)));
// 设置固定窗体大小
this->setFixedSize(484, 487);
}
///
/// 初始化数据链接分组
///
void DialogDataLink::initComboGroup()
{
// 首先处理特殊类型
if (m_propertiesNameToType.contains(m_strPropertyShortName))
{
this->initComboGroupByPropertyName();
}
// 2022-5-22 添加字符类型
else if ((m_pControlObject->m_Type == VALUE_TYPE::Control_Image)
&& m_strPropertyShortName == IMAGE_PROPERTY_EX_LINK6_NAME)
{
this->initComboGroupByValue();
}
// 如果是Button类型
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Button)
{
this->initComboGroupByButton();
}
// 如果是Value类型、或者复杂数值类型,都是绑定数值变量的
// TODO 2021-12-7: 此处应该为Complex类型专门设计一个初始化函数,因为需要的变量类型还是不大一样的
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Value
|| m_pControlObject->m_Type == VALUE_TYPE::Control_Result
|| m_pControlObject->isComplexControl()
)
{
this->initComboGroupByValue();
}
// 如果是Label 控件、GroupBox控件,不链接任何接口
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Label
|| m_pControlObject->m_Type == VALUE_TYPE::Control_Groupbox)
{
return;
}
// 如果是其他控件
else
{
this->initComboGroupByOther();
}
// 默认选择ComboBox中的第一项
ui.comboValueGroup->setCurrentIndex(0);
this->onComboGroupChanged(0);
}
///
/// 按照一些特殊的属性名称来分组(例如Image中的图像链接、HObject、HTuple链接等等)
///
void DialogDataLink::initComboGroupByPropertyName()
{
QMap& allPous = g_pPouManager->getAllPous();
// 遍历所有的Pou信息
QMapIterator it(allPous);
// 找出控件类型相同的输出接口,就把这个Pou分组添加进来
while (it.hasNext())
{
if (it.next().value()->containInterface(
m_propertiesNameToType[m_strPropertyShortName],
INF_DIRECTION::INF_DIR_OUT)
)
{
// 添加适配的Pou分组
ui.comboValueGroup->addItem(it.key());
}
}
// // Pou 以及Pou 局部变量,分两个组(含硬件组态) -------------------
//
//// 添加所有tool数量>0的Pou
// QMap& allPous = g_pPouManager->getAllPous();
//
// // 遍历所有的Pou信息
// QMapIterator it(allPous);
//
// while (it.hasNext())
// {
// QString pouName = it.next().key();
//
// // Tool数量>0的添加进来
// if (it.value()->GetAllStandardTools().size() > 0)
// {
// // 添加适配的Pou分组
// ui.comboValueGroup->addItem(pouName);
// }
//
// // 如果局部变量数量 > 0的也添进来
// GVL* pVar = g_pVariablesManager->getVariablesByGroup(pouName);
// if (pVar != nullptr)
// {
// // 添加适配的Pou.Varables分组
// ui.comboValueGroup->addItem(pouName + VAR_SUFFIX);
// }
// }
//
// //// 硬件Pou和局部变量 -------------------------------------
//
// //// 硬件Pou
// //POU* pHdPou = g_pPouManager->getPouByName(CATEGORY_TOOL_HARDWARE);
// //if (pHdPou != nullptr && pHdPou->GetAllStandardTools().size() > 0)
// //{
// // ui.comboValueGroup->addItem(CATEGORY_TOOL_HARDWARE);
// //}
//
// //GVL* pHdVarable = g_pVariablesManager->getVariablesByGroup(CATEGORY_TOOL_HARDWARE);
// //// 如果硬件局部变量的数量>0,那么也添加进来
// //if (pHdVarable != nullptr
// // && pHdVarable->Variables.size() > 0)
// //{
// // ui.comboValueGroup->addItem(CATEGORY_TOOL_HARDWARE + VAR_SUFFIX);
// //}
//
// // 全局变量 -----------------------------------------
//
// ALL_VARIABLES* pAllVariables = g_pVariablesManager->getAllVariables();
// QHashIterator it2(*pAllVariables);
// while (it2.hasNext())
// {
// const GVL* pGvl = it2.next().value();
// // 如果全局变量的数量>0
// if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE
// && pGvl->Variables.size() > 0
// )
// {
// ui.comboValueGroup->addItem(it2.key());
// }
// }
}
///
/// Button 控件
/// 1、链接到系统功能上(SysRun、SysRunOnce、SysStop)
/// 2、链接到输入型的Button控件上
/// 3、链接到任意工具上(点击按钮的时候,等同于双击工具的功能块)
///
void DialogDataLink::initComboGroupByButton()
{
// 添加系统命令分组
ui.comboValueGroup->addItem(SYS_CMD_GROUP_NAME);
// 添加所有的Pou中的所有工具
// 获取所有Pou
QMap& allPous = g_pPouManager->getAllPous();
// 遍历所有的Pou信息
QMapIterator it(allPous);
// 只要Tool数量>0的就添加进来
while (it.hasNext())
{
if (it.next().value()->GetAllStandardTools().size()>0 )
{
// 添加适配的Pou分组
ui.comboValueGroup->addItem(it.key());
}
}
}
///
/// 按ValueControl类型初始化分组
/// 1、链接到输出型的任意数据类型端口上 (单向同步,用于任意输出型变量的String化展示),一对多
/// 同步规则:
///(1)tool变动时,向UI和Runtime所有链接的控件实时同步;
///(2)UI变动时,不做任何同步动作;
/// (3) runtime变动时,不做任何同步动作;
/// 2、链接到输入型的基础数据类型端口上 (单向同步,RunTime Edit->工具)一对一
/// 同步规则:
///(1)tool变动时,UI和Runtime 不做任何动作;
///(2)UI变动时,同步到Runtime和tool中;
///(3)Runtime变动时,同步到UI和tool中。
/// 注意本数据连接同样作为端口的连接,需要引用计数 + 1
/// 3、该控件需要链接到任意全局变量和硬件组态的局部变量
/// 4、 不允许链接到控件类型端口(控件类型端口同样也以字符串的形式展示)
///
void DialogDataLink::initComboGroupByValue()
{
// Pou 以及Pou 局部变量,分两个组(含硬件组态) -------------------
// 添加所有tool数量>0的Pou
QMap& allPous = g_pPouManager->getAllPous();
// 遍历所有的Pou信息
QMapIterator it(allPous);
while (it.hasNext())
{
QString pouName = it.next().key();
// Tool数量>0的添加进来
if (it.value()->GetAllStandardTools().size() > 0)
{
// 添加适配的Pou分组
ui.comboValueGroup->addItem(pouName);
}
// 如果局部变量数量 > 0的也添进来
GVL* pVar = g_pGvlManager->getGvl(pouName);
if (pVar != nullptr && pouName != GROUP_NAME_HARDWARE)
{
// 添加适配的Pou.Varables分组
ui.comboValueGroup->addItem(pouName + VAR_SUFFIX);
}
}
//// 硬件Pou和局部变量 -------------------------------------
//// 硬件Pou
//POU* pHdPou = g_pPouManager->getPouByName(CATEGORY_TOOL_HARDWARE);
//if (pHdPou != nullptr && pHdPou->GetAllStandardTools().size() > 0)
//{
// ui.comboValueGroup->addItem(CATEGORY_TOOL_HARDWARE);
//}
//GVL* pHdVarable = g_pVariablesManager->getVariablesByGroup(CATEGORY_TOOL_HARDWARE);
//// 如果硬件局部变量的数量>0,那么也添加进来
//if (pHdVarable != nullptr
// && pHdVarable->Variables.size() > 0)
//{
// ui.comboValueGroup->addItem(CATEGORY_TOOL_HARDWARE + VAR_SUFFIX);
//}
// 全局变量 -----------------------------------------
GVLS* pAllVariables = g_pGvlManager->getAllGvls();
QMapIterator it2(*pAllVariables);
while (it2.hasNext())
{
const GVL* pGvl = it2.next().value();
// 不加判断,偶尔会崩溃 2022-02-12
if (pGvl != nullptr && !pGvl->isDefaultValueGroup())
{
// 如果全局变量的数量>0
if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE
&& pGvl->Variables.size() > 0
)
{
ui.comboValueGroup->addItem(it2.key());
}
}
}
}
///
/// Edit、RadioBox、ListBox、ComboBox、CheckBox控件
/// 1、链接到输入型号的控件端口上,(不需要实现)
/// 2、链接到输出型的控件端口上(三向同步),一对一
/// 同步规则:
///(1)tool变动时,向UI和Runtime实时同步;
/// (2) UI变动时,向tool和Runtime实时同步;
/// (3) Runtime变动时,向tool和UI实时同步。
/// 3、不允许链接到非控件型端口
///
void DialogDataLink::initComboGroupByOther()
{
QMap& allPous = g_pPouManager->getAllPous();
// 遍历所有的Pou信息
QMapIterator it(allPous);
// 找出控件类型相同的输出接口,就把这个Pou分组添加进来
while (it.hasNext())
{
if (it.next().value()->containInterface(m_pControlObject->m_Type, INF_DIRECTION::INF_DIR_OUT))
{
// 添加适配的Pou分组
ui.comboValueGroup->addItem(it.key());
}
}
// //// 硬件Pou和局部变量 -------------------------------------
//
// //// 硬件Pou
// //POU* pHdPou = g_pPouManager->getPouByName(CATEGORY_TOOL_HARDWARE);
// //if (pHdPou != nullptr && pHdPou->GetAllStandardTools().size() > 0)
// //{
// // ui.comboValueGroup->addItem(CATEGORY_TOOL_HARDWARE);
// //}
//
// //GVL* pHdVarable = g_pVariablesManager->getVariablesByGroup(CATEGORY_TOOL_HARDWARE);
// //// 如果硬件局部变量的数量>0,那么也添加进来
// //if (pHdVarable != nullptr
// // && pHdVarable->Variables.size() > 0)
// //{
// // ui.comboValueGroup->addItem(CATEGORY_TOOL_HARDWARE + VAR_SUFFIX);
// //}
//
// // 全局变量 -----------------------------------------
//
// ALL_VARIABLES* pAllVariables = g_pVariablesManager->getAllVariables();
// QHashIterator it2(*pAllVariables);
// while (it2.hasNext())q
// {
// const GVL* pGvl = it2.next().value();
// // 如果全局变量的数量>0
// if (pGvl->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE
// && pGvl->Variables.size() > 0
// )
// {
// ui.comboValueGroup->addItem(it2.key());
// }
// }
}
///
/// Combo框选择变更时,需要切换对应的变量列表
///
///
void DialogDataLink::onComboGroupChanged(int nIndex)
{
Q_UNUSED(nIndex);
// 先将当前的树形控件及对应数据结构全部清空
ui.treeTool->clear();
// 获取当前选中的分组名称
QString strGroup = ui.comboValueGroup->currentText();
// 如果当前选择的是系统命令组,则显示对应的系统命令
if (strGroup == SYS_CMD_GROUP_NAME)
{
AddSystemCmdToTree();
}
// 如果是Pou分组
else if(g_pPouManager->isPou(strGroup))
{
AddPouToolsToTree(strGroup);
}
// 如果是全局变量分组
else if (g_pGvlManager->isGlobalGvl(strGroup))
{
AddPouVariablesToTree(strGroup);
}
// 如果是Pou局部变量分组
else if (strGroup.contains(VAR_SUFFIX))
{
// 去掉后缀找到真正的变量分组名称
strGroup.remove(VAR_SUFFIX);
AddPouVariablesToTree(strGroup);
}
// 无效分组(不应该执行到这里)
else if(!strGroup.isEmpty())
{
qWarning() << "DialogDataLink - Invalid value group[" << strGroup << "].";
}
// 将树形结构展开
ui.treeTool->expandAll();
}
///
/// 添加系统命令
///
void DialogDataLink::AddSystemCmdToTree()
{
// 首先添加几个Task相关命令
QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(QString(SYS_CMD_TASK_RUN)));
newItem->setIcon(0, QIcon("./image/gvl_group_tree_item.png"));
ui.treeTool->addTopLevelItem(newItem);
newItem = new QTreeWidgetItem(QStringList(QString(SYS_CMD_TASK_RUNONCE)));
newItem->setIcon(0, QIcon("./image/gvl_group_tree_item.png"));
ui.treeTool->addTopLevelItem(newItem);
newItem = new QTreeWidgetItem(QStringList(QString(SYS_CMD_TASK_STOP)));
newItem->setIcon(0, QIcon("./image/gvl_group_tree_item.png"));
ui.treeTool->addTopLevelItem(newItem);
// 然后添加可以切换的界面
newItem = new QTreeWidgetItem(QStringList(QString(SYS_CMD_UI_SWITCH)));
newItem->setIcon(0, QIcon("./image/gvl_group_tree_item.png"));
ui.treeTool->addTopLevelItem(newItem);
// 添加当前所有的设计页面信息
QStringList uiLIst = g_pUiManager->getAllUiNames();
for (QString strName : uiLIst)
{
QTreeWidgetItem* uiItem = new QTreeWidgetItem(newItem, QStringList(strName));
uiItem->setIcon(0, QIcon(":/image/Input.png"));
newItem->addChild(uiItem);
}
}
///
/// 添加选中的Pou Tool
///
///
void DialogDataLink::AddPouToolsToTree(const QString& strGroup)
{
// 添加兼容的Pou工具到界面中
POU* pPou = g_pPouManager->getPouByName(strGroup);
// 2022-1-16,为特殊的字段进行特殊处理
if (m_propertiesNameToType.contains(m_strPropertyShortName))
{
this->AddPouToolsByPropertyName(pPou);
}
// 如果是Button类型
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Button)
{
this->AddPouToolsByButton(pPou);
}
// 如果是Value类型
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Value)
{
this->AddPouToolsByValue(pPou);
}
// 如果是Value类型
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Result)
{
this->AddPouToolsByValue(pPou);
}
// 如果是Image类型
else if ((m_pControlObject->m_Type == VALUE_TYPE::Control_Image)
&& (m_strPropertyShortName == IMAGE_PROPERTY_EX_LINK6_NAME)
)
{
this->AddPouToolsByValue(pPou);
}
// 如果是复杂控件类型
else if (m_pControlObject->isComplexControl())
{
this->AddPouToolsByComplexValue(pPou);
}
// 如果是Label 控件、GroupBox控件,不添加任何信息(应该不会走到这里)
else if (m_pControlObject->m_Type == VALUE_TYPE::Control_Label
|| m_pControlObject->m_Type == VALUE_TYPE::Control_Groupbox)
{
return;
}
// 如果是其他控件
else
{
this->AddPouToolsByOther(pPou);
}
}
///
/// 按Button类型添加Pou Tool
/// 注:Button支持所有的Tool(双击打开Tool的对话框),但是只支持Button*类型的接口
///
void DialogDataLink::AddPouToolsByButton(POU* pPou)
{
// 获取所有标准工具
const QVector& allTools = pPou->GetAllStandardTools();
// 遍历所有的工具
QVectorIterator i(allTools);
while (i.hasNext())
{
const TOOL* pTool = i.next();
// 按照工具名称添加节点
QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
// 继续添加接口
for (_INTERFACE* pInf : pTool->Interfaces)
{
// 接口可用,且是Button类型的(忽略输入还是输出,全部链接)
if (pInf->bEnable
&& pInf->value.type == m_pControlObject->m_Type)
{
AddInterfaceTreeItem(pToolItem, pInf);
}
}
}
}
///
/// 按Value数值类型添加Pou Tool
/// ValueControl支持Pou中的非控件类型输入输出、全局变量、硬件局部变量
///
void DialogDataLink::AddPouToolsByValue(POU* pPou)
{
// 获取所有标准工具
const QVector& allTools = pPou->GetAllStandardTools();
// 遍历所有的工具
QVectorIterator i(allTools);
while (i.hasNext())
{
const TOOL* pTool = i.next();
// 按照工具名称添加节点
QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
// 继续添加接口
int nInfCount = 0;
for (_INTERFACE* pInf : pTool->Interfaces)
{
// 过滤掉隐藏接口,过滤掉控件类型,支持其他所有数据类型
if ( pInf->bEnable
&& pInf->Type!=INF_TYPE::INF_TYPE_CONTROL )
{
// 符合过滤条件的接口添加到列表中
AddInterfaceTreeItem(pToolItem, pInf);
nInfCount++;
}
}
// 如果没有有效的接口,则删除掉刚刚添加的Tool节点
if (nInfCount <= 0)
{
ui.treeTool->removeItemWidget(pToolItem, 0);
delete(pToolItem);
}
}
}
///
/// 按复杂控件类型添加Pou Tool
/// 只支持数值类型接口
///
///
void DialogDataLink::AddPouToolsByComplexValue(POU* pPou)
{
// 获取所有标准工具
const QVector& allTools = pPou->GetAllStandardTools();
// 遍历所有的工具
QVectorIterator i(allTools);
while (i.hasNext())
{
const TOOL* pTool = i.next();
// 按照工具名称添加节点
QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
// 继续添加接口
int nInfCount = 0;
for (_INTERFACE* pInf : pTool->Interfaces)
{
// 过滤掉隐藏接口
// 只支持基础的数值类型
// 只要输出接口
if (pInf->bEnable
&& pInf->isBaseValueType()
&& pInf->Direction == INF_DIRECTION::INF_DIR_OUT
)
{
// 符合过滤条件的接口添加到列表中
AddInterfaceTreeItem(pToolItem, pInf);
nInfCount++;
}
}
// 如果没有有效的接口,则删除掉刚刚添加的Tool节点
if (nInfCount <= 0)
{
ui.treeTool->removeItemWidget(pToolItem, 0);
delete(pToolItem);
}
}
}
///
/// 按其他控件类型添加Pou Tool
/// 只支持所有Pou里的相同输出控件类型
///
void DialogDataLink::AddPouToolsByOther(POU* pPou)
{
// 获取所有标准工具
const QVector& allTools = pPou->GetAllStandardTools();
// 遍历所有的工具
QVectorIterator i(allTools);
while (i.hasNext())
{
const TOOL* pTool = i.next();
// 按照工具名称添加节点
QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
// 继续添加接口
int nInfCount = 0;
for (_INTERFACE* pInf : pTool->Interfaces)
{
// 必须是可用接口,并且接口类型一致的输出接口
if (pInf->bEnable
&& pInf->Direction ==INF_DIRECTION::INF_DIR_OUT
&& pInf->value.type == m_pControlObject->m_Type
)
{
// 符合过滤条件的接口添加到列表中
AddInterfaceTreeItem(pToolItem, pInf);
nInfCount++;
}
}
// 如果没有有效的接口,则删除掉刚刚添加的Tool节点
if (nInfCount <= 0)
{
ui.treeTool->removeItemWidget(pToolItem, 0);
delete(pToolItem);
}
}
}
///
/// 按照一些特殊的属性名称添加Pou Tool
///
///
void DialogDataLink::AddPouToolsByPropertyName(POU* pPou)
{
// 获取所有标准工具
const QVector& allTools = pPou->GetAllStandardTools();
// 遍历所有的工具
QVectorIterator i(allTools);
while (i.hasNext())
{
const TOOL* pTool = i.next();
// 按照工具名称添加节点
QTreeWidgetItem* pToolItem = AddToolTreeItem(pTool->strInstanceName);
// 继续添加接口
int nInfCount = 0;
for (_INTERFACE* pInf : pTool->Interfaces)
{
// 必须是可用接口,并且接口类型一致的输出接口
if (pInf->bEnable
&& pInf->Direction == INF_DIRECTION::INF_DIR_OUT
&& pInf->value.type == m_propertiesNameToType[m_strPropertyShortName]
)
{
// 符合过滤条件的接口添加到列表中
AddInterfaceTreeItem(pToolItem, pInf);
nInfCount++;
}
}
// 如果没有有效的接口,则删除掉刚刚添加的Tool节点
if (nInfCount <= 0)
{
ui.treeTool->removeItemWidget(pToolItem, 0);
delete(pToolItem);
}
}
}
///
/// 添加兼容的Pou变量到树形结构中
///
///
///
void DialogDataLink::AddPouVariablesToTree(const QString& strGroup)
{
// 获取指定的变量
GVL* pGVL = g_pGvlManager->getGvl(strGroup);
// 根据类型添加不同的表头
QStringList title;
if (pGVL->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE)
{
title << GROUP_GLOBAL_VARIABLE;
}
else
{
title << GROUP_LOCAL_VARIABLE;
}
// 添加父节点
QTreeWidgetItem* pGroupItem = new QTreeWidgetItem(QStringList(title));
pGroupItem->setIcon(0, QIcon(":/image/gvl_group_tree_item.png"));
pGroupItem->setFlags(Qt::ItemIsEnabled);
ui.treeTool->addTopLevelItem(pGroupItem);
// 继续添加变量(Value以及所有的复杂控件都支持变量数值类型)
const VARIABLES& vars = pGVL->Variables;
for (const VARIABLE* var : vars)
{
if (var->bEnable)
{
// 2021-12-8 如果是复杂类型,需要做一下进一步的过滤
if (m_pControlObject->isComplexControl())
{
// 只要基础数值类型和输出接口
if (!(var->isBaseValueType()
&& var->isDirOutput()))
{
continue;
}
}
AddInterfaceTreeItem(pGroupItem, var);
}
}
}
///
/// 添加Tool子节点
///
///
QTreeWidgetItem* DialogDataLink::AddToolTreeItem(const QString& toolName)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList(toolName));
newItem->setIcon(0, QIcon(":/image/tool_tree_item.png"));
// 除了Button类型可以选中父节点之外,别的类型都不允许选中父节点
if (m_pControlObject->m_Type != VALUE_TYPE::Control_Button)
{
newItem->setFlags(Qt::ItemIsEnabled);
}
ui.treeTool->addTopLevelItem(newItem);
return newItem;
}
///
/// 添加接口子节点
///
void DialogDataLink::AddInterfaceTreeItem(QTreeWidgetItem* pToolItem, const _INTERFACE* pInf)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(pToolItem, QStringList(pInf->strNameWithType));
if (pInf->Direction == INF_DIRECTION::INF_DIR_OUT)
{
newItem->setIcon(0, QIcon(":/image/Output.png"));
}
else
{
newItem->setIcon(0, QIcon(":/image/Input.png"));
}
pToolItem->addChild(newItem);
}
///
/// 获取DataLink
///
///
DataLink DialogDataLink::getValue() const
{
return m_DataLink;
}
///
/// 设置DataLink
///
///
void DialogDataLink::setValue(const DataLink& value)
{
m_DataLink = value;
// ui.testEdit->setText(m_strInputValue);
// TODO : 根据用户选择的值,将值同步到界面中
}
///
/// select按钮
///
void DialogDataLink::onButtonSelectClicked()
{
// 获取用户选择的节点
QList selItems = ui.treeTool->selectedItems();
// 如果尚未选择节点则报错
if (selItems.size() <= 0)
{
Utility::VPCriticalMessageBox(" The item selected is invalid!");
return;
}
// 清空之后重新选择
m_DataLink.value.clear();
// 获取选中的Item
QTreeWidgetItem* selItem = selItems[0];
// TODO: 此处需要根据DataLink的索引值关联到对应的控件DataLink序列中
// 保存Button控件选择信息
if (m_pControlObject->m_Type == VALUE_TYPE::Control_Button)
{
this->saveSelectionByButton(selItem);
}
// 保存其他控件类型选择信息
else
{
this->saveSelectionByOther(selItem);
}
this->accept();
}
///
/// clear按钮(用于清空DataLink信息)
///
void DialogDataLink::onButtonClearClicked()
{
// 确认清除数据连接信息
QMessageBox::StandardButton ret = QUESTION_MESSAGE("Are you sure to clear the DataLink information?");
if (ret == QMessageBox::Yes)
{
m_DataLink.value.clear();
// 将界面设置未选中状态
ui.comboValueGroup->setCurrentIndex(0);
INFORMATION_MESSAGE("Clear DataLink information finished.");
this->accept();
}
}
///
/// 保存Button类型的相关信息
///
bool DialogDataLink::saveSelectionByButton(QTreeWidgetItem* pItem)
{
// 不允许选中UI顶层节点
if (pItem->text(0) == SYS_CMD_UI_SWITCH)
{
Utility::VPCriticalMessageBox(" The item selected is invalid!");
return false;
}
m_DataLink.value.clear();
// 分组信息
m_DataLink.value << ui.comboValueGroup->currentText();
// 保存信息
// 如果选择的是顶层节点(几个系统命令或者是Tool本身)
if(ui.treeTool->indexOfTopLevelItem(pItem)!=-1)
{
// 保存子类别和子项
m_DataLink.value << pItem->text(0);
m_DataLink.value << " ";
}
// UI切换选项和Tool导出的Button工具
else
{
// 保存子类别和子项
m_DataLink.value << pItem->parent()->text(0);
// 去掉子项中的类型名称后缀
QString strDetail = pItem->text(0);
strDetail = strDetail.left(strDetail.indexOf("<") - 1);
m_DataLink.value << strDetail;
// m_pControlObject->m_Property.m_DataLink = m_DataLink;
// 绑定指针用于后续同步
if (!g_pUiManager->bindDataLinkSyncInformation(m_DataLink, m_pControlObject))
{
return false;
}
}
return true;
}
///
/// 保存其他类型的选择信息
///
bool DialogDataLink::saveSelectionByOther(QTreeWidgetItem* pItem)
{
// 不允许选择顶层节点
if (ui.treeTool->indexOfTopLevelItem(pItem) != -1)
{
Utility::VPCriticalMessageBox(" The item selected is invalid!");
return false;
}
// 保存信息
// 分组
m_DataLink.value << ui.comboValueGroup->currentText();
// 子类别
m_DataLink.value << pItem->parent()->text(0);
// 子项
// 去掉子项中的类型名称后缀
QString strDetail = pItem->text(0);
strDetail = strDetail.left(strDetail.indexOf("<") - 1);
m_DataLink.value << strDetail;
// 2022-2-10,在此之前需要先解绑旧的接口绑定信息
// 根据属性名找到对应的DataLink
const DataLink& lastDataLink = m_pControlObject->getDataLinkByProperty(m_strPropertyName);
// 如果存在旧的绑定信息,先执行解绑
if (lastDataLink.isValid())
{
g_pUiManager->unbindDataLinkSyncInformation(lastDataLink, m_pControlObject);
}
// 绑定指针用于后续同步
if (!g_pUiManager->bindDataLinkSyncInformation(m_DataLink, m_pControlObject))
{
return false;
}
return true;
}