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