/* * @file WorkflowSceneManager.h * @author haidong * @date: 2011-8-17 * @brief 工作流编辑的场景管理器,负责模块,连线的添加删除等编辑的交互控制 */ #ifndef PAI_FRAME_WORKFLOWVIEW_WORKFLOWSCENEMANAGER_H #define PAI_FRAME_WORKFLOWVIEW_WORKFLOWSCENEMANAGER_H #include #include #include #include // #include #include #include "Turtle_globle.h" // #include "Job.h" // #include "PaiUndoStack.h" #include "WorkflowSpecialTypes.h" // #include "WorkflowJob.h" #include "GeneralWorkflowScene.h" // #include "ModuleInformation.h" namespace pai { namespace module { class CModuleCheckResult; } } namespace pai { class CPaiWorkflowPlugin; class ToolBarService; namespace objectmodel { class PaiObject; class PaiWorkflowDataModel; } namespace graphics2d { class ModuleGraphicsItem; class PaiModuleStyle; class CParameterEditor; } } namespace pai { namespace graphics2d { /** * @class WorkflowSceneManager * @brief 工作流编辑的场景管理器,负责模块,连线的添加删除等编辑的交互控制 */ class PAI_WORKFLOWVIEW_EXPORT WorkflowSceneManager : public GeneralWorkflowScene { Q_OBJECT public: /** * @brief 场景构造函数 * @param[in] x 场景左上角x轴开始坐标 * @param[in] y 场景左上角y轴开始坐标 * @param[in] width 场景宽度 * @param[in] height 场景高度 * @param[in] bUnitTest UT标志 */ WorkflowSceneManager(qreal x, qreal y, qreal width, qreal height, QObject *pParent = NULL); /** * @brief 场景析构函数 */ virtual ~WorkflowSceneManager(); /** * @brief 添加一个工作流到绘图场景区域并校验模块 * @param[in] pWorkflow 工作流对象句柄 * @param[in] bJobRelated 是否为JobMananger Tab 页上的工作流 */ virtual void AddWorkflow(pai::objectmodel::PaiWorkflowDataModel* pWorkflow, bool bJobRelated = false); /** * @brief 选中指定的模块图元并向参数编辑面板发送选中的消息 * @param[in] stepID 指定的模块图元的stepID */ void SelectModuleItem(int stepID); /** * @brief 只清除了场景中的连线和模块 */ virtual void Clear(); void ClearItems(); /** * @brief 根据视图的情况设置菜单项的关联或状态,处理了copy,paste等菜单 * @param[in] connect true根据情况设置可用,并关联信号,false解除信号关联 */ void RestoreActions(bool bConnectAction); /** * @brief 根据视图的情况设置菜单项的可用状态,处理了copy,paste等 */ void UpdateActions(); /* * @brief 获得已经启动的Submit验证线程的个数 */ int GetSubmitThreadCount(); /* * @brief 获得UndoStack * @return 当前场景对应的命令栈 */ // PaiUndoStack* GetUndoStack(); /* * @brief 用来设置工作流提交按钮状态 * @param[in] bSubmit提交按钮状态 */ void SetSubmitting(bool bSubmit); /* * @brief 用来设置工具栏名称,以便用来查找工具栏 * param[in] name 工具栏名称 */ void SetSubToolBarName(const QString &name); /** *@brief 设置工作流的参数面版 *@param[in] pParamEditor参数面板指针 */ void SetParameterEditor(CParameterEditor *pParamEditor); /** *@brief 设置试图内的模块是否可以框选 *@param[in] pWorkflowView 视口 *@param[in] 是否可框选 */ virtual void EnableMultiSelect(QGraphicsView *pWorkflowView, bool enable); /** * @brief 获取缩放次数 * @return 缩放次数 */ int GetZoomCount(); /** * @brief 设置缩放次数 * @param zoomCount 缩放次数 */ void SetZoomCount(int zoomCount); /** * @brief 在添加模块后,打开模块参数信息 * @param[in] pModuleInfo 模块信息 */ void OpenModuleParam(pai::workflow::CModuleInformation *pModuleInfo); /** * @brief 添加一个Module到绘图场景区域 * @param[in] pModule 模块的参数信息 * @param[in] pStyle 模块图元的绘图信息 * @param[in] bJobRelated 是否作业对应的工作流 * @return 被添加模块 */ virtual pai::graphics2d::ModuleGraphicsItem* AddModule(pai::workflow::CModuleInformation* pModule, pai::graphics2d::PaiModuleStyle* pStyle, bool bJobRelated = false); /** * @brief 添加一个连线到绘图场景区域 * @param[in] pConnect 模块连线的参数信息 */ virtual void AddConnection(pai::workflow::CModuleConnection* pConnect); /** * @brief 删除模块 * @param[in] setpID 模块的stepID */ virtual void DeleteModule(int setpID); /** * @brief 删除连线 * @param[in] pConnection 连线信息 */ virtual void DeleteConnection(pai::workflow::CModuleConnection *pConnection); /** * @brief 获取某模块对应的所有输出模块 * @param[in] pModuleItem 模块指针 * @return 输出模块链表 */ QList GetOutputModules(pai::graphics2d::ModuleGraphicsItem *pModuleItem); /** * @brief 检查两个模块之间是否已经存在连线 * @param[in] pBeginModule 开始模块 * @param[in] pEndModule 结束模块 * @return true 存在连线,false 不存在连线 */ bool CheckConnection(pai::graphics2d::ModuleGraphicsItem *pBeginModule, pai::graphics2d::ModuleGraphicsItem *pEndModule); /** * @brief 等待线程池中正在运行的线程结束 */ void WaitThreadForDone(); /** * @brief 启动验证Submit线程 */ void StartSubmitValidateThread(); void DeleteAll(); workflow::CModuleInformation * GetSingleSelectedModule( ); bool& getSingleMethodFlag(){return m_bIsSingleMethod;}; protected: /** * @brief 接受模块树上的拖拽 */ virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *pEvent); /** * @brief 接受模块树上的拖拽 */ virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent); /** * @brief 响应模块树上的拖拽 */ virtual void dropEvent(QGraphicsSceneDragDropEvent *pEvent); /** * @brief 响应双击事件 */ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * mouseEvent); /** * @brief 响应按键事件 */ virtual void keyReleaseEvent(QKeyEvent * keyEvent); /** * @brief 响应键盘按下事件 * @param keyEvent:键盘事件指针 */ virtual void keyPressEvent(QKeyEvent * keyEvent); /** * @brief 响应鼠标移动事件 */ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent); /** * @brief 响应鼠标抬起事件 */ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent); /** * @brief 响应鼠标按下事件 */ virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent); /** * @brief响应右键菜单事件 */ virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent * contextMenuEvent); /* * @brief 在空白处右键单击出现的上下文菜单 */ QMenu *WorkflowSenceMenu(QGraphicsSceneContextMenuEvent *pContextMenuEvent); /* * @brief 在选中的模块处单击出现的上下文菜单 */ QMenu *WorkflowModuleMenu(pai::workflow::CModuleInformation *moduleInfo); /* * @brief 在选中的模块连接线单击出现的上下文菜单 */ QMenu *WorkflowConnectLineMenu(QGraphicsSceneContextMenuEvent * contextMenuEvent); /* * @brief 在选中的模块连接点单击出现的上下文菜单 */ QMenu *WorkflowPortMenu(QGraphicsSceneContextMenuEvent * contextMenuEvent); /* * @brief 清空模块端口间的连接虚线 */ void ClearDashLine(); /* * @brief 在连接模块的时候判断模块某个输入端口是否已经有连线 * @param pEndItem 模块 * @param portIndex 输入端口索引值 */ bool PortHasBeenLined(ModuleGraphicsItem *pEndItem, int portIndex); public slots: /** * @brief 实现模块的粘贴功能 */ void slotPaste(); /* * @brief slot for copy items */ void slotCopy(); /* * @brief: cut item slot (added by Pangshiming 2012.9.9) */ void slotCutItem(); /** *@brief 应用工作流模板 *@param pObject 要应用的工作流模板对象 */ void slotApplyTemplate(pai::objectmodel::PaiObject* pObject); /* * @brief add module by module information */ void slotAddModule(const QString&); private slots: /** * @biref 更新模块状态 * @param[in] pItem 被更新的模块 */ void slotUpdateModule(pai::graphics2d::ModuleGraphicsItem *pItem); /** * @brief 响应用户修改模块名称 */ void slotOnSetName(pai::graphics2d::ModuleGraphicsItem *pItem); /** * @brief 响应用户禁用或激活模块 */ void slotOnDisableOrEnable(pai::graphics2d::ModuleGraphicsItem *, bool enable); /** * @brief 响应用户选择模块或者连线 */ void slotOnSelectionChanged(); /** * @brief 响应用户选择模块的端口 * @param pItem 模块图元 * @param bSelected 端口选择或取消选择 */ void slotOnPortSelectionChanged(pai::graphics2d::ModuleGraphicsItem* pItem, bool bSelected); /** * @brief 响应在绘制连接虚线的过程中,用户鼠标移动到模块的端口上 * @param pItem 模块图元 * @param bHovering */ void slotOnPortHoveringChanged(pai::graphics2d::ModuleGraphicsItem* pItem, bool bHovering); /** * @brief 响应数据模型的增加变化 */ void slotOnObjectAddChildren(pai::objectmodel::PaiObject* pWorkflow, QList< pai::objectmodel::PaiObject* > & children); /** * @brief 响应数据模型的删除变化 */ void slotOnObjectRemoveChild(pai::objectmodel::PaiObject* pObject, pai::objectmodel::PaiObject* pChild); /** * @brief 当参数检查结束时,给树形数据结构所携带的每个参数项赋错误信息并向外发送信号通知 */ void slotOnParameterValidated(); /** * @brief 响应工具栏上的删除模块按钮 * @param pModuleItem 待删除的模块图元 */ void slotDeleteModule(pai::graphics2d::GeneralWorkflowScene *pScene, pai::graphics2d::ModuleGraphicsItem* pModuleItem); /* * @brief 响应Action(delete)删除相应的模块 */ void slotDeleteModule(); /** * @brief 实现模块的右键菜单粘贴功能 */ void slotPasteHere(); /** * @brief 响应模块参数错误,让相应的模块图元变成红色 */ void slotOnModuleParameterError(pai::workflow::CModuleInformation * pModuleInfo,bool checkresult, const pai::module::CModuleCheckResult& errorInfo, ValidateEventSource eventSource); /** * @brief 响应参数修改的变化,将工作流对象的修改状态置为真 */ void slotOnModuleParamDataChanged(); /** * @brief workflow command undo. */ void slotUndo(); /** * @brief workflow command redo. */ void slotRedo(); /* * @brief align the selected items (added by Pangshiming 2012.5.31) */ void slotAlign(); /* * @brief 响应SubmitValidateThread线程finish信号,获得验证的结果,来设置Submit按钮的状态。 */ void slotOnCanSubmitThreadFinished(); /* * @brief 响应signalSelectModule信号,来设置m_pSelectedItem */ void slotSelectModule(pai::workflow::CModuleInformation*pInfo); /* * @brief select all items slot (added by Pangshiming 2012.6.11) */ void slotSelectAll(); /* * @brief copy all items slot (added by Pangshiming 2012.6.11) */ void slotCopyAll(); /** * @brief zoom in items */ void slotZoomin(); /** * @brief zoom out items */ void slotZoomout(); /* * @brief delete connection slot (added by Pangshiming 2012.9.6) */ void slotDeleteConnection(); /* * @brief :add modules connection line slot (added by Pangshiming 2012.9.10) */ void slotAddLine(); /* * @brief : break modules connection line slot (added by Pangshiming 2012.9.10) */ void slotBreakLine(); /* * @brief: slot for module tree menu item clicked(added by Pangshiming 2012.9.9) */ void slotOnModuleMenuClick(const QString&, const QString&); /* * @brief: slot for toolbar enable button clicked (added by Pangshiming 2012.9.10) */ void slotToolBarEnable(); /* * @brief: slot for toolbar edit button clicked(added by Pangshiming 2012.9.10) */ void slotToolBarEdit(); /* * @brief: slot for parameter button clicked(added by Pangshiming 2012.9.12) */ void slotModuleParameter(); /** * @brief: 删除被disable的模块 */ void slotDeleteDisabledItems(); /** *@brief 设置模块名称 */ // void slotSetSelectedModuleName(); signals: /** * @brief 场景中选择改变时,发送的信号 * @param[in] pInfo 模块信息 */ void signalSelectModule(pai::workflow::CModuleInformation* pInfo); /** * @brief 设置模块选中状态,发送的信号 * @param[in] selected 被选中:true,未被选中: false */ void moduleSelectedSignal(bool selected); /** * @brief 拖拽数据到模块时发送该信号显示该模块参数 * @param[in] pInfo 模块信息 */ void signalOpenModuleParam(pai::workflow::CModuleInformation* pInfo); /** * @brief 当场景中的模块图元被双击时候发送此消息 * @param[in] pInfo 被双击的模块 * @param[in] IsModuleReadOnly 模块是否来自只读场景 */ void doubleClickModule(pai::workflow::CModuleInformation* pInfo, bool IsModuleReadOnly); private: /** * @brief 场景中是否存在模块(注:右键菜单的selectAll,Zoom,copyAll Action使能条件) * @return true:存在,false:不存在 */ bool IsModuleExisting(); /** * @brief 是否删除模块按钮使能 * @return true:可以删除模块,false:不能删除模块 */ bool DeleteModuleCondition(); /** *@brief 把所有的模块名称编辑框都隐藏掉 */ // void HideAllModuleNameEdit(); /** * @brief 初始化ModuleNameList */ void InitModuleNameList(); /** * @brief 模块是否处于名称编辑状态 * @return true正处于编辑状态,false处于未编辑状态 */ // bool IsEditingModuleName(); /** * @检查所有模块是否都有连线 * @return 如果是一个完整的工作流,返回true,其它返回false */ bool CheckConnection(); /** * @brief 响应数据模型的变化 */ void HandleOnObjectAddOrRemove(pai::objectmodel::PaiObject* pChild, bool add); /** * @brief 验证有可拖拽数据的模块 */ void ValidateModulesAcceptDropData(QUuid typeID, QString logicFileName); /** * @brief 得到该场景对应的局部工具栏的服务 */ void RemoveModulesInBackup(); /** * @brief 得到工作流的插件 */ // CPaiWorkflowPlugin * GetWorkflowPlugin(); /** * @brief 判断工作流是否是Active的 */ bool IsActiveWorkflow(pai::objectmodel::PaiWorkflowDataModel* pWorkflow); /** * @brief 得到该场景对应的局部工具栏的服务 */ pai::ToolBarService* GetStyleToolBarService() const; /** * @brief 判断是否可以加入连接线 */ bool AddLineCondition(); /** * @brief 判断是否可以删除连接线 */ bool BreakLineCondition(); /** * @brief 判断Disable and Eidt icon 是否可用 */ bool DisableAndEditCondition(); /** * @brief 在选定模块前或后加入一模块 * @param[in] moduleName 模块类名 * @param[in] isBefore 在被选模块上边添加:true,否则false */ void addBeforeOrAfter(const QString& moduleName, bool isBefore); /* * @brief 释放ThreadPool */ void ReleaseThreadPool(); /** * @brief 发送更新B2区的info页签的信号 */ void UpdateHelpDoc(); private: ModuleGraphicsItem* m_pStartItem; //添加连线开始模块 ModuleGraphicsItem* m_pEndItem; //添加连线结束模块 QGraphicsLineItem *m_pTmpLine; //端口连接时绘制的虚线 QString m_strSubToolBarName; //工具栏名称 QMap< QString, QString > m_pMouduleNameList; // 模块名称,类名称 bool m_bModuleMoved; //记录模块是否被移动过。 bool m_bLeftButtonDown; //记录鼠标左键是否按下,用来区分鼠标滑动和拖到。 bool m_bKeyPressed; //记录键盘是否按下。 QPointF m_bMousePressPoint; //鼠标按下坐标 int m_SubmitThreadCount; //记录场景中的验证线程的个数,在SaveAs的情况下,可能不只有过一个工作流 // PaiUndoStack *m_pUndoStack; //命令栈 // QThreadPool *m_pThreadPool; //线程池 int m_zoomCount; //场景视图放大或缩小的次数 QPointF m_rubberBandPoint; //框选时鼠标按下点 QPoint m_PastePoint; //复制模块的位置 CParameterEditor *m_pParameterEditor; //参数面板指针 bool m_bEnableMultiSelect; //判断是否可以多选操作 bool m_bIsSingleMethod; //判断当前是否单方法模式 }; } } #endif