logplus/Workflow/WFEngine/Component/WorkflowWidget/src/SaveHelper.cpp

504 lines
19 KiB
C++
Raw Normal View History

2026-01-16 17:18:41 +08:00
/**
* @file SaveHelper.cpp
* @date 2012-10-17
* @author liujunxia
*/
#include <QDir>
#include <QtDebug>
#include "SaveHelper.h"
#include "PaiObject.h"
#include "PaiProject.h"
#include "PaiWorkflowDataModel.h"
#include "WorkflowConst.h"
#include "PaiSaveAsWorkflowDialog.h"
#include "ConsoleGUIService.h"
#include "PaiInputDialog.h"
#include "WorkflowWidget.h"
#include "PaiWorkflowMaster.h"
#include "PaiMessageBox.h"
#include "Log.h"
#include "GlobalModuleBackup.h"
#include "PAIConst.h"
#include "ViewExtension.h"
#include "WorkflowWidget.h"
#include "PaiPermissionChecker.h"
#include "PaiTextEdit.h"
#include "PaiSurvey.h"
using namespace pai;
using namespace pai::objectmodel;
using namespace pai::gui;
using namespace pai::graphics2d;
#define PROPERTIES_VIEW_ID "Properties"
pai::graphics2d::WorkflowWidget* SaveHelper::m_pActiveWorkflowWidget = NULL;
QString SaveHelper::m_ExceptionWhat = "";
int SaveHelper::m_ExceptionWhich = pai::error::ERR_SUCCESS;
SaveHelper::SaveHelper()
{
}
SaveHelper::~SaveHelper()
{
}
void SaveHelper::SetSaveException(const QString & what, const int which)
{
m_ExceptionWhat = what;
m_ExceptionWhich = which;
}
QString SaveHelper::GetSaveExceptionWhat()
{
return m_ExceptionWhat;
}
int SaveHelper::GetSaveExceptionWhich()
{
return m_ExceptionWhich;
}
int SaveHelper::OpenSaveDialog(QString &workflowName, PaiSurvey** ppSurvey, pai::objectmodel::PaiWorkflowDataModel*pActiveWorkflow)
{
return OpenSaveDialog(true, workflowName, ppSurvey, pActiveWorkflow);
}
int SaveHelper::OpenSaveAsDialog(QString &workflowName, PaiSurvey** ppSurvey, pai::objectmodel::PaiWorkflowDataModel*pActiveWorkflow)
{
return OpenSaveDialog(false, workflowName, ppSurvey, pActiveWorkflow);
}
bool SaveHelper::SaveWorkflow(pai::objectmodel::PaiWorkflowDataModel* pWorkflow, bool isTemplate)
{
bool ret = false;
QCursor oldCursor = ::GetConsoleGUIService()->GetMainWindow()->cursor();
::GetConsoleGUIService()->GetMainWindow()->setCursor(Qt::WaitCursor);
//为提交而保存成json文件
QString strJsonFileName("/tmp/");
if(isTemplate)
{
strJsonFileName = "/tmp/template/";
}
strJsonFileName += pWorkflow->GetName();
QString strID = pWorkflow->GetID().toString();//这里取ID来保证/tmp/下的工作流文件名唯一
strID.remove('{').remove('-').remove('}');
strJsonFileName += strID;
strJsonFileName += ".json";
pWorkflow->SetAsTemplate(isTemplate);
if(SaveWorkflowJson(pWorkflow, strJsonFileName) == true)
{
//保存到数据库(包括刚才保存的文件)
try
{
QString strErrMsg;
ret = true;
long long wfDBID = pWorkflow->GetDBID();
if(!(pWorkflow->HasFlag(PaiObject::Loaded)))
{
if(!pWorkflow->SaveToDB(&strErrMsg, isTemplate))
{
pai::log::Debug(_FLF(strErrMsg.toStdString()));
ret = false;
}
else if(!isTemplate)
{
bool locked = GetObjectModelService()->GetObjectLockManager()->IsObjectLocked(wfDBID);
if (locked && m_pActiveWorkflowWidget && (pWorkflow == m_pActiveWorkflowWidget->GetWorkflow()))
{
// after saving a new workflow, we need to update the object lock
// because the object DBID will change.
m_pActiveWorkflowWidget->UpdateWorkflowLock(wfDBID);
}
}
}
else
{
if(!pWorkflow->UpdateToDB(&strErrMsg, isTemplate))
{
pai::log::Debug(_FLF(strErrMsg.toStdString()));
ret = false;
}
}
if(!isTemplate)
{
//获取数据树上虚拟工作流
PaiObject *pDataTreeWorkflow = GetObjectModelService()->GetObject(wfDBID);
if(pDataTreeWorkflow)
{
PaiWorkflowDataModel *pTmpWorkflow = dynamic_cast<PaiWorkflowDataModel*>(pDataTreeWorkflow);
if(pTmpWorkflow && pWorkflow->GetWorkflowPtr())
{
pTmpWorkflow->SetDBWorkflow(pWorkflow->GetWorkflowPtr()->GetWorkflwoPtr());
pTmpWorkflow->SetDBID(pWorkflow->GetDBID());
//做删除操作时会用到这个id
pTmpWorkflow->GetWorkflowPtr()->SetID(pWorkflow->GetWorkflowPtr()->GetID());
pTmpWorkflow->SetIgnoreSyncDB(false);
pTmpWorkflow->SetSyncabled(true);
}
}
}
}
catch(pai::error::generic_error & e)
{
SetSaveException(e.what(), e.which());
pai::log::Info(_FLF(pWorkflow->GetName().toStdString() + " save workflow caught an exception. " + e.what()));
ret = false;
}
}
GlobalModuleBackup *pModuleBack = ::GetGlobalModuleBackup();
pModuleBack->UpDateBackupModule(pWorkflow->GetID());
::GetConsoleGUIService()->GetMainWindow()->setCursor(oldCursor);
return ret;
}
bool SaveHelper::SaveWorkflowJson(pai::objectmodel::PaiWorkflowDataModel* pWorkflow, const QString& jsonFilePath)
{
if(jsonFilePath == "")
{
ShowMessage(PAI_NAME, "Save failure for empty workflow file name.");
return false;
}
if(pWorkflow != NULL)
{
try
{
if(pWorkflow->IsTemplate())//判断是否为模板
{
//判断模板的保存目录是否存在,不存在则创建该目录
QDir templateDir("/tmp/template");
if(!templateDir.exists("/tmp/template"))
{
templateDir.mkdir("/tmp/template");
QFile::setPermissions("/tmp/template",
QFile::ReadUser
| QFile::WriteUser
| QFile::ExeUser
| QFile::ReadGroup
| QFile::WriteGroup
| QFile::ExeGroup
| QFile::ReadOther
| QFile::WriteOther
| QFile::ExeOther);
}
}
if(!pWorkflow->Save(jsonFilePath.toStdString()))
{
if(pWorkflow->IsTemplate())
{
ShowMessage(PAI_NAME, "Save template failure");
}
else
{
ShowMessage(PAI_NAME, "Save workflow failure");
}
return false;
}
return true;
}
catch(std::exception &ex)
{
if(::GetConsoleGUIService())
{
pai::gui::PaiMessageBox::Critical(::GetConsoleGUIService()->GetMainWindow(), PAI_NAME,
QObject::tr("Save workflow %1 caught an exception. ").arg(pWorkflow->GetName()).append(ex.what()));
}
pai::log::Error(_FLF(pWorkflow->GetName().toStdString() + " save workflow caught an exception. " + ex.what()));
}
}
return false;
}
PaiTextEdit* SaveHelper::GetPropertiesTextEdit()
{
ViewExtension * pViewExtension =
dynamic_cast< ViewExtension* > (GetConsoleGUIService()->GetUtilityTabService()->GetExtension(PROPERTIES_VIEW_ID));
if(pViewExtension)
{
return dynamic_cast< PaiTextEdit* > (pViewExtension->GetView());
}
return NULL;
}
void SaveHelper::SetActiveWorkflowView(WorkflowWidget* pWorkflowWidget)
{
m_pActiveWorkflowWidget = pWorkflowWidget;
}
WorkflowWidget* SaveHelper::GetActiveWorkflowView()
{
return m_pActiveWorkflowWidget;
}
void SaveHelper::ShowMessage(const QString& title, const QString& message)
{
ConsoleGUIService* pServer = ::GetConsoleGUIService();
if(pServer)
{
pai::gui::PaiMessageBox::Information(pServer->GetMainWindow(), title, message);
}
pai::log::Info(_FLF(QObject::tr("ControlExtension::ShowMessage").toStdString() + message.toStdString()));
}
/*
* OpenSaveDialog ValidateSaveWorkflowName
* 使Save和SaveAs两种情况
* Save操作使OpenSaveDialog
* SaveAs操作使OpenSaveDialog
*
*
* 1.SaveType_DoCancel
* 2.newoldoldold工作流(SaveType_DoSave | SaveType_DoReplace)
* 3.newnewnew(SaveType_DoSave)
* 4.newnew2new2(SaveType_DoSave)
* 5.oldold2
* old2old2工作流(SaveType_DoCopy | SaveType_DoSave | SaveType_DoReplace)
* 6.oldoldold(SaveType_DoSave)
* 7.oldnewnew(SaveType_DoCopy | SaveType_DoSave);
* 8.(SaveType_DoOpenDialog)
*/
int SaveHelper::OpenSaveDialog(bool save, QString &workflowName, pai::objectmodel::PaiSurvey** ppSurvey, pai::objectmodel::PaiWorkflowDataModel*pActiveWorkflow)
{
PaiWorkflowDataModel *pCurrentWorkflow = pActiveWorkflow;
if(!pCurrentWorkflow)
{
return (SaveType_DoCancel);
}
if(!save)
{
long long projectID = 0;
long long surveyID = 0;
if(*ppSurvey)
{
pai::objectmodel::PaiProject *pProject = (*ppSurvey)->GetForebear< pai::objectmodel::PaiProject > ();
if(pProject)
{
projectID = (*ppSurvey)->GetForebear< pai::objectmodel::PaiProject > ()->GetDBID();
}
surveyID = (*ppSurvey)->GetDBID();
}
pai::gui::PaiSaveAsWorkflowDialog iDlg(projectID, surveyID, pActiveWorkflow->GetName(), ::GetConsoleGUIService()->GetMainWindow());
int result = QDialog::Rejected;
while((result = iDlg.exec()) != QDialog::Rejected)
{
workflowName = iDlg.GetSaveAsWorkflowName();
//获取选中的工区
PaiSurvey* pSelectSurvey = iDlg.GetSelectedSurvey();
*ppSurvey = pSelectSurvey;
if(result == QDialog::Accepted && "" != workflowName)
{
bool permission = true;
try
{
//添加指针为空的判断防止为空的情况还获取DBID 导致的系统崩溃
if(pSelectSurvey)
{
permission = PaiPermissionChecker::HasPermission(dynamic_cast<PaiObject*> (pSelectSurvey), PaiAction::PaiPermissionTypes(PaiAction::UPDATE));
}
else
{
permission = false;
}
}
catch(pai::error::generic_error & e)
{
permission = false;
}
catch(...)
{
permission = false;
}
if(!permission)
{
PaiMessageBox::Critical(&iDlg, QObject::tr("π-Frame Workflow"),
QObject::tr("You don't have permission to save Workflow into this Survey, please select another one."),
PaiMessageBox::Ok, PaiMessageBox::Ok);
iDlg.ResetValidateNameEdit();
continue;
}
int findResult = ValidateSaveWorkflowName(save, workflowName, pActiveWorkflow, pSelectSurvey);
if(findResult & SaveType_DoOpenDialog)
{
iDlg.ResetValidateNameEdit();
continue;
}
else
{
return findResult;
}
}
else
{
//1.取消操作
return (SaveType_DoCancel);
}
}
}
else
{
//在左保存之前先把数据树上的workflow同步一下
PaiSurvey *pSurvey = GetSurveyByWfDBID(pCurrentWorkflow->GetDBID());
PaiObject *pWorkflowMaster = NULL;
if(pSurvey)
{
pWorkflowMaster = pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString()));
}
if(pWorkflowMaster && pWorkflowMaster->HasFlag(PaiObject::ChildrenLoaded))
{
pWorkflowMaster->SyncDB(pai::Children | pai::Force);
}
//打开对话框设置工作流的名字
PaiInputDialog dlgNameWorkflow(::GetConsoleGUIService()->GetMainWindow());
dlgNameWorkflow.SetOkButtonText("&Save");
if(save)
{
dlgNameWorkflow.setWindowTitle(g_szSave);
}
else
{
dlgNameWorkflow.setWindowTitle(g_szSaveAs);
}
dlgNameWorkflow.SetLabelText("Please enter the workflow name:");
dlgNameWorkflow.SetText(pCurrentWorkflow->GetName());
dlgNameWorkflow.UseValidateNameEdit(g_iMaxWorkflowNameLength);
int result = QDialog::Rejected;
while((result = dlgNameWorkflow.exec()) != QDialog::Rejected)
{
workflowName = dlgNameWorkflow.TextValue();
if((result == QDialog::Accepted) && ("" != workflowName))
{
int findResult = ValidateSaveWorkflowName(save, workflowName, pActiveWorkflow);
if(findResult & SaveType_DoOpenDialog)
{
dlgNameWorkflow.ResetValidateNameEdit();
continue;
}
else
{
return findResult;
}
}
else
{
//1.取消操作
return (SaveType_DoCancel);
}
}
}
//1.取消操作
return (SaveType_DoCancel);
}
int SaveHelper::ValidateSaveWorkflowName(bool save, const QString& workflowName, pai::objectmodel::PaiWorkflowDataModel*pActiveWorkflow, pai::objectmodel::PaiSurvey* pSurvey)
{
int ret = SaveType_IsWorkOpen;
PaiWorkflowDataModel *pCurrentWorkflow = pActiveWorkflow;
if(!pCurrentWorkflow)
{
return ret;
}
QList< PaiObject* > lstChildren;
//获取数据树上虚拟工作流
PaiObject *pDataTreeWorkflow = GetObjectModelService()->GetObject(pActiveWorkflow->GetDBID());
//当前工作流有父节点的使用父节点获得工作流子节点列表,没有的如果参数指定了工区,使用工区获得工作流管理器进而得到工作流字节点列表。
if(save && pDataTreeWorkflow && (pDataTreeWorkflow->GetParent()))
{
pDataTreeWorkflow->GetParent()->GetChildren(lstChildren);
}
else if(pSurvey != NULL && pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString())) != NULL)
{
PaiWorkflowMaster* pMaster =
dynamic_cast< PaiWorkflowMaster* > (pSurvey->GetMaster(QUuid(PaiWorkflowMaster::GetTypeIDString())));
pMaster->SyncDB(pai::Children | pai::Force);
pMaster->GetChildren(lstChildren);
}
if(!(pCurrentWorkflow->HasFlag(PaiObject::Loaded)) && pDataTreeWorkflow && (pDataTreeWorkflow->GetParent()))
{
ret |= SaveType_IsNewWorkflow;
}
for(int i = 0; i < lstChildren.size(); ++i)
{
PaiObject* pModel = lstChildren.at(i);
if(pModel->GetName() == workflowName)
{
if((dynamic_cast< PaiWorkflowDataModel* > (pModel) == pDataTreeWorkflow) && (ret & SaveType_IsNewWorkflow))
{
ret |= SaveType_IsCurrentWorkflow;
continue;
}
ret |= SaveType_ExistSameName;
QWidget* pMainWindow = ::GetConsoleGUIService()->GetMainWindow();
QString body = QObject::tr("workflow %1 exists. Do you want to replace it?").arg(workflowName);
int r = PaiMessageBox::Warning(pMainWindow, "π-Frame Workflow", body, PaiMessageBox::Yes
| PaiMessageBox::No, PaiMessageBox::Yes);
if(r == PaiMessageBox::No)
{
ret = SaveType_DoOpenDialog;
return ret;
}
return ret;
}
}
return ret;
}
QList< PaiWorkflowDataModel* > SaveHelper::GetModifiedWorkflows(QUuid viewID)
{
QList< PaiWorkflowDataModel* > lstWorkflows;
PageService* pPageService = GetConsoleGUIService()->GetViewTabService()->GetPageService(viewID);
if(pPageService != NULL)
{
QWidget* pWorkflowTabs = pPageService->GetWidgetView("A");
if(pWorkflowTabs != NULL)
{
QList< WorkflowWidget* > lstWorkflowWidgets = pWorkflowTabs->findChildren< WorkflowWidget* > ();
foreach(WorkflowWidget* pWorkflowWidget, lstWorkflowWidgets)
{
PaiWorkflowDataModel* pWorkflow = pWorkflowWidget->GetWorkflow();
if (pWorkflow != NULL && pWorkflow->HasDataModified())
{
lstWorkflows.prepend(pWorkflow);
}
}
}
}
return lstWorkflows;
}
pai::objectmodel::PaiSurvey* SaveHelper::GetSurveyByWfDBID(long long workflowDBID)
{
//获取数据树上虚拟工作流
PaiObject *pDataTreeWorkflow = GetObjectModelService()->GetObject(workflowDBID);
//获取工作流所在工区
if(!pDataTreeWorkflow)
{
return NULL;
}
PaiSurvey *pSurvey = pDataTreeWorkflow->GetForebear< PaiSurvey > ();
return pSurvey;
}