You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmWxIncludeOtherWells.cpp

249 lines
7.7 KiB
C++

#include "nmWxIncludeOtherWells.h"
#include "nmDataAnalyzeManager.h"
#include "nmDataWellBase.h"
#include <QCheckBox>
#include <QWidget>
#include <QHBoxLayout>
namespace
{
// Include 对话框只展示当前 PEBI 网格能够表达的真实井型。
bool isSupportedNumericalWell(nmDataWellBase* pWellData)
{
if(pWellData == nullptr || pWellData->getWellCode().isEmpty()) {
return false;
}
const NM_WELL_MODEL eWellType = pWellData->getWellType();
return eWellType == NM_WELL_MODEL::Vertical_Well ||
eWellType == NM_WELL_MODEL::Vertical_Fractured_Well ||
eWellType == NM_WELL_MODEL::Horizontal_Fractured_Well;
}
}
nmWxIncludeOtherWells::nmWxIncludeOtherWells(
nmDataAnalyzeManager* pDataManager,
QWidget* pParent)
: iDlgBase(pParent), m_pDataManager(pDataManager), m_pTableWidget(nullptr),
m_pOkButton(nullptr), m_pCancelButton(nullptr),
m_pButtonLayout(nullptr), m_pMainLayout(nullptr)
{
this->initUI();
}
nmWxIncludeOtherWells::~nmWxIncludeOtherWells()
{
// Qt的对象父子关系会自动处理内存释放
}
void nmWxIncludeOtherWells::initUI()
{
this->setupTable();
this->setupButtons();
this->setupLayouts();
this->setupConnections();
this->setWindowTitle(tr("Include Other Wells"));
this->resize(772, 339);
}
void nmWxIncludeOtherWells::setupTable()
{
m_pTableWidget = new QTableWidget(this);
QVector<nmDataWellBase*> vecMapWells;
if(m_pDataManager != nullptr) {
vecMapWells = m_pDataManager->getWellDataList();
}
// 设置行列数
m_pTableWidget->setColumnCount(6);
m_pTableWidget->setRowCount(vecMapWells.size());
m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_pTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
m_pTableWidget->setStyleSheet(
"QTableWidget::item:focus {"
" background: transparent;"
" color: black;"
"}"
);
// 设置水平表头(列标题)
QStringList headers;
headers << tr("Name") << tr("Included") << tr("Oil production")
<< tr("Gas production") << tr("Water production") << tr("Pressure");
m_pTableWidget->setHorizontalHeaderLabels(headers);
// 确保水平表头可见
m_pTableWidget->horizontalHeader()->setVisible(true);
// 设置垂直表头(行标题)属性
m_pTableWidget->verticalHeader()->setVisible(true); // 保持垂直表头可见(用于行选择视觉反馈)
m_pTableWidget->verticalHeader()->setMinimumWidth(16); // 最小宽度
// 隐藏垂直表头的数字(设置为空文本)
QStringList emptyRowHeaders;
for(int i = 0; i < m_pTableWidget->rowCount(); ++i) {
emptyRowHeaders << "";
}
m_pTableWidget->setVerticalHeaderLabels(emptyRowHeaders);
// 加载数据
QString sPrimaryWellCode = m_pDataManager != nullptr
? m_pDataManager->getPrimaryWellCode() : QString();
int displayRow = 0;
// 第一步:候选来源是 Map而不是整个项目井库。该对话框只管理
// 其他有产量的生产/注入井;主井和无产量观察井都不在这里显示。
for(int i = 0; i < vecMapWells.size(); i++) {
nmDataWellBase* pWell = vecMapWells[i];
if(pWell == nullptr || !isSupportedNumericalWell(pWell)) {
continue;
}
const bool bIsPrimary = pWell->getWellCode() == sPrimaryWellCode;
const bool bHasValidRate = pWell->getFlowPoints().size() >= 2;
const bool bHasValidPressure = pWell->getPressurePoints().size() >= 2;
if(bIsPrimary || !bHasValidRate) {
continue;
}
WellDataRow wellRow;
wellRow.m_sWellCode = pWell->getWellCode();
wellRow.m_sName = pWell->getWellName();
wellRow.m_bIsPrimary = bIsPrimary;
// 第二步:读取这口有产量干扰井上次确认的包含状态。
wellRow.m_bCanCalculate = true;
wellRow.m_bIsIncluded =
m_pDataManager != nullptr &&
m_pDataManager->getNumericalAnalysisCase()->isIncludedWell(
wellRow.m_sWellCode);
// 第三步IncludedWells 中的候选固定是有产量主动井。
wellRow.m_sPressure = bHasValidPressure ? "History" : "None";
wellRow.m_sOilProd = "Rate";
wellRow.m_eMode = NM_CaseWell_RateControlled;
// 气相和水相暂时设为None
wellRow.m_sGasProd = "None";
wellRow.m_sWaterProd = "None";
// 添加到数据列表和表格
m_wellData.append(wellRow);
addWellDataToTable(wellRow, displayRow);
displayRow++;
}
m_pTableWidget->setRowCount(displayRow); // 调整实际显示的行数
m_pTableWidget->horizontalHeader()->setStretchLastSection(true);
m_pTableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
}
void nmWxIncludeOtherWells::addWellDataToTable(const WellDataRow& data, int row)
{
// Name列 - 不可编辑
QTableWidgetItem* nameItem = new QTableWidgetItem(data.m_sName);
nameItem->setFlags(nameItem->flags() & ~Qt::ItemIsEditable);
nameItem->setData(Qt::UserRole, data.m_sWellCode); // 表格内部始终携带 WellCode
m_pTableWidget->setItem(row, 0, nameItem);
// Included列 - 使用自定义复选框组件
QWidget* pWidget = new QWidget();
QCheckBox* pCheckBox = new QCheckBox();
QHBoxLayout* pLayout = new QHBoxLayout(pWidget);
pLayout->addWidget(pCheckBox);
pLayout->setAlignment(Qt::AlignCenter);
pLayout->setContentsMargins(0, 0, 0, 0);
pWidget->setLayout(pLayout);
pCheckBox->setChecked(data.m_bIsIncluded);
// 表内只有其他有产量井,用户可以决定它是否作为干扰井参与计算。
pCheckBox->setEnabled(data.canCalculate());
pCheckBox->setProperty("row", row); // 存储行索引
// 连接复选框信号
connect(pCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onCheckBoxStateChanged(int)));
// 设置单元格控件
m_pTableWidget->setCellWidget(row, 1, pWidget);
// 其他列只显示各类 simulation target与 Saphir 对话框保持一致。
QStringList listOtherData;
listOtherData.append(data.m_sOilProd);
listOtherData.append(data.m_sGasProd);
listOtherData.append(data.m_sWaterProd);
listOtherData.append(data.m_sPressure);
for(int col = 2; col < 6; col++) {
QTableWidgetItem* item = new QTableWidgetItem(listOtherData[col-2]);
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
item->setData(Qt::UserRole, row);
m_pTableWidget->setItem(row, col, item);
}
}
void nmWxIncludeOtherWells::onCheckBoxStateChanged(int state)
{
QCheckBox* pCheckBox = qobject_cast<QCheckBox*>(sender());
if(pCheckBox == nullptr) {
return;
}
const int nRow = pCheckBox->property("row").toInt();
if(nRow < 0 || nRow >= m_wellData.size()) {
return;
}
// 主井正常不会进入本表;保留该判断作为防御,避免未来改动误取消主井。
if(m_wellData[nRow].m_bIsPrimary) {
m_wellData[nRow].m_bIsIncluded = true;
return;
}
// 其他候选井只记录选择状态,绝不在该对话框内创建或删除 Map 井。
m_wellData[nRow].m_bIsIncluded = (state == Qt::Checked);
m_pTableWidget->selectRow(nRow);
}
void nmWxIncludeOtherWells::onItemClicked(QTableWidgetItem* item)
{
}
QVector<WellDataRow> nmWxIncludeOtherWells::getWellData() const
{
return m_wellData;
}
void nmWxIncludeOtherWells::setupButtons()
{
// 创建确定和取消按钮
m_pOkButton = new QPushButton(tr("OK"), this);
m_pCancelButton = new QPushButton(tr("Cancel"), this);
}
void nmWxIncludeOtherWells::setupLayouts()
{
// 创建按钮布局并添加按钮
m_pButtonLayout = new QHBoxLayout();
m_pButtonLayout->addStretch(); // 添加伸缩项使按钮靠右
m_pButtonLayout->addWidget(m_pOkButton);
m_pButtonLayout->addWidget(m_pCancelButton);
// 创建主布局并添加控件
m_pMainLayout = new QVBoxLayout(this);
m_pMainLayout->addWidget(m_pTableWidget);
m_pMainLayout->addLayout(m_pButtonLayout);
setLayout(m_pMainLayout);
}
void nmWxIncludeOtherWells::setupConnections()
{
connect(m_pOkButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
connect(m_pTableWidget, SIGNAL(itemClicked(QTableWidgetItem*)),
this, SLOT(onItemClicked(QTableWidgetItem*)));
}