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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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*)));
}