404 lines
14 KiB
C++
404 lines
14 KiB
C++
|
|
/**
|
|||
|
|
* @file SaveAsWorkflowCmd.cpp
|
|||
|
|
* @date 2012-10-17
|
|||
|
|
*/
|
|||
|
|
#include <QUuid>
|
|||
|
|
#include <QDebug>
|
|||
|
|
|
|||
|
|
#include "PaiObject.h"
|
|||
|
|
#include "PaiSurvey.h"
|
|||
|
|
#include "PaiWorkflowDataModel.h"
|
|||
|
|
#include "WorkflowConst.h"
|
|||
|
|
#include "PaiBalloonTipSettings.h"
|
|||
|
|
#include "PaiBalloonTip.h"
|
|||
|
|
#include "ObjectModelService.h"
|
|||
|
|
#include "PaiMessageBox.h"
|
|||
|
|
#include "PAIConst.h"
|
|||
|
|
#include "ViewExtension.h"
|
|||
|
|
#include "PaiWorkflowMaster.h"
|
|||
|
|
#include "SaveAsWorkflowCmd.h"
|
|||
|
|
#include "SaveHelper.h"
|
|||
|
|
#include "WorkflowWidget.h"
|
|||
|
|
#include "ConsoleGUIService.h"
|
|||
|
|
#include "PaiGUIService.h"
|
|||
|
|
#include "PaiActionsHistory.h"
|
|||
|
|
#include "WorkFlowFile.h"
|
|||
|
|
#include "PaiObjectSelection.h"
|
|||
|
|
#include "GlobalUtility.h"
|
|||
|
|
|
|||
|
|
using namespace pai::workflow;
|
|||
|
|
using namespace pai;
|
|||
|
|
using namespace pai::objectmodel;
|
|||
|
|
using namespace pai::gui;
|
|||
|
|
using namespace pai::graphics2d;
|
|||
|
|
|
|||
|
|
SaveAsWorkflowCmd::SaveAsWorkflowCmd(QUuid viewID,
|
|||
|
|
PaiWorkflowDataModel *pActiveWorkflow,
|
|||
|
|
QUndoCommand *pParent) :
|
|||
|
|
QUndoCommand(pParent),
|
|||
|
|
m_ViewID(viewID),
|
|||
|
|
m_pSurvey(NULL),
|
|||
|
|
m_pOldWorkflow(NULL),
|
|||
|
|
m_pOldSameNameWorkflow(NULL),
|
|||
|
|
m_SaveType(SaveType_DoCancel),
|
|||
|
|
m_SaveSuccess(true),
|
|||
|
|
m_pActiveWorkflow(pActiveWorkflow)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SaveAsWorkflowCmd::~SaveAsWorkflowCmd()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SaveAsWorkflowCmd::undo()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SaveAsWorkflowCmd::redo()
|
|||
|
|
{
|
|||
|
|
if(!m_pActiveWorkflow)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
m_SaveSuccess = HandleSaveAsWorkflow();
|
|||
|
|
|
|||
|
|
// 如果保存工作流成功,则为其再添加一条“Edit”历史记录
|
|||
|
|
if(m_SaveSuccess)
|
|||
|
|
{
|
|||
|
|
PaiWorkflowDataModel *pWorkflow = m_pActiveWorkflow;
|
|||
|
|
if(pWorkflow)
|
|||
|
|
{
|
|||
|
|
PageService* pPageService = GetConsoleGUIService()->GetViewTabService()->GetPageService(m_ViewID);
|
|||
|
|
// 获取数据树上工作流并且设置新名称
|
|||
|
|
PaiObject *pDataTreeWorkflow = GetObjectModelService()->GetObject(pWorkflow->GetDBID());
|
|||
|
|
if(pPageService && pDataTreeWorkflow)
|
|||
|
|
{
|
|||
|
|
pPageService->SetSubtilte(pDataTreeWorkflow->GetVisibleFile());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ActionHistroy history;
|
|||
|
|
history.node = pWorkflow->GetVisibleFile();
|
|||
|
|
history.icon = pWorkflow->GetIconName().section('/', -1);
|
|||
|
|
history.action = QObject::tr("Edit...");
|
|||
|
|
GetPaiGUIService()->GetActionsHistory()->AppendExtraHistory(history);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool SaveAsWorkflowCmd::GetSaveAsResult() const
|
|||
|
|
{
|
|||
|
|
return m_SaveSuccess;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SaveAsWorkflowCmd::CopyWorkflow()
|
|||
|
|
{
|
|||
|
|
if(m_pOldWorkflow == NULL)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 创建新工作流模型
|
|||
|
|
PaiWorkflowDataModel *pNewWorkflow = new PaiWorkflowDataModel();
|
|||
|
|
// 拷贝当前工作流模型到新工作流模型
|
|||
|
|
pNewWorkflow->Copy(*m_pOldWorkflow);
|
|||
|
|
pNewWorkflow->SetEventEnabled(true);
|
|||
|
|
// 设置新的工作流模型为ActiveWorkflow
|
|||
|
|
m_pActiveWorkflow = pNewWorkflow;
|
|||
|
|
|
|||
|
|
// 数据树上的虚拟的PaiObject,现在先这么做,后边再整改
|
|||
|
|
PaiWorkflowDataModel *pDataTreeWorkflow = new PaiWorkflowDataModel();
|
|||
|
|
// 新建的工作流不用和数据库同步
|
|||
|
|
pDataTreeWorkflow->SetIgnoreSyncDB(true);
|
|||
|
|
pDataTreeWorkflow->SetSyncabled(false);
|
|||
|
|
pDataTreeWorkflow->SetDBID(pNewWorkflow->GetDBID());
|
|||
|
|
pDataTreeWorkflow->SetID(pNewWorkflow->GetID());
|
|||
|
|
pDataTreeWorkflow->SetName(m_NewWorkflowName);
|
|||
|
|
|
|||
|
|
if(m_pSurvey && m_pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString())))
|
|||
|
|
{
|
|||
|
|
m_pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()))->AddChild(pDataTreeWorkflow);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SaveAsWorkflowCmd::RestoreWorkflow()
|
|||
|
|
{
|
|||
|
|
if(!m_pActiveWorkflow)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果另存为同一工作流,则无需restore
|
|||
|
|
if((m_pOldWorkflow == NULL) || (m_pOldWorkflow == m_pActiveWorkflow))
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
// save failed restore
|
|||
|
|
if(!(m_SaveType & SaveType_IsNewWorkflow) && !(m_SaveType & SaveType_IsCurrentWorkflow))
|
|||
|
|
{
|
|||
|
|
PaiWorkflowDataModel *pNewWorkflow = m_pActiveWorkflow;
|
|||
|
|
if(m_pOldWorkflow->GetParent())
|
|||
|
|
{
|
|||
|
|
m_pOldWorkflow->GetParent()->RemoveChild(pNewWorkflow, true);
|
|||
|
|
}
|
|||
|
|
else if(m_pSurvey && m_pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString())))
|
|||
|
|
{
|
|||
|
|
m_pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()))->RemoveChild(pNewWorkflow, true);
|
|||
|
|
}
|
|||
|
|
delete pNewWorkflow;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PaiObject* SaveAsWorkflowCmd::GetOldSameNameWorkflow() const
|
|||
|
|
{
|
|||
|
|
if(m_pSurvey && m_pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString())))
|
|||
|
|
{
|
|||
|
|
return m_pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()))->GetObjectByName(m_NewWorkflowName);
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool SaveAsWorkflowCmd::HandleExtensionTabAndNodeSelection()
|
|||
|
|
{
|
|||
|
|
if(!m_pActiveWorkflow)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
PageService *pPageService = GetConsoleGUIService()->GetViewTabService()->GetPageService(m_ViewID);
|
|||
|
|
if(pPageService)
|
|||
|
|
{
|
|||
|
|
std::string oldWorkflowID = m_pOldWorkflow->GetID().toString().toStdString();
|
|||
|
|
// 找到要重设工作流模型的Extension
|
|||
|
|
ViewExtension *pViewExtension = dynamic_cast< ViewExtension* > (pPageService->GetExtension(oldWorkflowID));
|
|||
|
|
// 备份的当前工作流并没有打开编辑界面,即作业界面的SaveAs
|
|||
|
|
if(NULL == pViewExtension)
|
|||
|
|
{
|
|||
|
|
delete m_pActiveWorkflow;
|
|||
|
|
m_pActiveWorkflow = NULL;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// 备份的当前工作流有打开编辑界面 选中保存后的工作流左侧节点
|
|||
|
|
GetObjectModelService()->GetObjectSelection()->Select(m_pActiveWorkflow->GetID(), true);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 为当前工作流编辑界面或者SaveType_IsJobSave情况下打开了同名的工作流编辑界面重设工作流模型
|
|||
|
|
if(pViewExtension)
|
|||
|
|
{
|
|||
|
|
WorkflowWidget *pFindWorkflowWidget = GetFirstChildObject< WorkflowWidget >
|
|||
|
|
(dynamic_cast< QWidget* > (pViewExtension->GetView()));
|
|||
|
|
if(pFindWorkflowWidget)
|
|||
|
|
{
|
|||
|
|
pFindWorkflowWidget->SetWorkflow(m_pActiveWorkflow);
|
|||
|
|
}
|
|||
|
|
std::string workflowID = m_pActiveWorkflow->GetID().toString().toStdString();
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 修改tab页的名字,重新注册
|
|||
|
|
pPageService->CService::Unregister(oldWorkflowID);
|
|||
|
|
pViewExtension->SetViewID(workflowID);
|
|||
|
|
pPageService->CService::Register(pViewExtension, ILocation());
|
|||
|
|
pPageService->SetTabText("A", workflowID, m_pActiveWorkflow->GetName());
|
|||
|
|
}
|
|||
|
|
catch(pai::error::generic_error & e)
|
|||
|
|
{
|
|||
|
|
QString errorMsg = QString("SaveAs Workflow caught an exception. ").append(e.what());
|
|||
|
|
PaiMessageBox::Critical(::GetConsoleGUIService()->GetMainWindow(), PAI_NAME, errorMsg);
|
|||
|
|
pai::log::Error(_FLF(QObject::tr("QUndoCommand::ShowMessage ").toStdString() + errorMsg.toStdString()));
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
delete m_pActiveWorkflow;
|
|||
|
|
m_pActiveWorkflow = NULL;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool SaveAsWorkflowCmd::HandleSaveAsWorkflow()
|
|||
|
|
{
|
|||
|
|
// 如果当前工作流为空直接返回
|
|||
|
|
if(!m_pActiveWorkflow)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存当前个工作流指针
|
|||
|
|
m_pOldWorkflow = m_pActiveWorkflow;
|
|||
|
|
if(!m_pOldWorkflow)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 打开对话框设置另存工作流的名字
|
|||
|
|
m_NewWorkflowName = "";
|
|||
|
|
|
|||
|
|
// 获取数据树上虚拟工作流对应工区
|
|||
|
|
m_pSurvey = SaveHelper::GetSurveyByWfDBID(m_pOldWorkflow->GetDBID());
|
|||
|
|
|
|||
|
|
m_SaveType = SaveHelper::OpenSaveAsDialog(m_NewWorkflowName, &m_pSurvey, m_pOldWorkflow);
|
|||
|
|
|
|||
|
|
// 如果点击取消或者新工作流名称为空直接返回false
|
|||
|
|
if(m_SaveType == SaveType_DoCancel || m_NewWorkflowName.isEmpty())
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
// 获取同名工作流,不存在同名则m_pOldSameNameWorkflow = NULL
|
|||
|
|
m_pOldSameNameWorkflow = GetOldSameNameWorkflow();
|
|||
|
|
|
|||
|
|
// 当旧工作流和同名工作流相同时,即SaveAs为自己,不需要拷贝;
|
|||
|
|
// 新工作流SaveAs为另外一个名的工作流,也不需要拷贝,但是另存到别的工区需要copy,之后将保留copy并删除所谓新工作流
|
|||
|
|
bool bSameWorkflow = false;
|
|||
|
|
if(SaveHelper::GetSurveyByWfDBID(m_pOldWorkflow->GetDBID()))
|
|||
|
|
{
|
|||
|
|
PaiBaseMaster *pWorkflowMaster = SaveHelper::GetSurveyByWfDBID(m_pOldWorkflow->GetDBID())->
|
|||
|
|
GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()));
|
|||
|
|
if(pWorkflowMaster && (m_pOldSameNameWorkflow == pWorkflowMaster->GetObject(m_pOldWorkflow->GetDBID())))
|
|||
|
|
{
|
|||
|
|
bSameWorkflow = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//如果存在同名工作流并且不是Save As自己
|
|||
|
|
if(m_pOldSameNameWorkflow && !bSameWorkflow)
|
|||
|
|
{
|
|||
|
|
//尝试删除同名工作流,看是否能够正常删除
|
|||
|
|
QString errMsg;
|
|||
|
|
if(!m_pOldSameNameWorkflow->TryDelete(errMsg))
|
|||
|
|
{
|
|||
|
|
PaiMessageBox::Critical(::GetConsoleGUIService()->GetMainWindow(),
|
|||
|
|
QObject::tr("Error"),
|
|||
|
|
QObject::tr("Cannot save as \"%1\":\n").arg(m_pOldSameNameWorkflow->GetName()) + errMsg,
|
|||
|
|
PaiMessageBox::Ok,
|
|||
|
|
PaiMessageBox::Ok);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// Save As不是自己
|
|||
|
|
if(!bSameWorkflow)
|
|||
|
|
{
|
|||
|
|
CopyWorkflow();
|
|||
|
|
}
|
|||
|
|
// 设置新工作流名称
|
|||
|
|
m_pActiveWorkflow->SetName(m_NewWorkflowName);
|
|||
|
|
|
|||
|
|
CWorkFlowFile *pWorkflowFile = m_pActiveWorkflow->GetWorkflowFile();
|
|||
|
|
QString surveyPath;
|
|||
|
|
if(m_pSurvey && pWorkflowFile)
|
|||
|
|
{
|
|||
|
|
surveyPath.append(m_pSurvey->GetPhysicalFile());
|
|||
|
|
std::vector < std::string > outPutfiles;
|
|||
|
|
pWorkflowFile->GetOutPutFilePaths(outPutfiles);
|
|||
|
|
|
|||
|
|
std::vector < std::string > updatedOutPutfiles;
|
|||
|
|
foreach(std::string file, outPutfiles)
|
|||
|
|
{
|
|||
|
|
if (!file.empty())
|
|||
|
|
{
|
|||
|
|
int pos = file.find_last_of("/");
|
|||
|
|
file.replace(0, pos, surveyPath.toStdString());
|
|||
|
|
}
|
|||
|
|
updatedOutPutfiles.push_back(file);
|
|||
|
|
}
|
|||
|
|
pWorkflowFile->SetOutPutFilePaths(updatedOutPutfiles);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果存在同名工作流并且不是Save As自己
|
|||
|
|
if(m_pOldSameNameWorkflow && !bSameWorkflow)
|
|||
|
|
{
|
|||
|
|
// 做删除操作
|
|||
|
|
QString errorMsg;
|
|||
|
|
if(m_pOldSameNameWorkflow->Erase(&errorMsg))//从数据库删除
|
|||
|
|
{
|
|||
|
|
if(SaveHelper::GetSurveyByWfDBID(m_pOldSameNameWorkflow->GetDBID()))
|
|||
|
|
{
|
|||
|
|
pai::objectmodel::PaiObject *pParent = SaveHelper::GetSurveyByWfDBID(m_pOldSameNameWorkflow->GetDBID())->
|
|||
|
|
GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()));
|
|||
|
|
if(pParent)
|
|||
|
|
{
|
|||
|
|
// 从内存树删除并通知数据树
|
|||
|
|
pParent->RemoveChild(m_pOldSameNameWorkflow, true);
|
|||
|
|
|
|||
|
|
PaiObject *pShadowObject = GetObjectModelService()->GetObject(m_pOldSameNameWorkflow->GetDBID());
|
|||
|
|
if(pShadowObject)
|
|||
|
|
{
|
|||
|
|
pParent = pShadowObject->GetParent();
|
|||
|
|
if(pParent)
|
|||
|
|
{
|
|||
|
|
// 从内存树删除并通知数据树
|
|||
|
|
pParent->RemoveChild(pShadowObject, true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
PaiMessageBox::Critical(::GetConsoleGUIService()->GetMainWindow(), QObject::tr("Error!"), errorMsg);
|
|||
|
|
pai::log::Error(_FLF(QObject::tr("QUndoCommand::ShowMessage ").toStdString() + errorMsg.toStdString()));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存工作流模型
|
|||
|
|
if(SaveHelper::SaveWorkflow(m_pActiveWorkflow) == false)
|
|||
|
|
{
|
|||
|
|
RestoreWorkflow();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 工作流有修改,并且非Save As自己
|
|||
|
|
if(m_pOldWorkflow->HasDataModified() && !bSameWorkflow)
|
|||
|
|
{
|
|||
|
|
if(SaveHelper::GetSurveyByWfDBID(m_pOldWorkflow->GetDBID()) && SaveHelper::GetSurveyByWfDBID(
|
|||
|
|
m_pOldWorkflow->GetDBID())->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString())) && !(m_SaveType
|
|||
|
|
& SaveType_IsNewWorkflow))
|
|||
|
|
{
|
|||
|
|
// 刷新原来的工作流,保持原来未编辑的状态,但不能是从作业打开的工作流
|
|||
|
|
// 作业打开的工作流这么刷新界面是空的
|
|||
|
|
m_pOldWorkflow->ReloadDataModuel();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 跨工区另存新工作流,则将前工区下新建的工作流删除
|
|||
|
|
if(!bSameWorkflow && m_SaveType & SaveType_IsNewWorkflow)
|
|||
|
|
{
|
|||
|
|
if(SaveHelper::GetSurveyByWfDBID(m_pOldWorkflow->GetDBID()))
|
|||
|
|
{
|
|||
|
|
PaiObject *pParent = SaveHelper::GetSurveyByWfDBID(m_pOldWorkflow->GetDBID())->
|
|||
|
|
GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()));
|
|||
|
|
if(pParent)
|
|||
|
|
{
|
|||
|
|
// 从内存树删除并通知数据树
|
|||
|
|
pParent->RemoveChild(GetObjectModelService()->GetObject(m_pOldWorkflow->GetDBID()), true);
|
|||
|
|
|
|||
|
|
PaiObject *pShadowObject = GetObjectModelService()->GetObject(m_pOldWorkflow->GetDBID());
|
|||
|
|
if(pShadowObject)
|
|||
|
|
{
|
|||
|
|
pParent = pShadowObject->GetParent();
|
|||
|
|
if(pParent)
|
|||
|
|
{
|
|||
|
|
// 从内存树删除并通知数据树
|
|||
|
|
pParent->RemoveChild(pShadowObject, true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
m_pActiveWorkflow->SetModify(false);
|
|||
|
|
GetObjectModelService()->GetObjectSelection()->Select(m_pActiveWorkflow->GetID(), true);
|
|||
|
|
|
|||
|
|
QString text = QObject::tr("Workflow \"") + m_NewWorkflowName + QObject::tr("\"") +
|
|||
|
|
" saved." + "<br> Double click to open it or right click to open menu.";
|
|||
|
|
PaiBalloonGuide::GetInstance()->ShowInstantTip(m_pActiveWorkflow->GetID(), text, QObject::tr("SaveAsWorkflow"));
|
|||
|
|
|
|||
|
|
if(HandleExtensionTabAndNodeSelection() == false)
|
|||
|
|
{
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|