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