#pragma once #include "iSubWndBaseFit.h" #include "nmSubWnd_global.h" #include "nmCalculationDefine.h" #include #include class ZxObjBase; class ZxObjCurve; class ZxDataObject; class nmGuiPlot; class ZxTableView; class iDockBaseWx; class nmWxParaProperty; class nmDataDemo; class QToolBar; class nmDataWellBase; class nmDataAnalyzeManager; class nmCalculationDllPebiSolverTask; class iSubWndFitting; class QWidget; class QObject; class NM_SUB_WND_EXPORT nmSubWndMain : public iSubWndBaseFit { Q_OBJECT public: explicit nmSubWndMain(QWidget *parent = 0, QString sExt = ""); ~nmSubWndMain(); // 配置窗体 virtual void configWnd(QString sPrevInfo); // 初始化UI virtual void initUI(); virtual QWidget* initUiMainWx(); virtual void initUiDockWxs(); virtual void initUiDockPtys(); // 成果保存加载 virtual bool loadRsts(); virtual bool saveRsts(); #ifdef QT_DEBUG // 示例:演示增加Dock并且追加至程序主窗口 void initUiTop(); #endif // 窗体初始后允许数据加载及刷新 virtual void firstLoadAndUpdate(); // 窗体创建完毕之后的尾处理 virtual void finalDeals(); // 当前窗体激活时被调用 virtual void onActivated(); #ifdef QT_DEBUG // 更新左右Dock数据 void updateDockWxs(); // 更新图形 void updatePlots(); /// @brief 从当前井获取压力数据 /// @param sType 具体类型,比如压力、流量、温度等 /// @param sCode 指定Code,如果不指定,则返回满足条件的第一条 ZxDataObject* getDataObjOf(QString sType, QString sCode = ""); // 把曲线数据刷新至表格 void updateTableByCurve(ZxObjCurve* pObjCurve, ZxTableView* pTableView); #endif // 序列化 virtual void onSerialize(ZxSerializer* ser); virtual void onDeserialize(ZxSerializer* ser); virtual void onDeserialized(); // 成果保存加载,TODO,参考nmSubWndDemo // virtual bool loadRss(); // virtual bool saveRss(); // 窗体关闭之前的确认 virtual bool onConfirmClosing(); protected: // 绑定图形信号 virtual void bindChartSignals(iGuiPlot* pWxPlot); // 重新调整工具栏 virtual void reAdjustToolbar(QToolBar*); public: // 执行命令:通常来自图形右侧/左侧的工具栏 virtual bool runActionOf(QString sAction); // 执行命令:通常来自Ribbon virtual bool runCmdBy(QString sName, QString sID); /// @brief 命令是否Enabled的状态判断,通常来自Ribbon /// @param b (out),true:Enabled false:disabled /// @param sName (in),Cmd Name /// @param nID (in),Cmd ID /// @param bLicensed (in),当前是否有授权 /// @return 本窗体是否已经进行状态判断(即属于本窗体可执行的命令) virtual bool checkCmdEnable(bool &b, \ QString sName, int nID, \ bool bLicensed); // 返回当前绘图对象,供外界获取绘图数据 nmGuiPlot* getWxPlot() const; // 根据分析数据绘制对应的地图信息 void updateMapByDataManager(nmDataAnalyzeManager* pDataManager); signals: void sigFreshRnStates(QStringList list); void sigShowProgressAbout(bool); public slots: // Obj选择状态改变 void slotObjSelChanged(ZxObjBase*, bool); // Obj数据发生了改变 void slotObjPtsChanged(ZxObjBase*); // 当前窗体所有信息的保存,比如关闭时提问的保存 virtual bool slotSaveAll(); // 求解完成 bool on_calculationFinished(NM_Calculation_Result, const QString& sFailureReason); // DLL线程只返回成功/失败,这里转换回原来的计算结果处理流程。 void on_solverTaskFinished(bool isSuccessed); /** @brief 完成回调退出后隐藏求解进度框。 */ void dismissPendingSolverProgress(); /** @brief 进度框隐藏后的下一轮事件中完成结果界面刷新。 */ void completePendingSolverResult(); /** @brief 首次结果载体创建完成后,在下一轮事件中填充三维和参数页面。 */ void populatePendingResultWidgets(); /** @brief 首次结果页面填充调用栈退出后显示最终求解提示。 */ void showPendingSolverResultCompletion(); /** @brief 进度框显示后再创建任务,避免输入捕获发生在首次绘制之前。 */ void startSolverTask(); /** @brief 每轮事件只捕获少量井输入,保持准备阶段界面和停止按钮可响应。 */ void continueSolverInputCapture(); /** @brief 使用后台任务报告的真实阶段更新进度框。 */ void onSolverStageChanged(QString sStage, int nCurrent, int nTotal); /** @brief 请求当前手工任务协作式停止。 */ void onSolverCancelRequested(); /** @brief 当前分析的建网提交结束后,恢复待启动或待捕获的求解流程。 */ void onPebiGridGenerationFinished(quint64 nGridInputRevision, bool bSucceeded); /** @brief 按快照井 UUID 切换结果曲线,不改变实时井或参数编辑井。 */ void onWellSelected(const QString& sWellInstanceId); // 点击左侧按钮求解生成操作 void onGenerateButtonClicked(); void onDialogCmdDestroyed(QObject*); private: // 更新添加的井(从之前创建的井中选择) void updateSelectedWells(QList); // 地质图导入 void geologicalMapImport(); // 比例尺 void drawMeasuringScale(); // 地质图隐藏 void geologicalMapHide(); // 隐藏公共的Dock视图 void setTopDocksVisible(bool visible); // 画多边形边界 void drawPolygonOutline(); // 画正方形边界 void drawSquareOutline(); // 画圆形边界 void drawRoundOutline(); // 画断层 void drawFault(); // 选择井 void selectWell(); // 新建井菜单暂时停用。 // void drawWell(); // 画裂缝 void drawCrack(); // 画区域 void drawRegion(); // 区域标识 void drawRegionMark(); // 储层特性 void reservoirCharacteristics(); // 几何分层 void geoLayering(); // 网格生成 void generationMesh(); // 求解和分析 void solveAndAnalyze(); // 删除图元 void deleteOneObj(); // 锁定 void setLocked(); // 生成DFN void generateDFN(); // Show void displaySetting(); // 测量 void drawMeasure(); // Geo模型 void drawGeoRef(); // 模型位置 void drawPointerPos(); // 显示测量对话框 QWidget* showMeasureDialog(); // 显示模型位置对话框 QWidget* showPointerPosDialog(); // 显示属性插值对话框 QWidget* showPropertyInterpolationDialog(); void bindDialogCmdDestroyed(QWidget* dialog, int nId); void bindMeasureDialog(QWidget* measureDlg); bool isDialogCmdOpened(int nId) const; void markDialogCmdOpened(int nId); void markDialogCmdClosed(int nId); // 从菜单点击绘制,除非ToolBar上的点击 void triggerToolBarAction(int index); // 合并数据到流量端分析窗口 bool mergeAnaResultToFitting(); // 填充已经存在的数值三维和结果参数页面。 bool populateResultWidgets(iSubWndFitting* pSubWndFit, nmDataAnalyzeManager* pDataManager); /** @brief 用快照中冻结的历史和计算曲线刷新三个结果窗口。 */ bool refreshPebiResultCurves( iSubWndFitting* pSubWndFit, nmDataAnalyzeManager* pDataManager, const QString& sWellInstanceId); // 将首次结果载体的页面填充排队到当前创建事件结束之后。 void schedulePendingResultWidgets(); // 根据结果页面是否准备成功显示本次求解的最终提示。 void showSolverResultCompletion(bool bResultWindowReady, int nPebiCount, int nSolveTimeMs); // 先隐藏求解进度框,再排队处理结果界面。 void scheduleSolverResultCompletion(bool bSucceeded, int nPebiCount, int nSolveTimeMs, bool bInputChanged, const QString& sFailureReason); // 半对数曲线数据 bool inithalfLog(QVector> & vvecLogPreData, QVector& vecDescs,bool isPreLoadData); // 双对数曲线数据 bool initloglog(QVector> & vvecLogPreData, QVector& vecDescs,bool isHistoryData); // 压力历史曲线数据 bool initPreHistory(QVector> & vvecHistoryData, QVector& vecDescs,bool isHistoryData); // 根据原始压力数据、计算出半对数、双对数数据 //void calculationLogData(nmDataWellBase* pWellData,QVector>& vvecHistoryData,QVector>& vvecLogPreData,QVector>& vvecSemiLogPreData); private: /** @brief 建网尚未提交时更新进度并订阅完成信号,不阻塞主线程。 */ bool waitForPebiGridGeneration(); /** @brief 取消当前求解上下文对建网完成信号的订阅。 */ void disconnectPebiGridGenerationWait(); // 绘图相关 nmGuiPlot* m_pWxPlot; // 锁定状态 bool m_lockState; QVector m_openDialogCmdIds; // 已打开对话框对应的命令ID iDockBaseWx* m_pWxDockParas; //模型参数 nmWxParaProperty* m_pWxParas; iDockBaseWx* m_pWxDockData1; //表格数据样例1 ZxTableView* m_pTableView1; iDockBaseWx* m_pWxDockData2; //表格数据样例2 ZxTableView* m_pTableView2; private: // 求解进度条 QProgressDialog* m_pProgressDlg; nmCalculationDllPebiSolverTask* m_pSolverTask; ///< 当前窗口持有的 DLL 求解线程任务。 /** @brief 启动求解时捕获的所属数据管理器,防止完成时活动窗口已经切换。 */ QPointer m_pSolverDataManager; /** @brief 启动求解时捕获的拟合窗口,只把结果合并回该窗口。 */ QPointer m_pSolverFitting; /** @brief 首次结果载体创建后,延迟页面填充所需的数据管理器。 */ QPointer m_pPendingResultDataManager; /** @brief 首次结果载体创建后,延迟页面填充所需的拟合窗口。 */ QPointer m_pPendingResultFitting; bool m_bPendingResultWidgetRefresh; ///< 正在等待下一轮事件填充首次结果页面。 bool m_bPendingResultCompletionMessage; ///< 首次页面填充后再显示求解结果提示。 bool m_bPendingResultWindowReady; ///< 延迟填充是否成功创建全部结果页面。 int m_nPendingResultPebiCount; ///< 延迟提示所需的网格数量。 int m_nPendingResultSolveTimeMs; ///< 延迟提示所需的求解耗时。 bool m_bSolverResultCompletionPending; ///< 等待进度框隐藏后处理求解结果。 bool m_bPendingSolverSucceeded; ///< 待处理求解结果是否成功。 bool m_bPendingSolverInputChanged; ///< 输入变化导致本次旧结果被丢弃。 QString m_sPendingSolverFailureReason; ///< 当前代码已识别的待显示失败原因。 int m_nPendingSolverPebiCount; ///< 待显示的网格数量。 int m_nPendingSolverTimeMs; ///< 待显示的求解耗时。 bool m_bSolverStartPending; ///< 进度框已显示,输入正分批捕获或任务等待启动。 bool m_bSolverCancelRequested; ///< 已向当前任务发送停止请求,忽略后续阶段信号。 #ifdef QT_DEBUG // 示例:演示增加Dock并且追加至程序主窗口 iDockBaseWx* m_pWxDockTemp; QListWidget* m_pListWxTemp; #endif // QDSZ QToolBar* m_pPlotToolBar; };