|
|
#include "zxLogInstance.h"
|
|
|
#include "iRibbonXmlCmd.h"
|
|
|
#include <QDebug>
|
|
|
#include "zxSysUtils.h"
|
|
|
#include "ZxUiBase.h"
|
|
|
|
|
|
#include "ZxMainWindow.h"
|
|
|
#include "ZxTabWidget.h"
|
|
|
#include "TreeWxMain.h"
|
|
|
#include "iDockBaseWx.h"
|
|
|
|
|
|
#include "iModuleHelper.h"
|
|
|
#include "ZxDataWell.h"
|
|
|
#include "ZxDataProject.h"
|
|
|
|
|
|
#include "nmFrameworkTest.h"
|
|
|
#include "iSubWndFitting.h"
|
|
|
|
|
|
#ifdef MY_OWN_GRID
|
|
|
#include "iSubWndGrid.h"
|
|
|
#else
|
|
|
#include "nmSubWndDemo.h"
|
|
|
#endif
|
|
|
|
|
|
#include "nmSubWndUtils.h"
|
|
|
|
|
|
#include "nmSubWndMain.h"
|
|
|
#include "nmSubWndGrid.h"
|
|
|
#include "nmSubWndPostprocessing.h"
|
|
|
|
|
|
#include "nmWxGridDlg.h"
|
|
|
|
|
|
#include "nmWxPostprocessingAnimationWidget.h"
|
|
|
|
|
|
#include "nmGuiPlot.h"
|
|
|
#include "ZxObjBase.h"
|
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
#include "iRibbonXmlTab.h"
|
|
|
#include "nmWxParameterProperty.h"
|
|
|
#include "nmWxNumericalDesign.h"
|
|
|
#include "nmDataOutline.h"
|
|
|
|
|
|
#include "ZxRstWnd.h"
|
|
|
|
|
|
#include "nmWxChangeAnal.h"
|
|
|
#include "nmDataAxis.h"
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
// 判断指定相态下是否至少有一个PVT曲线结果
|
|
|
bool hasPvtCurve(iSubWndFitting* pSubWndF, PvtFluidType eType, const QStringList& listParas)
|
|
|
{
|
|
|
if(pSubWndF == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
for(int i = 0; i < listParas.size(); ++i) {
|
|
|
VecDouble vecX;
|
|
|
QVector<double> vecY;
|
|
|
pSubWndF->getPvtRstOf(eType, listParas[i], vecX, vecY);
|
|
|
|
|
|
if(!vecX.isEmpty()) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
nmSubWndUtils* nmSubWndUtils::getInstance()
|
|
|
{
|
|
|
static nmSubWndUtils s_instance; // 在第一次调用时创建唯一实例
|
|
|
return &s_instance;
|
|
|
}
|
|
|
|
|
|
nmSubWndUtils::nmSubWndUtils()
|
|
|
{
|
|
|
m_pMainWnd = nullptr;
|
|
|
m_pTabWx = nullptr;
|
|
|
}
|
|
|
|
|
|
nmSubWndUtils::~nmSubWndUtils() {}
|
|
|
|
|
|
iSubWnd* nmSubWndUtils::createSubWnd(const iRibbonXmlCmd* pCmdInfo, \
|
|
|
const ZxMainWindow* pMainWnd, \
|
|
|
bool& bCreatedNewOne)
|
|
|
{
|
|
|
if (nullptr == pCmdInfo)
|
|
|
{
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
// TODO 此处是自行控制是否单一模式
|
|
|
bool bOnlyOneForCurTabWx = true;
|
|
|
return makesureSubWnd(pCmdInfo->m_sID, pCmdInfo->m_sExtInfo, \
|
|
|
pMainWnd, bCreatedNewOne, \
|
|
|
bOnlyOneForCurTabWx);
|
|
|
}
|
|
|
|
|
|
iSubWnd* nmSubWndUtils::makesureSubWnd(QString sID, QString sExt, \
|
|
|
const ZxMainWindow* pMainWnd, \
|
|
|
bool& bCreatedNewOne, \
|
|
|
bool bOnlyOneForCurTabWx /*= true*/)
|
|
|
{
|
|
|
Q_ASSERT (nullptr != pMainWnd);
|
|
|
|
|
|
//单一模式,则先查找,如果已经存在,则直接返回
|
|
|
if (bOnlyOneForCurTabWx)
|
|
|
{
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx(); //仅仅在当前TabWx下查找,此处可以根据需要调整
|
|
|
if (nullptr != pTabWx)
|
|
|
{
|
|
|
for (int i = 0; i < pTabWx->count(); i++)
|
|
|
{
|
|
|
iSubWnd* pSubWnd = dynamic_cast<iSubWnd*>(pTabWx->widget(i));
|
|
|
if (nullptr != pSubWnd)
|
|
|
{
|
|
|
if (_isSame(sID, pSubWnd->getWndID()))
|
|
|
{
|
|
|
bCreatedNewOne = false;
|
|
|
|
|
|
// TODO 根据需要,是否需要激活当前
|
|
|
if (i != pTabWx->currentIndex())
|
|
|
{
|
|
|
pTabWx->setCurrentIndex(i);
|
|
|
}
|
|
|
|
|
|
return pSubWnd;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 创建新的
|
|
|
bCreatedNewOne = true;
|
|
|
iSubWnd* pSubWnd = nullptr;
|
|
|
|
|
|
// Here is your own codes
|
|
|
int nID = sID.toInt();
|
|
|
|
|
|
if(nID == 5118) {
|
|
|
|
|
|
// TODO:提示应该先打开一个分析
|
|
|
//QMessageBox::information(pSubWnd, tr("error"), tr("please open an analyze!"));
|
|
|
|
|
|
// 判断油藏参数是否已经初始化
|
|
|
//if(nmDataAnalyzeManager::getCurrentInstance()->getReservoirData() == nullptr) {
|
|
|
// // 初始化油藏参数
|
|
|
// nmDataAnalyzeManager::getCurrentInstance()->createReservoir();
|
|
|
// // 初始化PVT
|
|
|
// nmDataAnalyzeManager::getCurrentInstance()->initPvtParaFromSubFit();
|
|
|
//}
|
|
|
|
|
|
// 1、获取当前窗体下的所有流动段分析
|
|
|
|
|
|
// 选择一个流动段分析里的数据作为当前地图要展示的数据
|
|
|
|
|
|
// TODO:2、没有流动段分析
|
|
|
if(nmDataAnalyzeManager::getCurrentFitting() != nullptr) {
|
|
|
nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, sExt);
|
|
|
pSubWnd = pSubWndMain;
|
|
|
} else {
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
QMessageBox::information(pMainWnd1, tr("No Data"), tr("please open an Fitting and click Numerical button"));
|
|
|
}
|
|
|
} else if(nID == 5114) {
|
|
|
// PEBI GridControl控制参数,对应HX_NWTM_GRID_INPUT::GridControl
|
|
|
double dPebiGridControl = 150.0;
|
|
|
bool bGeneratePebiGrid = true;
|
|
|
|
|
|
// 判断是否是加载进来的数据,如果不是加载进来的,则需要添加设置网格信息的对话框
|
|
|
if(!nmDataAnalyzeManager::getCurrentInstance()->m_bIsLoadData) {
|
|
|
// 当前只保留PEBI网格,弹窗只需要设置GridControl
|
|
|
nmWxGridDlg dlg(&dPebiGridControl);
|
|
|
|
|
|
if(dlg.exec() == QDialog::Rejected) {
|
|
|
return NULL;
|
|
|
}
|
|
|
} else {
|
|
|
// 更新标志
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->m_bIsLoadData = false;
|
|
|
bGeneratePebiGrid = false;
|
|
|
}
|
|
|
|
|
|
// 创建PEBI网格窗口;新建数据时生成网格,加载数据时直接展示已加载结果。
|
|
|
nmSubWndGrid* pSubWndGrid = new nmSubWndGrid(NULL, sExt, dPebiGridControl, bGeneratePebiGrid);
|
|
|
disconnect(nmDataAnalyzeManager::getCurrentInstance(), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()));
|
|
|
connect(nmDataAnalyzeManager::getCurrentInstance(), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection);
|
|
|
pSubWnd = pSubWndGrid;
|
|
|
} else if(nID == 5116) {
|
|
|
// 后处理
|
|
|
nmSubWndPostprocessing* pSubWndPostProcessing = new nmSubWndPostprocessing(NULL, sExt);
|
|
|
pSubWnd = pSubWndPostProcessing;
|
|
|
}
|
|
|
|
|
|
if(NULL != pSubWnd) {
|
|
|
// TODO 此处根据需要设置 改变 标识
|
|
|
pSubWnd->setModified(true);
|
|
|
}
|
|
|
|
|
|
return pSubWnd;
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::runCmdBySpecial(const iRibbonXmlCmd* pCmdInfo, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
//nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance();
|
|
|
// 第一次创建,TODO:或者打开另一个窗体时连接槽函数,避免多次调用
|
|
|
//if (pUtilsInstance->m_pMainWnd == nullptr || pUtilsInstance->m_pMainWnd != pMainWnd)
|
|
|
//{
|
|
|
// // 第一次操作时连接tab的槽函数
|
|
|
// ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
// if (nullptr != pMainWnd1)
|
|
|
// {
|
|
|
// pUtilsInstance->m_pMainWnd = pMainWnd1;
|
|
|
// ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx();
|
|
|
// if (nullptr != pTabWx){
|
|
|
// disconnect(pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
|
|
|
// connect(pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
|
|
|
// }
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance();
|
|
|
|
|
|
if(nullptr != pMainWnd1) {
|
|
|
ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx();
|
|
|
|
|
|
if(nullptr != pTabWx) {
|
|
|
if(pUtilsInstance->m_pTabWx == nullptr || pUtilsInstance->m_pTabWx != pTabWx) {
|
|
|
pUtilsInstance->m_pTabWx = pTabWx;
|
|
|
disconnect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
|
|
|
connect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(nullptr == pCmdInfo) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 20250310 测试Release崩溃问题,暂时放开
|
|
|
//#ifdef QT_DEBUG
|
|
|
|
|
|
// 专门提供给数值模块,进行一些框架代码的调试
|
|
|
if (_isSame(pCmdInfo->m_sID, "5999"))
|
|
|
{
|
|
|
nmFrameworkTest::testFrmCodes(pCmdInfo, pMainWnd);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
//#endif
|
|
|
|
|
|
return runCmdBySpecial(pCmdInfo->m_sID, pCmdInfo->m_sExtInfo, pMainWnd);
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::runCmdBySpecial(QString sID, QString sExt, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
// Here is your own codes
|
|
|
if(_isSame(sID, "12345")) {
|
|
|
QMessageBox::information(nullptr, zxAppDescEN, QObject::tr("I am abc"));
|
|
|
return true;
|
|
|
} if(_isSame(sID, "5130")) {
|
|
|
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
// 创建并显示对话框
|
|
|
nmWxChangeAnal analChangeDlg(nullptr, pMainWnd1);
|
|
|
|
|
|
// 执行对话框并判断返回值
|
|
|
if(analChangeDlg.exec() == QDialog::Accepted) {
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::isEnableOfID_Common(QString sID, QString sName, \
|
|
|
const bool bLicensed, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
// 20250310 测试Release崩溃问题,暂时放开
|
|
|
//#ifdef QT_DEBUG
|
|
|
|
|
|
// 专门提供给数值模块,进行一些框架代码的调试
|
|
|
if (_isSame(sID, "5999"))
|
|
|
{
|
|
|
return (true);
|
|
|
}
|
|
|
|
|
|
//#endif
|
|
|
|
|
|
bool b1 = (nullptr != zxCurProject);
|
|
|
// Here is your own codes
|
|
|
if (_isSame(sID, "5101"))
|
|
|
{
|
|
|
return (true);
|
|
|
}
|
|
|
else if (_isSame(sID, "5002")) //或者 _isSame(sName, "PropertyLoad")
|
|
|
{
|
|
|
// <Cmd ID="5002" Bounds="0,1,2,1" Name="PropertyLoad" Alias="属性导入"
|
|
|
// TODO 只有当前窗体为流动分析或者流动段选择的情况下才能点击
|
|
|
bool bOk = false;
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
if (nullptr != pMainWnd1)
|
|
|
{
|
|
|
iSubWnd* pSubWnd = pMainWnd1->getCurSubWnd(); //当前窗体
|
|
|
if (nullptr != pSubWnd)
|
|
|
{
|
|
|
QString sCurID = pSubWnd->getWndID();
|
|
|
bOk = (_isSame(sCurID, "3003") || _isSame(sCurID, "3004")
|
|
|
// || _isSame(sCurID, "6001") //TODO 这是试井设计页面,待定
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return bOk;
|
|
|
} else if(_isSame(sName, "NmMap")) {
|
|
|
return (b1 && bLicensed);
|
|
|
} else if(_isSame(sName, "NmAnalChange")) {
|
|
|
return (b1 && bLicensed);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::dealwithRibbonTab(iRibbonXmlTab* pTab, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
return false; //your own codes
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::fillNmDockWxs(iSubWnd* pSubWnd)
|
|
|
{
|
|
|
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
|
|
|
Q_ASSERT(nullptr != pSubWndF);
|
|
|
if(pSubWndF == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 如果当前分析没有对应相态的PVT相关参数,提示并返回
|
|
|
//PvtFluidType eType = pSubWndF->getBasicPft();
|
|
|
//bool bHasPvtData = false;
|
|
|
|
|
|
//if(eType == WFT_Oil) {
|
|
|
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Oil, QStringList() << "Rs" << "Bo" << "Co" << "Rhoo" << "Miuo");
|
|
|
//} else if(eType == WFT_Gas) {
|
|
|
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Gas, QStringList() << "Rv" << "Bg" << "Cg" << "Miug" << "Rhog" << "Zg");
|
|
|
//} else if(eType == WFT_Water) {
|
|
|
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Water, QStringList() << "Rsw" << "Bw" << "Cw" << "Miuw" << "Rhow");
|
|
|
//} else if(eType == WFT_Oil_Water) {
|
|
|
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Oil, QStringList() << "Rs" << "Bo" << "Co" << "Rhoo" << "Miuo")
|
|
|
// || hasPvtCurve(pSubWndF, WFT_Water, QStringList() << "Rsw" << "Bw" << "Cw" << "Miuw" << "Rhow");
|
|
|
//}
|
|
|
|
|
|
//if(!bHasPvtData) {
|
|
|
// QString appDir = QCoreApplication::applicationDirPath();
|
|
|
// appDir = appDir.section('/', 0, -2); // 获取上一级目录
|
|
|
|
|
|
// QMessageBox msgBox;
|
|
|
// msgBox.setWindowTitle(tr("PVT Data Missing"));
|
|
|
// msgBox.setText(tr("Please check if PVT parameters have been calculated in the analysis."));
|
|
|
// msgBox.setIconPixmap(QPixmap(appDir + "/Res/Icon/NmPVTDataMissMessage.png")); // PVT 参数计算向导
|
|
|
// msgBox.setStandardButtons(QMessageBox::Ok);
|
|
|
// msgBox.exec();
|
|
|
|
|
|
// return false;
|
|
|
//}
|
|
|
|
|
|
iDockBaseWx* pWxDockNm1 = pSubWndF->getNmDockWx(0);
|
|
|
iDockBaseWx* pWxDockNm2 = pSubWndF->getNmDockWx(1);
|
|
|
Q_ASSERT (nullptr != pWxDockNm1);
|
|
|
Q_ASSERT (nullptr != pWxDockNm2);
|
|
|
if (pWxDockNm1->widget() != nullptr && pWxDockNm2->widget() != nullptr)
|
|
|
{
|
|
|
return true; //已经设定的话,则不再处理
|
|
|
}
|
|
|
|
|
|
// 获取当前井并检查类型是否支持
|
|
|
ZxDataWell* pWellData = zxCurWell;
|
|
|
if(pWellData == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
QString wellClass = pWellData->getWellClassEn();
|
|
|
|
|
|
// 定义支持的井类型列表
|
|
|
QStringList supportedTypes;
|
|
|
supportedTypes << "VerticalWell" << "VerticalFracturedWell" << "HorizontalMultiFracturedWell";
|
|
|
|
|
|
if (!supportedTypes.contains(wellClass)) {
|
|
|
QMessageBox::warning(nullptr, tr("Unsupported Well Type"),
|
|
|
tr("The current well type '%1' is not supported for numerical modeling.\n"
|
|
|
"Supported types: Vertical, Vertical Fractured, and Horizontal Multi-Fractured Wells.")
|
|
|
.arg(pWellData->getWellClassCn()));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 进入到这里,说明是新打开的流动段分析,所以需要动态创建数据管理中心
|
|
|
|
|
|
// 根据分析窗口创建唯一的数据管理对象
|
|
|
nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getInstanceByFitting(pSubWndF);
|
|
|
Q_ASSERT(nullptr != pDataManager);
|
|
|
if(pDataManager == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 设置当前分析窗体
|
|
|
nmDataAnalyzeManager::setCurrentFitting(pSubWndF);
|
|
|
|
|
|
// TODO:初始化坐标轴相关信息
|
|
|
nmDataAxis* pAxisData = pDataManager->getAxisData();
|
|
|
|
|
|
if(pAxisData == nullptr) {
|
|
|
pAxisData = new nmDataAxis;
|
|
|
// 将 pAxisData 存入数据中心
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->setAxisData(pAxisData);
|
|
|
}
|
|
|
|
|
|
// 读取解析解的参数
|
|
|
// 1.1 初始化油藏参数
|
|
|
pDataManager->createReservoir();
|
|
|
// 1.2 初始化PVT参数
|
|
|
pDataManager->initPvtParaFromSubFit();
|
|
|
// 1.3 初始化当前井数据
|
|
|
pDataManager->initCurWellData();
|
|
|
// 1.4 初始化边界数据
|
|
|
nmDataWellBase* pCurWell = pDataManager->getCurWellData();
|
|
|
Q_ASSERT(nullptr != pCurWell);
|
|
|
if(pCurWell == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
double dX = pCurWell->getX().getValue().toDouble();
|
|
|
double dY = pCurWell->getY().getValue().toDouble();
|
|
|
|
|
|
// 解析解相关参数
|
|
|
QMap<QString, QVariant> mapAnaParas;
|
|
|
mapAnaParas.clear();
|
|
|
pSubWndF->getBrotherDockParas(mapAnaParas, false);
|
|
|
Q_ASSERT(mapAnaParas.count() > 0);
|
|
|
|
|
|
// 解析解边界类型
|
|
|
m_Bdy_Type oBdyType = BT_None;
|
|
|
QString sKey = "Bdy";
|
|
|
|
|
|
if(mapAnaParas.contains(sKey)) {
|
|
|
int n = mapAnaParas[sKey].toInt();
|
|
|
|
|
|
if(n <= (int)BT_Rect) {
|
|
|
oBdyType = m_Bdy_Type(n);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 边界距离(是井点到四周的直线距离)
|
|
|
if(oBdyType == BT_Rect || oBdyType == BT_Circle) {
|
|
|
// 设置边界数据
|
|
|
if(oBdyType == BT_Rect) {
|
|
|
// 矩形边界
|
|
|
VecDouble vecBdyDiss;
|
|
|
vecBdyDiss.clear();
|
|
|
QStringList list;
|
|
|
list << "ne" << "se" << "we" << "ee";
|
|
|
|
|
|
for(int i = 0; i < list.count(); i++) {
|
|
|
QString s = list[i];
|
|
|
|
|
|
if(mapAnaParas.contains(s)) {
|
|
|
vecBdyDiss << mapAnaParas[s].toDouble();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
double top_dist = vecBdyDiss[0];
|
|
|
double right_dist = vecBdyDiss[1];
|
|
|
double bottom_dist = vecBdyDiss[2];
|
|
|
double left_dist = vecBdyDiss[3];
|
|
|
// 计算四个顶点的坐标
|
|
|
QPointF topLeft(dX - left_dist, dY + top_dist); // 左上角
|
|
|
QPointF topRight(dX + right_dist, dY + top_dist); // 右上角
|
|
|
QPointF bottomRight(dX + right_dist, dY - bottom_dist); // 右下角
|
|
|
QPointF bottomLeft(dX - left_dist, dY - bottom_dist); // 左下角
|
|
|
// 创建边界点集合
|
|
|
QVector<QPointF> vecBoundaryPoints;
|
|
|
vecBoundaryPoints << topLeft << topRight << bottomRight << bottomLeft;
|
|
|
// 创建矩形边界数据对象
|
|
|
nmDataOutline* pOutlineData = pDataManager->createOutline();
|
|
|
Q_ASSERT(pOutlineData);
|
|
|
if(pOutlineData == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
// 设置默认边界名称
|
|
|
pOutlineData->setName("");
|
|
|
// 设置边界点
|
|
|
pOutlineData->setOutlinePoints(vecBoundaryPoints);
|
|
|
// 设置边界类型
|
|
|
pOutlineData->setOutlineType(NM_Rect_Outline_Type);
|
|
|
// 设置流型列表(假设全部为0)
|
|
|
QVector<int> vecFlowTypes(vecBoundaryPoints.size(), 0);
|
|
|
pOutlineData->setFlowTypeList(vecFlowTypes);
|
|
|
} else {
|
|
|
// 圆形边界
|
|
|
QString s = "re";
|
|
|
double dRadius = 0.0;
|
|
|
|
|
|
if(mapAnaParas.contains(s)) {
|
|
|
dRadius = mapAnaParas[s].toDouble();
|
|
|
}
|
|
|
|
|
|
// 创建圆形边界数据对象
|
|
|
nmDataOutline* pOutlineData = pDataManager->createOutline();
|
|
|
Q_ASSERT(pOutlineData);
|
|
|
if(pOutlineData == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
// 设置默认边界名称
|
|
|
pOutlineData->setName("");
|
|
|
// 设置半径
|
|
|
pOutlineData->setRadius(dRadius);
|
|
|
// 设置圆心
|
|
|
pOutlineData->setCenter(QPointF(dX, dY));
|
|
|
// 设置边界类型
|
|
|
pOutlineData->setOutlineType(NM_Data_Outline_Type::NM_Round_Outline_Type);
|
|
|
// 设置流型列表(假设全部为0)
|
|
|
QVector<int> vecFlowTypes(1, 0);
|
|
|
pOutlineData->setFlowTypeList(vecFlowTypes);
|
|
|
// 创建存储点的向量
|
|
|
QVector<QPointF> vecPoints;
|
|
|
// 放入圆心
|
|
|
vecPoints.append(QPointF(dX, dY));
|
|
|
// 放入半径
|
|
|
vecPoints.append(QPointF(dRadius, dRadius));
|
|
|
// 计算圆上的四个关键点并放入向量(上、右、下、左)
|
|
|
vecPoints.append(QPointF(dX, dY - dRadius));
|
|
|
vecPoints.append(QPointF(dX + dRadius, dY));
|
|
|
vecPoints.append(QPointF(dX, dY + dRadius));
|
|
|
vecPoints.append(QPointF(dX - dRadius, dY));
|
|
|
// 添加到数据中
|
|
|
pOutlineData->setOutlinePoints(vecPoints);
|
|
|
}
|
|
|
} else {
|
|
|
// 如果解析解这里没有设置边界,数值解设置默认边界
|
|
|
// 创建默认矩形边界数据对象
|
|
|
nmDataOutline* pDefaultOutlineData = pDataManager->createOutline();
|
|
|
Q_ASSERT(pDefaultOutlineData);
|
|
|
if(pDefaultOutlineData == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
// 设置默认边界名称
|
|
|
pDefaultOutlineData->setName("");
|
|
|
// 设置边界点
|
|
|
QVector<QPointF> vecPoints;
|
|
|
vecPoints << QPointF(-1000.00, 1000.00)
|
|
|
<< QPointF(1000.00, 1000.00)
|
|
|
<< QPointF(1000.00, -1000.00)
|
|
|
<< QPointF(-1000.00, -1000.00);
|
|
|
pDefaultOutlineData->setOutlinePoints(vecPoints);
|
|
|
// 设置边界类型
|
|
|
pDefaultOutlineData->setOutlineType(NM_Rect_Outline_Type);
|
|
|
// 设置流型列表(假设全部为0)
|
|
|
QVector<int> vecFlowTypes(vecPoints.size(), 0);
|
|
|
pDefaultOutlineData->setFlowTypeList(vecFlowTypes);
|
|
|
}
|
|
|
|
|
|
// 1.6 创建时间步设置相关数据
|
|
|
pDataManager->createTimeStep();
|
|
|
|
|
|
// 创建敏感性分析数据
|
|
|
pDataManager->createSensitiveData();
|
|
|
|
|
|
// TODO:创建nmSubWndMain的作用主要是因为求解函数在这个类里,后续应该拆分掉
|
|
|
nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, "");
|
|
|
ZxMainWindow* pMainWnd = pSubWndF->getMainWindow();
|
|
|
// 设置当前窗口到Map
|
|
|
pSubWndMain->setMainWindow(pMainWnd);
|
|
|
|
|
|
pWxDockNm1->setWindowTitle(tr("Generate numerical model")); //改变Title
|
|
|
pWxDockNm2->setWindowTitle(tr("Parameters"));
|
|
|
|
|
|
//QTextEdit* pWx1 = new QTextEdit("This is demo for upper");
|
|
|
//QTextEdit* pWx2 = new QTextEdit("This is demo for lower");
|
|
|
nmWxNumericalDesign* pAnalWx = new nmWxNumericalDesign();
|
|
|
nmWxParameterProperty* pParaWx = new nmWxParameterProperty();
|
|
|
|
|
|
// 建立求解调用连接
|
|
|
connect(pAnalWx, SIGNAL(sigGenerateClicked()),
|
|
|
pSubWndMain, SLOT(onGenerateButtonClicked()));
|
|
|
// 切换查看井结果时刷新曲线窗口
|
|
|
connect(pAnalWx, SIGNAL(sigResultWellChanged(QString)),
|
|
|
pSubWndMain, SLOT(onWellSelected(QString)));
|
|
|
|
|
|
// 建立更新参数栏连接
|
|
|
//connect(pAnalWx, SIGNAL(sigIncludeWells()),
|
|
|
// pParaWx, SLOT(onUpdate()));
|
|
|
|
|
|
// 井图元更新连接
|
|
|
// connect(pAnalWx, SIGNAL(sigUpdateWellPlot(nmDataAnalyzeManager*)),
|
|
|
// pSubWndMain, SLOT(slotUpdateWellPlotByDataManager(nmDataAnalyzeManager*)));
|
|
|
|
|
|
// QTextEdit* pWx1 = new CustomParaWx("This is demo for upper");
|
|
|
// pWx1->...
|
|
|
Q_ASSERT(nullptr != pAnalWx);
|
|
|
Q_ASSERT(nullptr != pParaWx);
|
|
|
|
|
|
pWxDockNm1->setWidget(pAnalWx);
|
|
|
pWxDockNm2->setWidget(pParaWx);
|
|
|
|
|
|
return true; //your own codes
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::getAnaDockParas(iSubWnd* pSubWnd)
|
|
|
{
|
|
|
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
|
|
|
Q_ASSERT(nullptr != pSubWndF);
|
|
|
if(pSubWndF == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
// 如下代码,请根据需要在合适位置借鉴参照编写
|
|
|
QMap<QString, QVariant> mapAnaParas;//当前解析解的参数
|
|
|
mapAnaParas.clear();
|
|
|
pSubWndF->getBrotherDockParas(mapAnaParas, false);
|
|
|
Q_ASSERT(mapAnaParas.count() > 0);
|
|
|
|
|
|
// 解析解边界类型
|
|
|
m_Bdy_Type oBdyType = BT_None;
|
|
|
QString sKey = "Bdy";
|
|
|
if (mapAnaParas.contains(sKey))
|
|
|
{
|
|
|
int n = mapAnaParas[sKey].toInt();
|
|
|
if (n <= (int)BT_Rect)
|
|
|
{
|
|
|
oBdyType = m_Bdy_Type(n);
|
|
|
}
|
|
|
}
|
|
|
// 边界距离(是井点到四周的直线距离)
|
|
|
if (oBdyType == BT_Rect || oBdyType == BT_Circle)
|
|
|
{
|
|
|
VecDouble vecBdyDiss;
|
|
|
vecBdyDiss.clear();
|
|
|
int nCount = (oBdyType == BT_Rect ? 4 : 1);
|
|
|
for (int i = 1; i <= nCount; i++)
|
|
|
{
|
|
|
QString sRealBdyName = getBdyRealNameOf(i, mapAnaParas); //sRealBdyName为map中边界距离key的真实内容
|
|
|
sKey = sRealBdyName;
|
|
|
if (!sKey.isEmpty() && mapAnaParas.contains(sKey))
|
|
|
{
|
|
|
vecBdyDiss << mapAnaParas[sKey].toDouble();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Q_ASSERT (false);//TODO
|
|
|
}
|
|
|
}
|
|
|
// 说明,对于BT_Rect,vecBdyDiss中存放的四个距离数值,依次为,上(ne)/下(se)/左(we)/右(ee)
|
|
|
// 对于BT_Circle,vecBdyDiss中存放的是圆形半径r
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
QString nmSubWndUtils::getBdyRealNameOf(int xIndex, QMap<QString, QVariant>& map)
|
|
|
{
|
|
|
QStringList list;
|
|
|
list << "ne" << "se" << "we" << "ee" << "re";
|
|
|
|
|
|
int n = -1;
|
|
|
for (int i = 0; i < list.count(); i++)
|
|
|
{
|
|
|
QString s = list[i];
|
|
|
if (map.find(s) != map.end())
|
|
|
{
|
|
|
n++;
|
|
|
if (n == xIndex - 1)//TODO -1,从1开始
|
|
|
{
|
|
|
return s;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//m_sError = QString("Bdy name of 'x%1'' not found.").arg(xIndex);
|
|
|
//zxLogRunF(m_sError);
|
|
|
|
|
|
return "";
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::nmCalAndFresh(iSubWnd* pSubWnd, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::saveRsts(iSubWnd* pSubWnd, \
|
|
|
QString sRstName, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
Q_ASSERT(nullptr != pSubWnd);
|
|
|
if(pSubWnd == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 流动段分析窗体
|
|
|
if(pSubWnd->getWndID() == "3004") {
|
|
|
// 转换为Fitting窗口
|
|
|
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
|
|
|
if(pSubWndF == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
// 根据窗体指针,找到创建的对应的数据管理对象
|
|
|
nmDataAnalyzeManager*pDataManager = nmDataAnalyzeManager::findManagerByFitting(pSubWndF);
|
|
|
|
|
|
// 如果不存在,则说明当前分析窗体没有做数值解,不需要做保存处理
|
|
|
if(pDataManager == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 如果存在,则对当前分析数据进行保存
|
|
|
if(!pDataManager->saveNmResult(sRstName, pSubWndF)) {
|
|
|
return false;
|
|
|
}
|
|
|
} else if(pSubWnd->getWndID() == "5118") {
|
|
|
return true;
|
|
|
} else if(pSubWnd->getWndID() == "5114") {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// TODO:Map窗口保存、网格窗口保存
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool nmSubWndUtils::loadRsts(iSubWnd* pSubWnd, \
|
|
|
QString sRstName, \
|
|
|
const ZxMainWindow* pMainWnd)
|
|
|
{
|
|
|
Q_ASSERT(nullptr != pSubWnd);
|
|
|
if(pSubWnd == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance();
|
|
|
|
|
|
if(nullptr != pMainWnd1) {
|
|
|
ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx();
|
|
|
|
|
|
if(nullptr != pTabWx) {
|
|
|
if(pUtilsInstance->m_pTabWx == nullptr || pUtilsInstance->m_pTabWx != pTabWx) {
|
|
|
pUtilsInstance->m_pTabWx = pTabWx;
|
|
|
disconnect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
|
|
|
connect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 处理流动段分析窗口数据
|
|
|
if(pSubWnd->getWndID() == "3004") {
|
|
|
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
|
|
|
if(pSubWndF == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 获取当前分析窗体Code
|
|
|
ZxRstWnd* pRstWnd = pSubWndF->getRstUtilWnd();
|
|
|
if(pRstWnd == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
QString sRstUtilWndCode = pRstWnd->getCode();
|
|
|
ZxDataWell* pCurrentWell = pSubWndF->getDataWell();
|
|
|
if(pCurrentWell == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 获取该分析所在的目录
|
|
|
QString sDir = ZxBaseUtil::getWellDirOf(pCurrentWell->getName(), "Nm");
|
|
|
sDir += sRstName + "/" + sRstUtilWndCode;
|
|
|
// 判断分析目录是否存在
|
|
|
bool bDirExists = nmDataAnalyzeManager::isDirExist(sDir);
|
|
|
|
|
|
// 如果不存在,则说明没有保存数值解的参数
|
|
|
if(!bDirExists) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 存在,说明保存了数值解的参数,需要解析文件里的数据到数据中心
|
|
|
// 动态创建数据中心类
|
|
|
nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getInstanceByFitting(pSubWndF);
|
|
|
if(pDataManager == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 设置当前操作的是哪一个分析
|
|
|
nmDataAnalyzeManager::setCurrentFitting(pSubWndF);
|
|
|
|
|
|
// 加载本地文件的数据到数据中心里的数据体里
|
|
|
pDataManager->loadNmResult(sDir);
|
|
|
// 加载当前分析中的PVT数据
|
|
|
pDataManager->initPvtParaFromSubFit();
|
|
|
// 成果加载完成后刷新查看井下拉框
|
|
|
nmWxNumericalDesign::notifyResultWellSelectorChanged();
|
|
|
|
|
|
// 切换左侧参数视图
|
|
|
pSubWndF->swapAnaNmDocks(true);
|
|
|
|
|
|
iDockBaseWx* pWxDockNm1 = pSubWndF->getNmDockWx(0);
|
|
|
iDockBaseWx* pWxDockNm2 = pSubWndF->getNmDockWx(1);
|
|
|
Q_ASSERT(nullptr != pWxDockNm1);
|
|
|
Q_ASSERT(nullptr != pWxDockNm2);
|
|
|
if(pWxDockNm1 == nullptr || pWxDockNm2 == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if(pWxDockNm1->widget() != nullptr && pWxDockNm2->widget() != nullptr) {
|
|
|
return true; //已经设定的话,则不再处理
|
|
|
}
|
|
|
|
|
|
// 创建Map,暂时
|
|
|
nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, "");
|
|
|
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
|
|
|
pSubWndMain->setMainWindow(pMainWnd1);
|
|
|
|
|
|
//pWxDockNm1->setWindowTitle(tr("Dock1's Title"));
|
|
|
//pWxDockNm2->setWindowTitle(tr("Dock2's Title"));
|
|
|
pWxDockNm1->setWindowTitle(tr("Generate numerical model")); //改变Title
|
|
|
pWxDockNm2->setWindowTitle(tr("Parameters"));
|
|
|
|
|
|
// 自定义窗体指针
|
|
|
nmWxNumericalDesign* pAnalWx = new nmWxNumericalDesign();
|
|
|
nmWxParameterProperty* pParaWx = new nmWxParameterProperty();
|
|
|
Q_ASSERT(nullptr != pAnalWx);
|
|
|
Q_ASSERT(nullptr != pParaWx);
|
|
|
|
|
|
// 建立求解调用连接
|
|
|
connect(pAnalWx, SIGNAL(sigGenerateClicked()),
|
|
|
pSubWndMain, SLOT(onGenerateButtonClicked()));
|
|
|
// 切换查看井结果时刷新曲线窗口
|
|
|
connect(pAnalWx, SIGNAL(sigResultWellChanged(QString)),
|
|
|
pSubWndMain, SLOT(onWellSelected(QString)));
|
|
|
// 建立更新参数栏连接
|
|
|
connect(pAnalWx, SIGNAL(sigIncludeWells()),
|
|
|
pParaWx, SLOT(onUpdate()));
|
|
|
// 井图元更新连接
|
|
|
// connect(pAnalWx, SIGNAL(sigUpdateWellPlot(nmDataAnalyzeManager*)),
|
|
|
// pSubWndMain, SLOT(slotUpdateWellPlotByDataManager(nmDataAnalyzeManager*)));
|
|
|
//connect(pAnalWx, SIGNAL(sigIncludeWells()),
|
|
|
// pParaWx, SLOT(onUpdate()));
|
|
|
|
|
|
pWxDockNm1->setWidget(pAnalWx);
|
|
|
pWxDockNm2->setWidget(pParaWx);
|
|
|
|
|
|
// 判断是否保存了时间步数据
|
|
|
if(!pDataManager->isTimeStepDataEmpty()) {
|
|
|
QString sErrorMessage;
|
|
|
// 刷新场图
|
|
|
QWidget* p3DWidget = pSubWndF->getFitSubRstWxOf(FSRT_Nm3D, true, &sErrorMessage);
|
|
|
|
|
|
// 创建 vtkWidget
|
|
|
nmWxPostprocessingAnimationWidget* pVtkWidget = nullptr;
|
|
|
|
|
|
pVtkWidget = new nmWxPostprocessingAnimationWidget();
|
|
|
|
|
|
if(p3DWidget == nullptr || pVtkWidget == nullptr) {
|
|
|
delete pVtkWidget;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 先清理
|
|
|
// 获取当前布局
|
|
|
QLayout* p3DLayout = p3DWidget->layout();
|
|
|
|
|
|
if(p3DLayout) {
|
|
|
// 移除布局中的所有控件
|
|
|
QLayoutItem* item;
|
|
|
|
|
|
while((item = p3DLayout->takeAt(0))) {
|
|
|
if(item->widget()) {
|
|
|
// 删除控件
|
|
|
delete item->widget();
|
|
|
}
|
|
|
|
|
|
delete item; // 删除布局项
|
|
|
}
|
|
|
|
|
|
// 删除布局
|
|
|
delete p3DLayout;
|
|
|
}
|
|
|
|
|
|
// 确保布局被移除
|
|
|
p3DWidget->setLayout(nullptr);
|
|
|
|
|
|
// 创建一个垂直布局管理器
|
|
|
QVBoxLayout* p3DnewLayout = new QVBoxLayout(p3DWidget);
|
|
|
|
|
|
// 将现有的控件添加到布局中
|
|
|
p3DnewLayout->addWidget(pVtkWidget);
|
|
|
|
|
|
// 设置 widget 的布局
|
|
|
p3DWidget->setLayout(p3DnewLayout);
|
|
|
|
|
|
// 刷新结果参数
|
|
|
// 结果参数界面
|
|
|
QWidget* pRstWidget = pSubWndF->getFitSubRstWxOf(FSRT_NmRst, true, &sErrorMessage);
|
|
|
if(pRstWidget == nullptr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 创建结果参数界面
|
|
|
nmWxResultParameters* pResultWidget = new nmWxResultParameters;
|
|
|
|
|
|
// 先清理
|
|
|
// 获取当前布局
|
|
|
QLayout* pRstLayout = pRstWidget->layout();
|
|
|
|
|
|
if(pRstLayout) {
|
|
|
// 移除布局中的所有控件
|
|
|
QLayoutItem* item;
|
|
|
|
|
|
while((item = pRstLayout->takeAt(0))) {
|
|
|
if(item->widget()) {
|
|
|
// 删除控件
|
|
|
delete item->widget();
|
|
|
}
|
|
|
|
|
|
delete item; // 删除布局项
|
|
|
}
|
|
|
|
|
|
// 删除布局
|
|
|
delete pRstLayout;
|
|
|
}
|
|
|
|
|
|
// 确保布局被移除
|
|
|
pRstWidget->setLayout(nullptr);
|
|
|
|
|
|
// 创建一个垂直布局管理器
|
|
|
QVBoxLayout* pRstnewLayout = new QVBoxLayout(pRstWidget);
|
|
|
|
|
|
// 将现有的控件添加到布局中
|
|
|
pRstnewLayout->addWidget(pResultWidget);
|
|
|
|
|
|
// 设置 widget 的布局
|
|
|
pRstWidget->setLayout(pRstnewLayout);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//// 请根据需要确定,文件存储的路径
|
|
|
//QString sDir = ZxBaseUtil::getCurWellDirOf("Nm");
|
|
|
|
|
|
////iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
|
|
|
////Q_ASSERT(nullptr != pSubWndF);
|
|
|
//QString sRstUtilWndCode = pSubWnd->getRstUtilWnd()->getCode();
|
|
|
|
|
|
//QByteArray ba = QByteArray();//这是你读取出来的内容
|
|
|
//ZxUiBase* pWx = nullptr; //your own widget
|
|
|
//if (nullptr != pWx && !ba.isNull())
|
|
|
//{
|
|
|
// // 根据二进制内容更新窗体内容
|
|
|
// // 注意:loadFromByteArr是 iWxBase(PVT模块)中的接口,如果需要,请参考下面源码进行自行实现
|
|
|
// //pWx->loadFromByteArr(ba);
|
|
|
//}
|
|
|
|
|
|
// 如果需要把二进制内容更新至其它如double数组、map等存入,可以参照 ZxBaHelper 提供的接口
|
|
|
|
|
|
// 其它代码
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// 如果需要加载某个窗体(继承自ZxUiBase,并且实现了序列化接口onSerialize/onDeserialize)
|
|
|
// 则可以参照如下进行
|
|
|
|
|
|
#ifdef _SCAN_OLD_CODES_
|
|
|
|
|
|
bool iWxBase::saveAsByteArr(QByteArray& v)
|
|
|
{
|
|
|
QString sRoot = this->objectName() + "abc";
|
|
|
ZxXpfDoc xpf(sRoot);
|
|
|
ZxSerializer ser(&xpf, true);
|
|
|
onSerialize(&ser);
|
|
|
|
|
|
QDataStream out(&v, QIODevice::WriteOnly);
|
|
|
out.setVersion(QDataStream::Qt_4_8);
|
|
|
if (xpf.save(out))
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
bool iWxBase::loadFromByteArr(QByteArray& v)
|
|
|
{
|
|
|
QDataStream in(&v, QIODevice::ReadOnly);
|
|
|
// quint32 nVer = ser->getDocDate();
|
|
|
// if (nVer > (quint32)(20180101))
|
|
|
// {
|
|
|
// in.setVersion(QDataStream::Qt_4_8);
|
|
|
// }
|
|
|
// else
|
|
|
{
|
|
|
in.setVersion(QDataStream::Qt_4_8);
|
|
|
}
|
|
|
|
|
|
QString sRoot = this->objectName() + "abc";
|
|
|
ZxXpfDoc xpf(sRoot);
|
|
|
if (!xpf.load(in))
|
|
|
{
|
|
|
zxLogRunW(tr("Failed to load ByteArray"));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
ZxSerializer ser(&xpf, false);
|
|
|
onDeserialize(&ser);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
void nmSubWndUtils::slotHandleTabChange(int index)
|
|
|
{
|
|
|
// 找到索引对应的流动段分析窗体
|
|
|
if(m_pTabWx == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if(index >= 0 && index < m_pTabWx->count()) {
|
|
|
iSubWnd* pSubWnd = dynamic_cast<iSubWnd*>(m_pTabWx->widget(index));
|
|
|
|
|
|
if(pSubWnd == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 切换的是流动段分析
|
|
|
if(pSubWnd->getWndID() == "3004") {
|
|
|
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
|
|
|
if(pSubWndF == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 查找有没有对应的数据中心实例
|
|
|
nmDataAnalyzeManager* pDataManger = nmDataAnalyzeManager::findManagerByFitting(pSubWndF);
|
|
|
|
|
|
if(pDataManger != nullptr && nmDataAnalyzeManager::getCurrentFitting() != pSubWndF) {
|
|
|
// 有对应的实例,并且不是当前分析
|
|
|
nmDataAnalyzeManager::setCurrentFitting(pSubWndF);
|
|
|
|
|
|
ZxMainWindow* pMainWnd = pSubWndF->getMainWindow();
|
|
|
Q_ASSERT(nullptr != pMainWnd);
|
|
|
if(pMainWnd == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 如果地图和网格窗体存在,则更新
|
|
|
QVector<iSubWnd*> vecSubWnds = pMainWnd->getAllSubWndsOf(m_pTabWx);
|
|
|
|
|
|
foreach(iSubWnd* pSub, vecSubWnds) {
|
|
|
nmSubWndMain* pMap = dynamic_cast<nmSubWndMain*>(pSub);
|
|
|
|
|
|
if(nullptr != pMap) {
|
|
|
// 更新地图相关信息
|
|
|
pMap->updateMapByDataManager(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF));
|
|
|
}
|
|
|
|
|
|
// TODO:网格更新
|
|
|
nmSubWndGrid* pSubWndGrid = dynamic_cast<nmSubWndGrid*>(pSub);
|
|
|
|
|
|
if(nullptr != pSubWndGrid) {
|
|
|
// 更新网格
|
|
|
disconnect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()));
|
|
|
connect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection);
|
|
|
// 手动更新
|
|
|
pSubWndGrid->updateGrid();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|