/* * AddLineCmd.cpp * * Created on: 2012-10-10 * Author: limengzhuo */ #include #include "AddLineCmd.h" #include "ModuleGraphicsItem.h" #include "ModuleConnectGraphicsItem.h" #include "PaiWorkflowDataModel.h" #include "WorkflowSceneManager.h" #include "ModuleConnection.h" #include "WorkFlowFile.h" #include "PaiMessageBox.h" #include "ConsoleGUIService.h" using namespace pai::graphics2d; using namespace pai::workflow; using namespace pai::objectmodel; using namespace pai::gui; namespace pai { AddLineCmd::AddLineCmd(WorkflowSceneManager *pSceneManager, PaiWorkflowDataModel *pWorkflow, ModuleGraphicsItem *pStartItem, ModuleGraphicsItem *pEndItem, QUndoCommand *pParent) :QUndoCommand(pParent) ,m_pSceneManager(pSceneManager) ,m_pWorkflow(pWorkflow) ,m_pConnection(new CModuleConnection()) ,m_nStepIdFirst(0) ,m_nStepIdSecond(0) ,m_nStartPortIndex(0) ,m_nEndPortIndex(0) ,m_type(AddLineType_General) ,m_bPortBeenLined(false) { if (pStartItem && (pStartItem->GetOutputPortCount() > 0) && pEndItem && (pEndItem->GetInputPortCount() > 0)) { if(pStartItem->GetModule()) { m_nStepIdFirst = pStartItem->GetModule()->GetStepID(); } if(pEndItem->GetModule()) { m_nStepIdSecond = pEndItem->GetModule()->GetStepID(); } } else if (pEndItem->GetOutputPortCount() > 0) { if(pEndItem->GetModule()) { m_nStepIdFirst = pEndItem->GetModule()->GetStepID(); } if(pStartItem->GetModule()) { m_nStepIdSecond = pStartItem->GetModule()->GetStepID(); } } } AddLineCmd::AddLineCmd(WorkflowSceneManager *pSceneManager, PaiWorkflowDataModel *pWorkflow, ModuleGraphicsItem *pStartItem, ModuleGraphicsItem *pEndItem, int nStartPortIndex, int nEndPortIndex, QUndoCommand *pParent) :QUndoCommand(pParent) ,m_pSceneManager(pSceneManager) ,m_pWorkflow(pWorkflow) ,m_pConnection(new CModuleConnection()) ,m_nStepIdFirst(0) ,m_nStepIdSecond(0) ,m_nStartPortIndex(nStartPortIndex) ,m_nEndPortIndex(nEndPortIndex) ,m_type(AddLineType_Destinated) ,m_bPortBeenLined(false) { if(pStartItem->GetModule()) { m_nStepIdFirst = pStartItem->GetModule()->GetStepID(); } if(pEndItem->GetModule()) { m_nStepIdSecond = pEndItem->GetModule()->GetStepID(); } } AddLineCmd::~AddLineCmd() { if(m_pConnection) { delete m_pConnection; m_pConnection = NULL; } } void AddLineCmd::undo() { RemoveLine(); } void AddLineCmd::RemoveLine() { if (m_pWorkflow && m_pConnection) { CModuleConnection* pConnectNeedRemove = m_pWorkflow->GetConnection(m_pConnection); if (pConnectNeedRemove) { //删除连线前,确保线程池中线程结束 m_pSceneManager->WaitThreadForDone(); m_pSceneManager->DeleteConnection(pConnectNeedRemove); if (m_pWorkflow->RemoveConnection(pConnectNeedRemove) == false) { pai::log::Debug(_FLF("Add connection undo failure.")); } else { //删除连线成功,开启提交校验 m_pSceneManager->StartSubmitValidateThread(); } } } } void AddLineCmd::redo() { AddLine(); } bool AddLineCmd::GetPortHasbeenLined() { return m_bPortBeenLined; } bool AddLineCmd::DetectCircle(ModuleGraphicsItem *pStartItem, ModuleGraphicsItem *pEndItem) { //获取pEndItem对应的所有的输出模块 QList lstModule = m_pSceneManager->GetOutputModules(pEndItem); // check whether the module item is pStartItem foreach(ModuleGraphicsItem* pModuleItem, lstModule) { // found a circle if (pModuleItem == pStartItem) { return true; } // Depth first search if (DetectCircle(pStartItem, pModuleItem)) { return true; } } return false; } void AddLineCmd::AddLine() { if (!m_pSceneManager || m_nStartPortIndex < 0 || m_nEndPortIndex < 0) { return; } ModuleGraphicsItem *pStartItem = m_pSceneManager->FindModule(m_nStepIdFirst); ModuleGraphicsItem *pEndItem = m_pSceneManager->FindModule(m_nStepIdSecond); if(!pStartItem || !pEndItem) { return; } /////////////////改 // 获取输出端口数量 int nOutputPort = pStartItem->GetOutputPortCount(); if (nOutputPort < m_nStartPortIndex + 1) { return; } //获取输入端口数量 int nInputPort = pEndItem->GetInputPortCount(); if (nInputPort < m_nEndPortIndex + 1) { return; } //如果结束item存在多个输入端口,查找合理的输入端口 if(m_type == AddLineType_General) { //设置即将被连线的输入端口索引 m_nEndPortIndex = pEndItem->GetFreeInPortIndex(); } //检查结束item的输入端口是否连线 if (m_nEndPortIndex == -1 || pEndItem->InPortHasBeenLined(m_nEndPortIndex)) { m_bPortBeenLined = true; QString strMessage = QString("This port has been lined, you should connect other port or delete the line on the port first."); PaiMessageBox::Critical(NULL, QObject::tr("Error!"), strMessage); pai::log::Error(_FLF(QObject::tr("QUndoCommand::ShowMessage ").toStdString()+strMessage.toStdString())); pai::log::Debug(_FLF("port already lined. Add connection failure.")); return; } //检查将要连线的模块之间是否已经存在连线 if(m_pSceneManager->CheckConnection(pStartItem,pEndItem)) { QString strMessage = QObject::tr("You can only connect two modules with one line!"); PaiMessageBox::Critical(NULL, QObject::tr("Error!"), strMessage); pai::log::Error(_FLF(QObject::tr("QUndoCommand::ShowMessage ").toStdString()+strMessage.toStdString())); return; } //删除循环的连线 if (DetectCircle(pStartItem, pEndItem)) { QString strMessage = QObject::tr("You will create a circle, it's not allowed!"); PaiMessageBox::Critical(NULL, QObject::tr("Error!"), strMessage); pai::log::Error(_FLF(QObject::tr("QUndoCommand::ShowMessage ").toStdString()+strMessage.toStdString())); pai::log::Debug(_FLF("Circle will be created. Add connection failure.")); return; } //新建连线 workflow::CModuleConnection *pConnection = new workflow::CModuleConnection(); pConnection->SetSourceId(pStartItem->GetModule()->GetStepID()); pConnection->SetDestId(pEndItem->GetModule()->GetStepID()); pConnection->SetOutPort(QString::number(m_nStartPortIndex).toStdString()); // first output port pConnection->SetInPort(QString::number(m_nEndPortIndex).toStdString()); // first input port //记录新建的连线 pConnection->CopyTo(*m_pConnection); //工作流中添加连线 if (!m_pWorkflow->AddConnection(pConnection)) { delete pConnection; pConnection = NULL; pai::log::Debug(_FLF("Add connection failure.")); } else { //场景中添加连线item m_pSceneManager->AddConnection(pConnection); //添加连线成功以后开启提交校验线程 m_pSceneManager->StartSubmitValidateThread(); } } void AddLineCmd::SetFirstStepID(int first) { m_nStepIdFirst = first; } void AddLineCmd::SetSecondStepID(int second) { m_nStepIdSecond = second; } }