#ifndef NMWXINCLUDEOTHERWELLS_H #define NMWXINCLUDEOTHERWELLS_H #include "nmSubWxs_global.h" #include "iDlgBase.h" #include "nmDataNumericalAnalysisCase.h" #include "nmDataGaugeRecord.h" #include #include #include #include #include #include #include class nmDataAnalyzeManager; /** * @brief Include Other Wells 表格的一行候选井数据。 * @note 该结构只描述 Map 中其他有产量数值井,无产量观察井不会进入本表。 */ struct WellDataRow { QString m_sWellCode; ///< 项目唯一井编码,只用于关联,不直接显示。 QString m_sName; ///< 井显示名称,允许重名或后续修改。 bool m_bIsIncluded; ///< 是否被用户勾选为其他主动井。 bool m_bIsPrimary; ///< 主井防御标记;主井正常情况下不会进入本表。 bool m_bCanCalculate; ///< 当前井型和几何参数是否可进入 PEBI 模型。 NM_WELL_CATEGORY m_eWellCategory; ///< 工程井井别,用于单相记录归相及求解模型匹配。 NM_CASE_WELL_MODE m_eMode; ///< 本列表固定保存有产量主动井角色。 QString m_sPressureGaugeCode; ///< 本次选择的压力记录,为空表示“无”。 QString m_sFlowGaugeCode; ///< 三个产量列共同使用的流量记录。 bool m_bUseOilRate; ///< 是否使用公共流量记录中的油相产量。 bool m_bUseGasRate; ///< 是否使用公共流量记录中的气相产量。 bool m_bUseWaterRate; ///< 是否使用公共流量记录中的水相产量。 int m_nFlowSegmentIndex; ///< 当前流量记录的一基流动段索引。 QVector m_vecPressureRecords; ///< 供压力列建立下拉项。 QVector m_vecFlowRecords; ///< 供三个产量列建立下拉项。 /** @brief 初始化未勾选、不可计算的主动井候选行。 */ WellDataRow() : m_bIsIncluded(false), m_bIsPrimary(false), m_bCanCalculate(false), m_eWellCategory(NM_WellCategory_Unknown), m_eMode(NM_CaseWell_RateControlled), m_bUseOilRate(false), m_bUseGasRate(false), m_bUseWaterRate(false), m_nFlowSegmentIndex(0) { } /** @brief 至少选择一个产量相时,该井才可作为主动井提交。 */ bool canCalculate() const { return m_bCanCalculate && !m_sWellCode.isEmpty() && !m_sFlowGaugeCode.isEmpty() && (m_bUseOilRate || m_bUseGasRate || m_bUseWaterRate) && m_nFlowSegmentIndex > 0; } }; class NM_SUB_WXS_EXPORT nmWxIncludeOtherWells : public iDlgBase { Q_OBJECT public: /** @brief 创建绑定到指定分析窗口的其他有产量井选择对话框。 */ explicit nmWxIncludeOtherWells(nmDataAnalyzeManager* pDataManager, QWidget* pParent = nullptr); ~nmWxIncludeOtherWells(); /** @brief 返回表格中各候选井及最终勾选状态。 */ QVector getWellData() const; private: /** @brief 按固定顺序初始化表格、按钮、布局和信号槽。 */ void initUI(); /** @brief 从所属数据管理器收集候选主动井并建立表格。 */ void setupTable(); /** @brief 创建确定和取消按钮。 */ void setupButtons(); /** @brief 组装表格与底部按钮布局。 */ void setupLayouts(); /** @brief 连接按钮及表格交互信号。 */ void setupConnections(); /** @brief 将一条候选井数据写入指定表格行。 */ void addWellDataToTable(const WellDataRow& data, int row); /** @brief 根据一行的公共流量记录重新建立三个分相下拉框和流动段。 */ void refreshRowEditors(int row); /** @brief 校正一行的分相状态及一基流动段索引。 */ void normalizeFlowSelection(WellDataRow& data) const; /** @brief 更新包含复选框;没有有效分相选择时自动取消包含。 */ void updateIncludeCheckBox(int row); /** @brief 填充一列分相流量记录选项。 */ void populateRateCombo(QComboBox* pComboBox, const WellDataRow& data, NM_PHASE_TYPE ePhase) const; /** @brief 填充压力记录选项。 */ void populatePressureCombo(QComboBox* pComboBox, const WellDataRow& data) const; /** @brief 填充当前公共流量记录对应的流动段选项。 */ void populateFlowSegmentCombo(QComboBox* pComboBox, const WellDataRow& data) const; private slots: /** @brief 把复选框状态同步回对应的 WellDataRow。 */ void onCheckBoxStateChanged(int state); /** @brief 切换某一相使用的流量记录;其他已选相同步到同一记录。 */ void onRateSourceChanged(int nIndex); /** @brief 切换该井使用的压力记录。 */ void onPressureSourceChanged(int nIndex); /** @brief 切换该井的一基流动段索引。 */ void onFlowSegmentChanged(int nIndex); private: /** @brief 当前对话框所属的数据管理器,不拥有对象。 */ nmDataAnalyzeManager* m_pDataManager; QTableWidget* m_pTableWidget; ///< 其他有产量井及其数据摘要表格。 QPushButton* m_pOkButton; ///< 提交当前勾选状态的确定按钮。 QPushButton* m_pCancelButton; ///< 放弃本次编辑的取消按钮。 QHBoxLayout* m_pButtonLayout; ///< 底部操作按钮布局。 QVBoxLayout* m_pMainLayout; ///< 对话框主布局。 QVector m_vecWellData; ///< 与表格行一一对应的候选井数据。 enum TableColumn { ColumnName = 0, ColumnWellCategory, ColumnIncluded, ColumnOilRate, ColumnGasRate, ColumnWaterRate, ColumnPressure, ColumnFlowSegment, ColumnCount }; }; #endif // NMWXINCLUDEOTHERWELLS_H