#include "WindowAppResourceManagerTree.h"
#include "DialogNewPou.h"
#include "DialogNewGVL.h"
#include "DialogNewTask.h"
#include "DialogNewUI.h"
#include "WindowAppPouFrame.h"
#include "PouManager.h"
#include "TaskManager.h"
#include "WindowAppMdiFrame.h"
#include "WindowAppMdiSubContainer.h"
#include "WindowAppTaskView.h"
#include "WindowAppTaskMonitorView.h"
#include "WindowAppUiFrame.h"
#include "WindowApp.h"
#include "UiManager.h"
#include "Document.h"
// 各个节点的名称
#define NODE_NAME_GVL "全局变量组"
#define NODE_NAME_PROGRAM "程序管理器"
#define NODE_NAME_TASKMANAGER "任务管理器"
#define NODE_NAME_UIDESIGN "页面设计器"
#define NODE_NAME_USER "用户管理器"
#define NODE_NAME_HARDWARE "外部硬件管理器"
WindowAppResourceManagerTree::WindowAppResourceManagerTree(QTreeWidget* parent)
: QTreeWidget(parent)
{
// 响应自定义右键菜单
this->setContextMenuPolicy(Qt::CustomContextMenu);
// 创建界面布局
createLayouts();
// 创建各个节点的右键菜单
createMenus();
VPGlobal::Register(this);
m_pMdiFrame = nullptr;
}
WindowAppResourceManagerTree::~WindowAppResourceManagerTree()
{
}
///
/// 创建界面布局
///
void WindowAppResourceManagerTree::createLayouts()
{
// 1列
this->setColumnCount(1);
// 隐藏表头
this->setHeaderHidden(true);
// this->setHeaderLabel(("TaskBox"));
// 显示虚线
this->setStyle(QStyleFactory::create("windows"));
this->setStyleSheet("QTreeView::branch:has-children:!has-siblings:closed,\
QTreeView::branch:closed:has-children:has-siblings{border-image: none; image: url(:/image/btn_down_black.png);}\
QTreeView::branch:open:has-children:!has-siblings,\
QTreeView::branch:open:has-children:has-siblings{border-image: none; image: url(:/image/btn_up_black.png);}");
// 各个根节点的名称
m_appNodeNames.push_back((NODE_NAME_GVL));
m_appNodeNames.push_back((NODE_NAME_PROGRAM));
m_appNodeNames.push_back((NODE_NAME_TASKMANAGER));
m_appNodeNames.push_back((NODE_NAME_UIDESIGN));
m_appNodeNames.push_back((NODE_NAME_USER));
QFont fontFollowNode;
fontFollowNode.setPointSize(8);
fontFollowNode.setBold(true);
fontFollowNode.setUnderline(true);
fontFollowNode.setWeight(75);
fontFollowNode.setStrikeOut(false);
QFont fontChildNode;
fontChildNode.setPointSize(8);
fontChildNode.setBold(true);
// 创建各个根节点
// QList items;
this->setFocusPolicy(Qt::NoFocus);
//屏蔽节点双击事件
this->setExpandsOnDoubleClick(false);
// 所有节点自动展开
this->setItemsExpandable(false);
m_appNodeIcons.append(QIcon(":/image/GVL.png"));
m_appNodeIcons.append(QIcon(":/image/Program.png"));
m_appNodeIcons.append(QIcon(":/image/Task.png"));
m_appNodeIcons.append(QIcon(":/image/UI.png"));
m_appNodeIcons.append(QIcon(":/image/Authority.png"));
m_appNodeIcons.append(QIcon(":/image/Authority.png"));
m_appNodeIcons.append(QIcon(":/image/User.png"));
// 创建App根节点
topAppItem = new QTreeWidgetItem(this, QStringList("应用程序管理器"));
topAppItem->setIcon(0, QIcon(":/image/Option.png"));
topAppItem->setFont(0, fontFollowNode);
// 创建App各子节点
for (int i = 0; i < (short)SUBVIEW_TYPE::SUBVIEW_COUNT; i++)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(topAppItem, QStringList(m_appNodeNames[i]));
newItem->setIcon(0, m_appNodeIcons[i]);
newItem->setFont(0, fontChildNode);
m_rootNodes.append(newItem);
}
// 创建App下的任务管理和调试窗口
topDebugItem = new QTreeWidgetItem(this, QStringList("调试信息管理器"));
topDebugItem->setIcon(0, QIcon(":/image/Hardware.png"));
topDebugItem->setFont(0, fontFollowNode);
// 默认的 App - Debug - TaskMonitor 节点
QTreeWidgetItem* TaskMonitorItem = new QTreeWidgetItem(topDebugItem, QStringList(GROUP_NAME_TASKMONITOR));
TaskMonitorItem->setIcon(0, QIcon(":/image/Com.png"));
TaskMonitorItem->setFont(0, fontChildNode);
// 默认的 App - Log - LogView 节点
QTreeWidgetItem* LogViewItem = new QTreeWidgetItem(topDebugItem, QStringList(GROUP_NAME_LOGVIEW));
LogViewItem->setIcon(0, QIcon(":/image/Cam.png"));
LogViewItem->setFont(0, fontChildNode);
// 创建硬件组,未来调整为子节点同步与硬件组态的工具(每个添加一个硬件到硬件组态,同步添加一个子节点)
topHardwareItem = new QTreeWidgetItem(this, QStringList("外部硬件管理器"));
topHardwareItem->setIcon(0, QIcon(":/image/Hardware.png"));
topHardwareItem->setFont(0, fontFollowNode);
// 默认的 Hardware - HDW Config节点
QTreeWidgetItem* ConfigItem = new QTreeWidgetItem(topHardwareItem, QStringList(GROUP_NAME_HARDWARE));
ConfigItem->setIcon(0, QIcon(":/image/HDWConf.png"));
ConfigItem->setFont(0, fontChildNode);
// 设置根节点风格
this->setRootIsDecorated(true);
// 设置所有的节点皆可以展开
this->setItemsExpandable(true);
// 默认展开所有节点
this->expandAll();
}
///
/// 创建各个节点的右键菜单
///
void WindowAppResourceManagerTree::createMenus()
{
// 根节点的菜单
m_menuGVLRoot = new QMenu(this);
m_menuPouRoot = new QMenu(this);
m_menuTaskRoot = new QMenu(this);
m_menuUiRoot = new QMenu(this);
// 子节点的菜单
m_menuGVLChild = new QMenu(this);
m_menuPouChild = new QMenu(this);
m_menuTaskChild = new QMenu(this);
m_menuUiChild = new QMenu(this);
m_menuScriptChild = new QMenu(this);
// GVL Action
m_actionGVLNew = new QAction(("New Gvl"), this);
m_actionGVLEdit = new QAction(("Edit Gvl"), this);
m_actionGVLRename = new QAction(("Rename Gvl"), this);
m_actionGVLDelete = new QAction(("Delete Gvl"), this);
// Pou Action
m_actionPouNew = new QAction(("New Pou"), this);
m_actionPouRename = new QAction(("Rename Pou"), this);
m_actionPouChangeMode = new QAction(("Change to Block Mode"), this);
m_actionPouDelete = new QAction(("Delete Pou"), this);
m_actionPouExport = new QAction(("Export Pou"), this);
m_actionPouImport = new QAction(("Import Pou"), this);
// Task Action
m_actionTaskNew = new QAction(("New Task"), this);
m_actionTaskAddPou = new QAction(("Add Pou"), this);
//m_actionTaskRename = new QAction(("Rename Task"), this);
m_actionTaskDelete = new QAction(("Delete Task"), this);
// UI Action
m_actionUiNew = new QAction(("New UI"), this);
m_actionUiMainPage = new QAction("Set main page", this);
m_actionUiDelete = new QAction(("Delete"), this);
// 添加Action
m_menuGVLRoot->addAction(m_actionGVLNew);
m_menuGVLChild->addAction(m_actionGVLEdit);
m_menuGVLChild->addAction(m_actionGVLRename);
m_menuGVLChild->addSeparator();
m_menuGVLChild->addAction(m_actionGVLDelete);
m_menuPouRoot->addAction(m_actionPouNew);
m_menuPouRoot->addAction(m_actionPouImport);
m_menuPouChild->addAction(m_actionPouExport);
m_menuPouChild->addSeparator();
m_menuPouChild->addAction(m_actionPouRename);
m_menuPouChild->addAction(m_actionPouDelete);
m_menuPouChild->addSeparator();
m_menuPouChild->addAction(m_actionPouChangeMode);
m_menuTaskRoot->addAction(m_actionTaskNew);
m_menuTaskChild->addAction(m_actionTaskAddPou);
//m_menuTaskChild->addAction(m_actionTaskRename);
m_menuTaskChild->addSeparator();
m_menuTaskChild->addAction(m_actionTaskDelete);
m_menuUiRoot->addAction(m_actionUiNew);
m_menuUiChild->addAction(m_actionUiDelete);
m_menuUiChild->addAction(m_actionUiMainPage);
// 右键菜单
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onTreeContextMenu(const QPoint&)));
// 双击事件
connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(onTreeItemDblClicked(QTreeWidgetItem*, int)));
// 菜单响应函数
connect(m_menuGVLRoot, SIGNAL(triggered(QAction*)), this, SLOT(onMenuGVL(QAction*)));
connect(m_menuGVLChild, SIGNAL(triggered(QAction*)), this, SLOT(onMenuGVL(QAction*)));
connect(m_menuPouRoot, SIGNAL(triggered(QAction*)), this, SLOT(onMenuPou(QAction*)));
connect(m_menuPouChild, SIGNAL(triggered(QAction*)), this, SLOT(onMenuPou(QAction*)));
connect(m_menuTaskRoot, SIGNAL(triggered(QAction*)), this, SLOT(onMenuTask(QAction*)));
connect(m_menuTaskChild, SIGNAL(triggered(QAction*)), this, SLOT(onMenuTask(QAction*)));
connect(m_menuUiRoot, SIGNAL(triggered(QAction*)), this, SLOT(onMenuUI(QAction*)));
connect(m_menuUiChild, SIGNAL(triggered(QAction*)), this, SLOT(onMenuUI(QAction*)));
}
///
/// 查找子节点
///
///
QTreeWidgetItem* WindowAppResourceManagerTree::findChildItem(const QString& strItemName)
{
QTreeWidgetItemIterator it(this);
while (*it)
{
QString strText = (*it)->text(0);
if (strText == strItemName)
{
return *it;
}
++it;
}
return nullptr;
}
///
/// 删除所有子节点
///
void WindowAppResourceManagerTree::removeAllSubNodes()
{
// 先收起所有子节点
// this->collapseAll();
// 遍历删除所有根节点下的子节点
for(QTreeWidgetItem * rootNode : m_rootNodes)
{
int itemChildrenCounts = rootNode->childCount();
while (itemChildrenCounts--)
{
QTreeWidgetItem* child = rootNode->child(itemChildrenCounts);
//// 不删除 Task Monitor的节点
//if (child->text(0) == TASKMONITOR_GROUP_NAME)
//{
// continue;
//}
rootNode->removeChild(child);
delete child;
child = nullptr;
}
}
// 设置当前项为空
this->setCurrentItem(nullptr);
// 最后打开所有节点
// this->expandAll();
}
///
/// 2022-2-22 创建默认的几个视图
///
void WindowAppResourceManagerTree::initDefaultViews()
{
// 创建默认的Task视图
this->addDefaultTaskMonitorNode(GROUP_NAME_TASKMONITOR);
// 创建默认的Log视图
this->addDefaultLogViewNode(GROUP_NAME_LOGVIEW);
// 创建默认的Hdw视图(TODO,此处应该加入加载硬件组态的逻辑)
this->addDefaultHWConfigViewNode(GROUP_NAME_HARDWARE);
}
///
/// 2022-2-22 创建默认的几个节点
///
void WindowAppResourceManagerTree::initDefaultNodes()
{
// 创建默认的测试视图(For Test)
this->addUiNode("UI_1", false);
// 创建默认的Pou视图
this->addPouNode("POU_1", false);
// 创建默认的GVL视图
this->addGvlNode("GVL_1", GVL_MODE::GVL_STANDARD, nullptr, false);
// 创建默认的Task视图
this->initDefaultTaskNodes("Task_1");
}
///
/// 创建初始 Task 节点
///
///
void WindowAppResourceManagerTree::initDefaultTaskNodes(QString strTaskName)
{
WindowAppTaskView* pTaskView = (WindowAppTaskView*)this->addTaskNode(strTaskName, false);
// 将用户输入的Task参数绑定到视图中
TASK_OPTION option;
option.strName = strTaskName;
pTaskView->addNewTask(option);
QVector pPous;
// const QMap& allPous = g_pPouManager->getAllPous();
// // 遍历所有的Pou信息
// QMapIterator it(allPous);
// while (it.hasNext())
// {
// QString strPouGroupName = it.next().key();
// // 需要跳过Hardware以及功能块类型的Pou
// if (strPouGroupName == GROUP_NAME_HARDWARE)
// {
// continue;
// }
// POU* pPou = it.value();
// pPous.push_back(pPou);
// }
QString strPouName = "POU_1";
POU* pPou = g_pPouManager->getPouByName(strPouName);
if (pPou != nullptr)
{
pPous.push_back(pPou);
}
pTaskView->addTaskPous(pPous);
addPouNodeToTask(strPouName, strTaskName);
}
///
/// 添加一个Pou节点
///
///
QWidget* WindowAppResourceManagerTree::addPouNode(QString strName, bool bActive)
{
// 2021/6/25增加,首先查找这个节点是否存在,如果存在则不重复添加了,直接返回对应指针
QWidget* pSubView = m_pMdiFrame->findSubView(strName);
if (pSubView == nullptr)
{
// 树形结构中添加一个节点(如果此节点不存在的话)
if (!this->findChildItem(strName))
{
addChildItem(SUBVIEW_TYPE::SUBVIEW_POU, strName);
}
// 然后添加对应的子窗口视图
return m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_POU, bActive);
}
else
{
return pSubView;
}
}
///
/// 添加一个GVL节点
///
///
QWidget* WindowAppResourceManagerTree::addGvlNode(QString strName, GVL_MODE gvlType, DllTool* pHdwTool, bool bActive)
{
// 2021/6/25增加,首先查找这个节点是否存在,如果存在则不重复添加了,直接返回对应指针
QWidget* pSubView = m_pMdiFrame->findSubView(strName);
if (pSubView == nullptr)
{
// 树形结构中添加一个节点
addChildItem(SUBVIEW_TYPE::SUBVIEW_GVL, strName);
// 然后添加对应的子窗口视图,并返回新视图指针
return m_pMdiFrame->addGvlSubView(strName, gvlType, pHdwTool, bActive);
}
else
{
return pSubView;
}
}
///
/// 添加一个Task节点
///
///
///
QWidget* WindowAppResourceManagerTree::addTaskNode(QString strName, bool bActive)
{
QWidget* pSubView = m_pMdiFrame->findSubView(strName);
if (pSubView == nullptr)
{
// 树形结构中添加一个节点
addChildItem(SUBVIEW_TYPE::SUBVIEW_TASK, strName);
// 然后添加对应的子窗口视图,并返回新视图指针
return m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_TASK, bActive);
}
else
{
return pSubView;
}
}
///
/// 添加一个UI节点
///
///
///
/// 是否从反序列化中恢复
///
QWidget* WindowAppResourceManagerTree::addUiNode(QString strName, bool bActive, bool bFromDoc)
{
QWidget* pSubView = m_pMdiFrame->findSubView(strName);
if (pSubView == nullptr)
{
bool bMainPage = false;
// 2022-10-16 增加,如果是从反序列化中来,则有Main后缀的页面会被设定为主页
if (bFromDoc)
{
if (strName.indexOf(UI_MAINPAGE_POSTFIX) >= 0)
{
bMainPage = true;
}
}
// 如果不是从反序列化中来,则根据页面数量设定主页
else
{
// 如果只有一个页面,那这个页面就是主页
if (g_pUiManager->getAllUiNames().size() <= 0)
{
strName += UI_MAINPAGE_POSTFIX;
bMainPage = true;
}
}
// 树形结构中添加一个节点
addChildItem(SUBVIEW_TYPE::SUBVIEW_UI, strName);
// 然后添加对应的子窗口视图,并返回新视图指针
// 2022-9-21,如果需要通过激活的页面来到树形结构里进行反查的话,那么带(main)的主页是会搜索不到的
// 这里干脆就不做区分了,直接在Mdi窗口汇总把(main)加上去
// 这样 strShowTitle 和 strRealTitle 其实就失去意义了
QWidget* pNewSubView = m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_UI, bActive);
// 如果当前是UI的主页,则通知uimanger设定新的主页
if (bMainPage)
{
g_pUiManager->setMainPage(strName);
this->m_strMainTitle = strName;
}
return pNewSubView;
}
else
{
return pSubView;
}
}
/////
///// 添加一个UI节点
/////
/////
/////
//QWidget* WindowAppResourceManagerTree::addUiNode(QString strName, bool bActive)
//{
// QWidget* pSubView = m_pMdiFrame->findSubView(strName);
// if (pSubView == nullptr)
// {
// // 如果只有一个页面,那这个页面就是主页
// QString strShowName = strName;
// bool bNewMainPage = false;
// if (g_pUiManager->getAllUiNames().size() <= 0)
// {
// strShowName += UI_MAINPAGE_POSTFIX;
//
// // 并且记录下mainpage名字的对应关系
// m_uiMainTitle.strShowTitle = strShowName;
// m_uiMainTitle.strRealTitle = strName;
//
// bNewMainPage = true;
// }
//
// // 树形结构中添加一个节点
// addChildItem(SUBVIEW_TYPE::SUBVIEW_UI, strShowName);
//
// // 然后添加对应的子窗口视图,并返回新视图指针
// // 2022-9-21,如果需要通过激活的页面来到树形结构里进行反查的话,那么带(main)的主页是会搜索不到的
// // 这里干脆就不做区分了,直接在Mdi窗口汇总把(main)加上去
// // 这样 strShowTitle 和 strRealTitle 其实就失去意义了
// // QWidget* pNewSubView = m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_UI, bActive);
// QWidget* pNewSubView = m_pMdiFrame->addSubView(strShowName, SUBVIEW_TYPE::SUBVIEW_UI, bActive);
//
// // 如果仅有一个页面,则通知uimanger设定新的主页
// if (bNewMainPage)
// {
// g_pUiManager->setMainPage(strShowName);
// }
//
// return pNewSubView;
// }
// else
// {
// return pSubView;
// }
//}
///
/// 添加子节点
///
///
///
void WindowAppResourceManagerTree::addChildItem(SUBVIEW_TYPE nodeIndex, const QString& strItemName)
{
// 根据类型在对应的位置新建节点
QTreeWidgetItem* newItem = new QTreeWidgetItem(m_rootNodes[(short)nodeIndex], QStringList(strItemName));
// 设置图标
newItem->setIcon(0, m_appNodeIcons[(short)nodeIndex]);
// 设置字体
QFont font;
font.setPointSize(8);
newItem->setFont(0, font);
// 将节点添加到界面中
m_rootNodes[(short)nodeIndex]->addChild(newItem);
}
///
/// 弹出右键菜单
///
///
void WindowAppResourceManagerTree::onTreeContextMenu(const QPoint& pt)
{
// qDebug() << "WindowAppTreeTask::onTreeContextMenu";
// 获取鼠标当前位置的Item
QTreeWidgetItem* curItem = this->itemAt(pt);
if (curItem == nullptr)
{
qDebug() << "WindowAppTreeTask::onTreeContextMenu - nullptr";
return;
}
// GVL 根节点
if (curItem == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_GVL])
{
m_menuGVLRoot->exec(QCursor::pos());
return;
}
// GVL子节点
if (curItem->parent() == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_GVL])
{
m_menuGVLChild->exec(QCursor::pos());
return;
}
// Pou 根节点
if (curItem == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_POU])
{
m_menuPouRoot->exec(QCursor::pos());
return;
}
// Pou 子节点
if (curItem->parent() == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_POU])
{
m_menuPouChild->exec(QCursor::pos());
return;
}
// Task Manager 根节点
if (curItem == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_TASK])
{
m_menuTaskRoot->exec(QCursor::pos());
return;
}
// Task Manager子节点
if (curItem->parent() == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_TASK])
{
m_menuTaskChild->exec(QCursor::pos());
return;
}
// Task Manager孙节点
if (curItem->parent()->parent() == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_TASK])
{
m_menuPouChild->exec(QCursor::pos());
return;
}
// Design 根节点
if (curItem == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_UI])
{
m_menuUiRoot->exec(QCursor::pos());
return;
}
// Design 子节点
if (curItem->parent() == m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_UI])
{
m_menuUiChild->exec(QCursor::pos());
return;
}
}
///
/// 节点双击,切换对应子页面
///
void WindowAppResourceManagerTree::onTreeItemDblClicked(QTreeWidgetItem* clickedItem, int column)
{
Q_UNUSED(column);
// qDebug() << "WindowAppTreeTask::onTreeItemDblClicked";
// 如果双击的是父节点,则不做任何操作
if (clickedItem->parent() == nullptr)
{
return;
}
// 如果是子节点,则切换到对应页面
if ( clickedItem->parent()!=topAppItem
//&& clickedItem->parent()!=topHardwareItem
)
{
// qDebug() << "WindowAppTreeTask::onTreeItemDblClicked child";
// 2021-9-28,如果点击的是UI页面,此处需要加一个名字转换,因为UI的主页后面有main字样
QString strItemName = clickedItem->text(0);
// 2022-9-22 统一了节点和子页面名称,此处不做转换了
//if (strItemName == m_uiMainTitle.strShowTitle)
//{
// strItemName = m_uiMainTitle.strRealTitle;
//}
m_pMdiFrame->activeSubView(strItemName);
// 根据当前双击节点的父节点,通知WindowApp切换对应的工具箱
this->switchAppToolbox(clickedItem->parent());
}
}
///
/// 2022-9-20,根据用户选择的子窗体,激活App中对应的工具箱Tab(仅Pou和UI)
///
///
void WindowAppResourceManagerTree::switchAppToolbox(QTreeWidgetItem* currentParentItem)
{
// 如果当前双击的是Pou节点,则通知WindowApp切换到对应的视觉工具箱
if (currentParentItem->text(0) == NODE_NAME_PROGRAM)
{
m_pWindowApp->activeToolBoxView(APPTOOLBOX_VIEW_VISION);
}
// 如果当前双击的是Ui节点,则通过WindowApp切换到对应的UI工具箱
else if(currentParentItem->text(0) == NODE_NAME_UIDESIGN)
{
m_pWindowApp->activeToolBoxView(APPTOOLBOX_VIEW_UI);
}
// 如果当前双击的是硬件组态节点,则通知WindowApp切换到对应的视觉工具箱
else if (currentParentItem->text(0) == NODE_NAME_HARDWARE)
{
m_pWindowApp->activeToolBoxView(APPTOOLBOX_VIEW_VISION, WindowAppTreeTool::TREETOOL_MODE::MODE_HARDWARE);
}
// 否则通知WindowApp隐藏工具箱
else
{
m_pWindowApp->activeToolBoxView(APPTOOLBOX_VIEW_NULL);
}
}
///
/// 2022-9-21 根据用户激活的子窗体的名字,激活App中对应的工具箱Tab(仅Pou和UI)
///
///
void WindowAppResourceManagerTree::switchAppToolbox(const QString& strSubviewName)
{
// 首先根据名字找到对应的节点
QTreeWidgetItem* pItem = this->findChildItem(strSubviewName);
// 如果是子节点
if (pItem->parent() != topAppItem)
{
// 根据当前双击节点的父节点,通知WindowApp切换对应的工具箱
this->switchAppToolbox(pItem->parent());
}
}
///
/// GVL的节点菜单
///
///
void WindowAppResourceManagerTree::onMenuGVL(QAction* action)
{
QTreeWidgetItem* currentItem = this->currentItem();
if (currentItem == nullptr)
{
return;
}
// 获取当前选中的节点名称
QString strName = currentItem->text(0);
if (action == m_actionGVLNew)
{
doMenuGvlNew();
}
else if (action == m_actionGVLDelete)
{
doMenuGvlDelete(strName);
}
// qDebug() << "WindowAppTreeTask::onMenuGVL";
}
///
/// Pou相关菜单
///
///
void WindowAppResourceManagerTree::onMenuPou(QAction* action)
{
QTreeWidgetItem* currentItem = this->currentItem();
if (currentItem == nullptr)
{
return;
}
// 获取当前选中的节点名称
QString strName = currentItem->text(0);
if (action == m_actionPouNew)
{
doMenuPouNew();
}
else if (action == m_actionPouImport)
{
doMenuPouImport();
}
else if (action == m_actionPouExport)
{
doMenuPouExport(strName);
}
else if (action == m_actionPouRename)
{
doMenuPouRename(strName);
}
else if (action == m_actionPouDelete)
{
doMenuPouDelete(strName);
}
else if (action == m_actionPouChangeMode)
{
doMenuPouChangeMode(strName);
}
// qDebug() << "WindowAppTreeTask::onMenuPou";
}
///
/// Task Config相关菜单
///
///
void WindowAppResourceManagerTree::onMenuTask(QAction* action)
{
// qDebug() << "WindowAppTreeTask::onMenuTaskManager";
QTreeWidgetItem* currentItem = this->currentItem();
if (currentItem == nullptr)
{
return;
}
// 获取当前选中的节点名称
QString strName = currentItem->text(0);
if (action == m_actionTaskNew)
{
doMenuTaskNew();
}
else if (action == m_actionTaskAddPou)
{
doMenuTaskAddPou(strName);
}
else if (action == m_actionTaskDelete)
{
doMenuTaskDelete(strName);
}
}
///
/// UI 菜单
///
///
void WindowAppResourceManagerTree::onMenuUI(QAction* action)
{
// qDebug() << "WindowAppTreeTask::onMenuUI";
QTreeWidgetItem* currentItem = this->currentItem();
if (currentItem == nullptr)
{
return;
}
// 获取当前选中的节点名称
QString strName = currentItem->text(0);
if (action == m_actionUiNew)
{
doMenuUiNew();
}
else if (action == m_actionUiMainPage)
{
doMenuUiMainPage(strName);
}
else if (action == m_actionUiDelete)
{
doMenuUiDelete(strName);
}
}
///
/// Gvl - New
///
void WindowAppResourceManagerTree::doMenuGvlNew()
{
// 生成默认名字
int nGvlSize = g_pGvlManager->getAllGvls()->size();
QString strGvlName("Gvl_" + QString::number(nGvlSize));
DialogNewGVL dlgNewGvl;
dlgNewGvl.setWindowModality(Qt::WindowModal);
dlgNewGvl.setDefaultName(strGvlName);
int res = dlgNewGvl.exec();
if (res != QDialog::Accepted)
{
return;
}
// 名称和类型
QString gvlName = dlgNewGvl.m_gvlName;
GVL_MODE gvlType = dlgNewGvl.m_gvlType;
switch (gvlType)
{
case GVL_MODE::GVL_BASIC:
gvlName = gvlName + GVL_BASIC_POSTFIX;
break;
case GVL_MODE::GVL_STANDARD:
gvlName = gvlName + GVL_STANDARD_POSTFIX;
break;
case GVL_MODE::GVL_SYSTEM:
break;
case GVL_MODE::GVL_DB:
{
gvlName = gvlName + GVL_DB_POSTFIX;
}
break;
default:
break;
}
// 检查节点是否有重复的名称
if (this->findChildItem(gvlName) != nullptr)
{
Utility::VPCriticalMessageBox(gvlName + " is duplicated!");
return;
}
// 2022-3-2,如果是DB模式,还需要额外绑定硬件和DB数据表
if (gvlType == GVL_MODE::GVL_DB)
{
// 添加对应的节点和视图
this->addGvlNode(gvlName, gvlType, dlgNewGvl.m_pSelHdwTool->pDllPtr, true);
g_pGvlManager->bindHdwToolAndDB(dlgNewGvl.m_pSelHdwTool, gvlName);
}
else
{
// 添加对应的节点和视图
this->addGvlNode(gvlName, gvlType, nullptr, true);
}
}
///
/// Gvl - Delete
///
void WindowAppResourceManagerTree::doMenuGvlDelete(const QString& strName)
{
// 当前选中Pou的名字
QString strDelGvlName = strName;
// 查找父节点
QTreeWidgetItem* pParentItem = this->currentItem()->parent();
if (pParentItem)
{
TOOL* pTool = g_pGvlManager->getHdwToolByDbName(strDelGvlName);
g_pGvlManager->unbindHdwToolAndDB(pTool , strDelGvlName);
// 删除指定的gvl
g_pGvlManager->removeGvl(strDelGvlName);
// 因为在pouReset()中会删除页面,所以此处应该可以注释掉了
if (pParentItem == m_rootNodes[(int)SUBVIEW_TYPE::SUBVIEW_GVL])
{
m_pMdiFrame->deleteSubView(strDelGvlName);
}
// 最后删除此节点
QTreeWidgetItem* currentItem = this->currentItem();
pParentItem->removeChild(currentItem);
}
}
///
/// Program - New
///
void WindowAppResourceManagerTree::doMenuPouNew()
{
// 生成默认名字
int nPouSize = g_pPouManager->getAllPous().size();
QString strPouName( "Pou_" + QString::number(nPouSize));
DialogNewPou dlgNewPou;
dlgNewPou.setWindowModality(Qt::WindowModal);
dlgNewPou.setDefaultName(strPouName);
int res = dlgNewPou.exec();
if (res != QDialog::Accepted)
{
return;
}
QString pouName = dlgNewPou.m_strPouName + POU_POSTFIX;
//Pou_TYPE pouType = dlgNewPou.pouType;
// 检查节点是否有重复的名称
if (this->findChildItem(pouName) != nullptr)
{
Utility::VPCriticalMessageBox(pouName + " is duplicated!");
return;
}
// 添加对应的节点和视图
this->addPouNode(pouName, true);
// 2022-9-20,新增了一个Pou节点的时候,也通知WindowApp切换到Pou工具箱
m_pWindowApp->activeToolBoxView(APPTOOLBOX_VIEW_VISION);
}
///
/// Program - Import
///
void WindowAppResourceManagerTree::doMenuPouImport()
{
// 获取加载的全路径
QString strFullPath = QFileDialog::getOpenFileName(this,
tr("Open POU"), "/home/POU", tr("POU Files (*.pou)"));
if (strFullPath.isEmpty())
{
return;
}
// 执行导入
VPGlobal::m_pDoc->loadSinglePou(strFullPath);
}
///
/// Program - Export
///
void WindowAppResourceManagerTree::doMenuPouExport(const QString& strName)
{
// 根据当前节点生成默认文件名
QString strExportPouName = strName;
QString strDefaultFileName = strExportPouName + "_Export.pou";
// 提示选择存储位置
QString m_strSavePath = QFileDialog::getSaveFileName(this, tr("save POU"), strDefaultFileName, "POU (*.pou)");
if (m_strSavePath.isEmpty())
{
return;
}
// 开始导出
VPGlobal::m_pDoc->saveSinglePou(m_strSavePath, strExportPouName);
}
// Program - Rename
void WindowAppResourceManagerTree::doMenuPouRename(const QString& strName)
{
qDebug() << "WindowAppResourceManager::DoMenuPouRename";
Q_UNUSED(strName);
}
///
/// Program - Delete
///
void WindowAppResourceManagerTree::doMenuPouDelete(const QString& strName)
{
// qDebug() << "WindowAppResourceManager::DoMenuPouDelete";
// 当前选中Pou的名字
QString strDelPouName = strName;
// 2021-8-17,首先需要检查待删除的Pou是否被Task选中
POU* pDelPou = g_pPouManager->getPouByName(strDelPouName);
if (pDelPou->isSelByTask())
{
Utility::VPCriticalMessageBox("Can't delete this pou : this pou is running in task[" + pDelPou->m_pParentTask->strName + "]");
return;
}
// 查找父节点
QTreeWidgetItem* pParentItem = this->currentItem()->parent();
// 因为在pouReset()中会删除页面,所以此处应该可以注释掉了
//if (pParentItem == m_rootNodes[(int)SUBVIEW_TYPE::SUBVIEW_POU])
//{
// m_pMdiFrame->deleteSubView(strDelPouName);
//}
// 最后删除此节点
QTreeWidgetItem* currentItem = this->currentItem();
pParentItem->removeChild(currentItem);
// 2021-8-23增加,清除相关Pou数据结构
VPGlobal::m_pDoc->pouReset(strDelPouName);
////如果没有父节点就直接删除
//if (currentItem->parent() == NULL)
//{
// delete ui->tv_Source->takeTopLevelItem(ui->tv_Source->currentIndex().row());
//}
//else
//{
// //如果有父节点就要用父节点的takeChild删除节点
// delete currentItem->parent()->takeChild(ui->tv_Source->currentIndex().row());
//}
}
///
/// Program - Change Mode
///
void WindowAppResourceManagerTree::doMenuPouChangeMode(const QString& strName)
{
qDebug() << "WindowAppTreeTask::DoMenuPouChangeMode";
Q_UNUSED(strName);
}
///
/// Task - New
///
void WindowAppResourceManagerTree::doMenuTaskNew()
{
// 生成默认名字
int nTaskSize = g_pTaskManager->getAllTasks().size() + 1;
QString strTaskName("Task_" + QString::number(nTaskSize));
DialogNewTask dlgNewTask;
dlgNewTask.setWindowModality(Qt::WindowModal);
dlgNewTask.setDefaultName(strTaskName);
int res = dlgNewTask.exec();
if (res != QDialog::Accepted)
{
return;
}
QString taskName = dlgNewTask.m_TaskOption.strName;
// 检查节点是否有重复的名称
if (this->findChildItem(taskName) != nullptr)
{
Utility::VPCriticalMessageBox(taskName + " is duplicated!");
return;
}
// 添加对应的节点和视图
WindowAppTaskView* pTaskView = (WindowAppTaskView*)this->addTaskNode(taskName);
// 将用户输入的Task参数绑定到视图中
pTaskView->addNewTask(dlgNewTask.m_TaskOption);
}
///
/// Task - Add Pou
///
void WindowAppResourceManagerTree::doMenuTaskAddPou(const QString& strTaskName)
{
Q_UNUSED(strTaskName);
// 生成默认名字
int nPouSize = g_pPouManager->getAllPous().size();
QString strPouName("Pou_" + QString::number(nPouSize));
DialogNewPou dlgNewPou;
dlgNewPou.setWindowModality(Qt::WindowModal);
dlgNewPou.setDefaultName(strPouName);
int res = dlgNewPou.exec();
if (res != QDialog::Accepted)
{
return;
}
QString pouName = dlgNewPou.m_strPouName + POU_POSTFIX;
//Pou_TYPE pouType = dlgNewPou.pouType;
// 检查节点是否有重复的名称
if (this->findChildItem(pouName) != nullptr)
{
Utility::VPCriticalMessageBox(pouName + " is duplicated!");
return;
}
// 添加对应的节点和视图
this->addPouNode(pouName, true);
// 添加 task 节点后的子节点
this->addPouNodeToTask(pouName, strTaskName);
}
///
/// Task - Del
///
void WindowAppResourceManagerTree::doMenuTaskDelete(const QString& strName)
{
// 获取要删除的Task名字
QString strDelTaskName = strName;
// 不允许删除 Task Monitor节点
if (strDelTaskName == GROUP_NAME_TASKMONITOR)
{
Utility::VPCriticalMessageBox("Can not delete TaskMonitor node!");
return;
}
// 数据结构中删除对应Task(此处需要先删数据再删视图,否则Task指针就随着视图删除也一起释放掉了)
g_pTaskManager->delTask(strDelTaskName);
// 查找父节点
QTreeWidgetItem* pParentItem = this->currentItem()->parent();
// Mdi删除对应的Task窗口
if (pParentItem == m_rootNodes[(int)SUBVIEW_TYPE::SUBVIEW_TASK])
{
m_pMdiFrame->deleteSubView(strName);
}
// 最后删除此节点
QTreeWidgetItem* currentItem = this->currentItem();
pParentItem->removeChild(currentItem);
// Task Monitor View中删除对应Task
VPGlobal::getTaskMonitorView()->delTask(strDelTaskName);
}
///
/// UI - New
///
void WindowAppResourceManagerTree::doMenuUiNew()
{
// 生成默认名字
int nUiSize = g_pUiManager->getAllUiNames().size() + 1;
QString strUiName("Ui_" + QString::number(nUiSize));
DialogNewUI dlgNewUI;
dlgNewUI.setWindowModality(Qt::WindowModal);
dlgNewUI.setDefaultName(strUiName);
int res = dlgNewUI.exec();
if (res != QDialog::Accepted)
{
return;
}
QString uiName = dlgNewUI.m_strUiName;
// 检查节点是否有重复的名称
// 并且不能与主页的实际名称重复才行(主页在树节点中会加main后缀)
//if (this->findChildItem(uiName) != nullptr
// && uiName!= m_uiMainTitle.strRealTitle
// )
if( g_pUiManager->getPageByName(uiName)!=nullptr )
{
Utility::VPCriticalMessageBox(uiName + " is duplicated!");
return;
}
// 添加对应的节点和视图
this->addUiNode(uiName, true);
// 2022-9-20,新增了一个UI节点的时候,也通知WindowApp切换到UI工具箱
m_pWindowApp->activeToolBoxView(APPTOOLBOX_VIEW_UI);
}
///
/// UI - setMainPage
///
void WindowAppResourceManagerTree::doMenuUiMainPage(const QString& strName)
{
// 通过UIManager设定主页
bool bRet = g_pUiManager->setMainPage(strName);
if (!bRet)
{
return;
}
// 如果设定成功,则首先去掉当前主页的后缀
QString strCurMain = m_strMainTitle;
if (!strCurMain.isEmpty())
{
// 枚举UI下所有节点,找到主页面节点
QTreeWidgetItemIterator it(m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_UI]);
while (*it)
{
if ((*it)->text(0) == strCurMain)
{
strCurMain.remove(UI_MAINPAGE_POSTFIX);
(*it)->setText(0, strCurMain);
break;
}
it++;
}
}
// 然后设定树形结构中新主页的名字
QString strNewMain = strName + UI_MAINPAGE_POSTFIX;
QTreeWidgetItemIterator it(m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_UI]);
while (*it)
{
if ((*it)->text(0) == strName)
{
(*it)->setText(0, strNewMain);
break;
}
it++;
}
// 最后保存新的主页信息
this->m_strMainTitle = strNewMain;
}
/////
///// UI - setMainPage
/////
//void WindowAppResourceManagerTree::doMenuUiMainPage(const QString& strName)
//{
// // 通过UIManager设定主页
// bool bRet = g_pUiManager->setMainPage(strName);
//
// if (!bRet)
// {
// return;
// }
//
// // 如果设定成功,则首先去掉当前主页的后缀
// QString strCurMain = m_uiMainTitle.strShowTitle;
// if (!strCurMain.isEmpty())
// {
// // 枚举UI下所有节点,找到主页面节点
// QTreeWidgetItemIterator it(m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_UI]);
// while (*it)
// {
// if ((*it)->text(0) == strCurMain)
// {
// strCurMain.remove(UI_MAINPAGE_POSTFIX);
//
// (*it)->setText(0, strCurMain);
//
// break;
// }
//
// it++;
// }
// }
//
// // 然后设定树形结构中新主页的名字
// QString strNewMain = strName + UI_MAINPAGE_POSTFIX;
// QTreeWidgetItemIterator it(m_rootNodes[(short)SUBVIEW_TYPE::SUBVIEW_UI]);
// while (*it)
// {
// if ((*it)->text(0) == strName)
// {
// (*it)->setText(0, strNewMain);
//
// break;
// }
//
// it++;
// }
//
// // 最后保存新的主页信息
// m_uiMainTitle.strRealTitle = strName;
// m_uiMainTitle.strShowTitle = strNewMain;
//}
///
/// UI - Del
///
void WindowAppResourceManagerTree::doMenuUiDelete(const QString& strName)
{
//// 转换一下实际名称
//QString strRealName = strName;
//if (strName == m_uiMainTitle.strShowTitle)
//{
// strRealName = m_uiMainTitle.strRealTitle;
//}
// 通过UIManager删除页面
bool bRet = g_pUiManager->deleteUi(strName);
// 如果删除成功,则继续执行后续操作
if (!bRet)
{
return;
}
// 查找父节点
QTreeWidgetItem* pParentItem = this->currentItem()->parent();
// Mdi删除对应的Task窗口
if (pParentItem == m_rootNodes[(int)SUBVIEW_TYPE::SUBVIEW_UI])
{
m_pMdiFrame->deleteSubView(strName);
}
// 最后删除此节点
QTreeWidgetItem* currentItem = this->currentItem();
pParentItem->removeChild(currentItem);
}
///
/// 重置(删除所有创建的节点和子视图)
///
void WindowAppResourceManagerTree::reset()
{
// 删除所有子视图
m_pMdiFrame->deleteAllSubViews();
// 移除所有子节点
this->removeAllSubNodes();
// 2022-2-222 重新添加几个默认视图(不包括硬件组态)
// 创建默认的Task视图
this->addDefaultTaskMonitorNode(GROUP_NAME_TASKMONITOR);
// 创建默认的Log视图
this->addDefaultLogViewNode(GROUP_NAME_LOGVIEW);
// this->initDefaultViews();
}
///
/// 添加默认的总任务管理视图节点
///
QWidget* WindowAppResourceManagerTree::addDefaultTaskMonitorNode(QString strName)
{
// 树形结构中添加一个节点
//addChildItem(SUBVIEW_TYPE::SUBVIEW_TASK, strName);
// 然后添加对应的子窗口视图
return m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_TASKMONITOR, false);
}
///
/// 添加默认的Debug视图节点
///
QWidget* WindowAppResourceManagerTree::addDefaultLogViewNode(QString strName)
{
return m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_LOG, false);
}
///
/// 添加默认的Hardware组态视图节点
///
///
///
QWidget* WindowAppResourceManagerTree::addDefaultHWConfigViewNode(QString strName)
{
//// 树形结构中添加一个节点
//addChildItem(SUBVIEW_TYPE::SUBVIEW_HDW, strName);
return m_pMdiFrame->addSubView(strName, SUBVIEW_TYPE::SUBVIEW_HDW, false);
}
///
/// 添加一个Pou节点到Task节点
///
///
///
void WindowAppResourceManagerTree::addPouNodeToTask(QString strPouName, QString strTaskName)
{
// 查找 Task 节点
QTreeWidgetItem* itmTask = findChildItem(strTaskName);
if (itmTask != nullptr)
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(itmTask, QStringList(strPouName));
// 设置图标
newItem->setIcon(0, m_appNodeIcons[(short)1]);
// 设置字体
QFont font;
font.setPointSize(8);
newItem->setFont(0, font);
// 将节点添加到界面中
itmTask->addChild(newItem);
WindowAppTaskView* pTaskView = (WindowAppTaskView*)m_pMdiFrame->findSubView(strTaskName);
if (pTaskView != nullptr)
{
QVector pPous;
POU* pPou = g_pPouManager->getPouByName(strPouName);
if (pPou != nullptr)
{
pPous.push_back(pPou);
}
pTaskView->addTaskPous(pPous);
}
}
}