#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); } } }