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/nmWxGeometryLayerDlg.cpp

546 lines
19 KiB
C++

#include "nmWxGeometryLayerDlg.h"
#include <QVBoxLayout>
#include <QFormLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QComboBox>
#include <QCheckBox>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QPushButton>
#include <QHeaderView>
#include "nmGUIComponentBase.h"
#include "nmDataReservoir.h"
#include "nmDataAnalyzeManager.h"
Q_DECLARE_METATYPE(double *)
nmWxGeometryLayerDlg::nmWxGeometryLayerDlg(){
m_pReservoir = nmDataAnalyzeManager::getCurrentInstance()->getReservoirData();
this->initUI();
this->initLayers(); // 确保在UI初始化后立即初始化层数据
this->updateLayers(); // 更新UI以显示初始数据
this->setWindowTitle(tr("Layer Setting"));
this->resize(500,300);
}
void nmWxGeometryLayerDlg::initUI() {
mainLayout = new QVBoxLayout;
this->setLayout(mainLayout);
QGridLayout* gridLayout = new QGridLayout();
mainLayout->addLayout(gridLayout);
int comboBoxWidth = 200;
QLabel* layersLabel = new QLabel(tr("Number of layers:"));
layersLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
layersComboBox = new QComboBox();
QStringList layerItems;
for (int i = 1; i <= 99; ++i) {
layerItems << QString::number(i);
}
layersComboBox->addItems(layerItems);
layersComboBox->setFixedWidth(comboBoxWidth);
gridLayout->addWidget(layersLabel, 0, 0, Qt::AlignRight);
gridLayout->addWidget(layersComboBox, 0, 1);
QLabel* geoLabel = new QLabel(tr("Geometry input:"));
geoLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
geometryComboBox = new QComboBox();
geometryComboBox->addItems(QStringList()
<< tr("1-top + n-thickness")
<< tr("n-thickness + 1-bottom")
<< tr("1-top + n-bottom")
<< tr("n-top + 1-bottom"));
geometryComboBox->setFixedWidth(comboBoxWidth);
gridLayout->addWidget(geoLabel, 1, 0, Qt::AlignRight);
gridLayout->addWidget(geometryComboBox, 1, 1);
QLabel* unitLabel = new QLabel(tr("Unit:"));
unitLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
unitComboBox = new QComboBox();
unitComboBox->addItems(QStringList() << tr("m") << tr("cm") << tr("mm") << tr("in") << tr("0.1 in") << tr("ft") << tr("mile") << tr("km"));
unitComboBox->setFixedWidth(comboBoxWidth);
gridLayout->addWidget(unitLabel, 1, 2, Qt::AlignRight);
gridLayout->addWidget(unitComboBox, 1, 3);
gridLayout->setHorizontalSpacing(10);
gridLayout->setVerticalSpacing(5);
gridLayout->setContentsMargins(10, 10, 10, 10);
treeWidget = new QTreeWidget(this);
treeWidget->setColumnCount(3);
QStringList headers;
headers << tr("Name") << tr("Gaps") << "";
treeWidget->setHeaderLabels(headers);
treeWidget->header()->setResizeMode(QHeaderView::Stretch);
treeWidget->setStyleSheet("QTreeWidget::item { height: 20px; }");
mainLayout->addWidget(treeWidget);
QHBoxLayout* hLayout = new QHBoxLayout;
QPushButton* resetBT = new QPushButton(tr("Reset from analytical"));
QPushButton* saveBT = new QPushButton(tr("Save"));
QPushButton* cancelBT = new QPushButton(tr("Cancel"));
connect(resetBT, SIGNAL(clicked()), this, SLOT(onResetButtonClicked()));
connect(saveBT, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelBT, SIGNAL(clicked()), this, SLOT(reject()));
hLayout->addWidget(resetBT);
hLayout->addStretch();
hLayout->addWidget(saveBT);
hLayout->addWidget(cancelBT);
mainLayout->addLayout(hLayout);
connect(layersComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onLayersComboBoxChanged(int)));
connect(geometryComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onGeometryComboBoxChanged(int)));
connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(onItemChanged(QTreeWidgetItem*, int)));
updateLayers();
}
QColor nmWxGeometryLayerDlg::getLayerColor(int index) {
if (index == 0) {
return QColor(0, 255, 0);
}
int red = (index * 50) % 256;
int green = 255 - (index * 30) % 256;
int blue = (index * 70) % 256;
return QColor(red, green, blue);
}
QTreeWidgetItem* nmWxGeometryLayerDlg::createLayer(int index, const QString& layerName) {
QTreeWidgetItem* layer = new QTreeWidgetItem(treeWidget);
layer->setText(0, layerName);
layer->setBackground(0, QBrush(getLayerColor(index)));
int numLayers = layersComboBox->currentIndex() + 1;
if (numLayers == 1 || index < numLayers - 1) {
QCheckBox* layerCheckBox = new QCheckBox(treeWidget);
layerCheckBox->setCheckState(Qt::Unchecked); // 确保初始状态为未勾选
QWidget* checkBoxWidget = new QWidget(treeWidget);
QHBoxLayout* checkBoxLayout = new QHBoxLayout(checkBoxWidget);
checkBoxLayout->addWidget(layerCheckBox);
checkBoxLayout->setAlignment(Qt::AlignCenter);
checkBoxLayout->setContentsMargins(0, 0, 0, 0);
treeWidget->setItemWidget(layer, 1, checkBoxWidget);
connect(layerCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onLayerCheckBoxStateChanged(int)));
}
configureLayerItems(index, layer);
return layer; // 返回创建的QTreeWidgetItem
}
void nmWxGeometryLayerDlg::configureLayerItems(int layerIndex, QTreeWidgetItem* layerItem) {
if (layerIndex < 0 || layerIndex >= m_layerData.size()) {
return;
}
nmDataLayer* layer = m_layerData[layerIndex];
int geometryIndex = geometryComboBox->currentIndex();
if (geometryIndex == 0) { // "1-top + n-thickness"
if (layerIndex == 0) {
QTreeWidgetItem* top = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(top, 0, new QLabel(tr("Top"), this));
treeWidget->setItemWidget(top, 1, createComboBox(tr("Constant")));
top->setText(2, QString::number(layer->getTop(), 'f', 2));
top->setFlags(top->flags() | Qt::ItemIsEditable);
}
QTreeWidgetItem* thickness = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(thickness, 0, new QLabel(tr("Thickness"), this));
treeWidget->setItemWidget(thickness, 1, createComboBox(tr("Constant")));
thickness->setText(2, QString::number(layer->getThickness(), 'f', 2));
thickness->setFlags(thickness->flags() | Qt::ItemIsEditable);
}
else if (geometryIndex == 1) { // "n-thickness + 1-bottom"
QTreeWidgetItem* thickness = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(thickness, 0, new QLabel(tr("Thickness"), this));
treeWidget->setItemWidget(thickness, 1, createComboBox(tr("Constant")));
thickness->setText(2, QString::number(layer->getThickness(), 'f', 2));
thickness->setFlags(thickness->flags() | Qt::ItemIsEditable);
if (layerIndex == layersComboBox->currentIndex()) {
QTreeWidgetItem* bottom = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(bottom, 0, new QLabel(tr("Bottom"), this));
treeWidget->setItemWidget(bottom, 1, createComboBox(tr("Constant")));
bottom->setText(2, QString::number(layer->getBottom(), 'f', 2));
bottom->setFlags(bottom->flags() | Qt::ItemIsEditable);
}
}
else if (geometryIndex == 2) { // "1-top + n-bottom"
if (layerIndex == 0) {
QTreeWidgetItem* top = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(top, 0, new QLabel(tr("Top"), this));
treeWidget->setItemWidget(top, 1, createComboBox(tr("Constant")));
top->setText(2, QString::number(layer->getTop(), 'f', 2));
top->setFlags(top->flags() | Qt::ItemIsEditable);
}
QTreeWidgetItem* bottom = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(bottom, 0, new QLabel(tr("Bottom"), this));
treeWidget->setItemWidget(bottom, 1, createComboBox(tr("Constant")));
bottom->setText(2, QString::number(layer->getBottom(), 'f', 2));
bottom->setFlags(bottom->flags() | Qt::ItemIsEditable);
}
else if (geometryIndex == 3) { // "n-top + 1-bottom"
QTreeWidgetItem* top = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(top, 0, new QLabel(tr("Top"), this));
treeWidget->setItemWidget(top, 1, createComboBox(tr("Constant")));
top->setText(2, QString::number(layer->getTop(), 'f', 2));
top->setFlags(top->flags() | Qt::ItemIsEditable);
if (layerIndex == layersComboBox->currentIndex()) {
QTreeWidgetItem* bottom = new QTreeWidgetItem(layerItem);
treeWidget->setItemWidget(bottom, 0, new QLabel(tr("Bottom"), this));
treeWidget->setItemWidget(bottom, 1, createComboBox(tr("Constant")));
bottom->setText(2, QString::number(layer->getBottom(), 'f', 2));
bottom->setFlags(bottom->flags() | Qt::ItemIsEditable);
}
}
}
QComboBox* nmWxGeometryLayerDlg::createComboBox(const QString& defaultText) {
QComboBox* comboBox = new QComboBox(treeWidget);
comboBox->addItems(QStringList() << tr("Constant") << tr("Data set..."));
comboBox->setCurrentIndex(comboBox->findText(defaultText));
return comboBox;
}
void nmWxGeometryLayerDlg::onLayerCheckBoxStateChanged(int state) {
QCheckBox* senderCheckBox = qobject_cast<QCheckBox*>(sender());
if (!senderCheckBox) return;
// 找到复选框所在的层索引
int currentLayerIndex = -1;
for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
QTreeWidgetItem* layerItem = treeWidget->topLevelItem(i);
QWidget* widget = treeWidget->itemWidget(layerItem, 1);
if (widget) {
QCheckBox* itemCheckBox = widget->findChild<QCheckBox*>();
if (itemCheckBox == senderCheckBox) {
currentLayerIndex = i;
break;
}
}
}
if (currentLayerIndex == -1) return;
// 更新 LayerData 的 isChecked 状态
if (currentLayerIndex < m_layerData.size() && m_layerData[currentLayerIndex] != nullptr) {
m_layerData[currentLayerIndex]->setIsChecked(state == Qt::Checked);
}
int geometryIndex = geometryComboBox->currentIndex();
if (geometryIndex == 0 || geometryIndex == 2) { // "1-top + n-thickness" 或 "1-top + n-bottom"
int nextLayerIndex = currentLayerIndex + 1;
if (nextLayerIndex < treeWidget->topLevelItemCount()) {
QTreeWidgetItem* nextLayer = treeWidget->topLevelItem(nextLayerIndex);
handleInsertTop(state, nextLayer);
}
}
else if (geometryIndex == 1 || geometryIndex == 3) { // "n-thickness + 1-bottom" 或 "n-top + 1-bottom"
QTreeWidgetItem* currentLayer = treeWidget->topLevelItem(currentLayerIndex);
handleInsertBottom(state, currentLayer);
}
}
void nmWxGeometryLayerDlg::initLayers() {
int numLayers = layersComboBox->currentIndex() + 1;
qDeleteAll(m_layerData); // 删除旧数据
m_layerData.clear();
double initialTop = 6000.0; // 初始顶层高度
double defaultThickness = m_pReservoir->getThickness().getValue().toDouble(); //获取储层厚度
for (int i = 0; i < numLayers; ++i) {
nmDataLayer* layer = new nmDataLayer();
layer->setTop((i == 0) ? initialTop : m_layerData[i - 1]->getBottom());
layer->setThickness(defaultThickness);
layer->setBottom(layer->getTop() + defaultThickness);
layer->setIsChecked(false);
layer->setColor(getLayerColor(i)); // 设置储层颜色
m_layerData.append(layer);
}
}
void nmWxGeometryLayerDlg::updateLayers() {
// 保存当前复选框状态
QVector<bool> checkedStates(m_layerData.size());
for (int i = 0; i < m_layerData.size(); ++i) {
checkedStates[i] = m_layerData[i]->getIsChecked();
}
treeWidget->clear();
for (int i = 0; i < m_layerData.size(); ++i) {
QString layerName = QString(tr("Layer #%1")).arg(i + 1);
QTreeWidgetItem* layerItem = createLayer(i, layerName);
// 恢复复选框状态
bool isChecked = checkedStates[i];
m_layerData[i]->setIsChecked(isChecked);
QWidget* widget = treeWidget->itemWidget(layerItem, 1);
if (widget) {
QCheckBox* checkBox = widget->findChild<QCheckBox*>();
if (checkBox) {
// 先清空当前复选框的状态
checkBox->setChecked(Qt::Unchecked);
// 再根据 m_layerData 的 isChecked 状态重新设置复选框的状态
checkBox->setChecked(isChecked);
}
}
}
treeWidget->expandAll();
}
void nmWxGeometryLayerDlg::updateLayerData(int index) {
if (index < 0 || index >= m_layerData.size()) {
return;
}
// 使用指针访问对象
nmDataLayer* currentLayer = m_layerData[index];
if (currentLayer == nullptr) {
return;
}
currentLayer->setThickness(currentLayer->getBottom() - currentLayer->getTop());
if (index + 1 < m_layerData.size()) {
nmDataLayer* nextLayer = m_layerData[index + 1];
if (nextLayer == nullptr) {
return;
}
nextLayer->setTop(currentLayer->getBottom());
nextLayer->setBottom(nextLayer->getTop() + nextLayer->getThickness());
}
QTreeWidgetItem* layerItem = treeWidget->topLevelItem(index);
if (layerItem) {
for (int i = 0; i < layerItem->childCount(); ++i) {
QTreeWidgetItem* child = layerItem->child(i);
if (child == nullptr) {
continue;
}
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(child, 0));
if (label) {
if (label->text() == tr("Top")) {
child->setText(2, QString::number(currentLayer->getTop(), 'f', 2));
}
else if (label->text() == tr("Bottom")) {
child->setText(2, QString::number(currentLayer->getBottom(), 'f', 2));
}
else if (label->text() == tr("Thickness")) {
child->setText(2, QString::number(currentLayer->getThickness(), 'f', 2));
}
}
}
}
if (index + 1 < m_layerData.size()) {
QTreeWidgetItem* nextLayerItem = treeWidget->topLevelItem(index + 1);
if (nextLayerItem) {
for (int i = 0; i < nextLayerItem->childCount(); ++i) {
QTreeWidgetItem* child = nextLayerItem->child(i);
if (child == nullptr || m_layerData[index + 1] == nullptr) {
continue;
}
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(child, 0));
if (label && label->text() == tr("Top")) {
child->setText(2, QString::number(m_layerData[index + 1]->getTop(), 'f', 2));
}
}
}
}
}
void nmWxGeometryLayerDlg::handleInsertTop(int state, QTreeWidgetItem* layer) {
if (!layer) return;
if (state == Qt::Checked) {
bool hasTop = false;
for (int i = 0; i < layer->childCount(); ++i) {
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(layer->child(i), 0));
if (label && label->text() == tr("Top")) {
hasTop = true;
break;
}
}
if (!hasTop) {
QTreeWidgetItem* top = new QTreeWidgetItem();
top->setFlags(top->flags() | Qt::ItemIsEditable);
layer->insertChild(0, top);
QLabel* nameLabel = new QLabel(tr("Top"));
QComboBox* typeComboBox = createComboBox(tr("Constant"));
treeWidget->setItemWidget(top, 0, nameLabel);
treeWidget->setItemWidget(top, 1, typeComboBox);
int layerIndex = treeWidget->indexOfTopLevelItem(layer);
if (layerIndex >= 0 && layerIndex < m_layerData.size()) {
top->setText(2, QString::number(m_layerData[layerIndex]->getTop(), 'f', 2));
}
}
}
else {
for (int i = 0; i < layer->childCount(); ++i) {
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(layer->child(i), 0));
if (label && label->text() == tr("Top")) {
delete layer->takeChild(i);
break;
}
}
}
}
void nmWxGeometryLayerDlg::handleInsertBottom(int state, QTreeWidgetItem* layer) {
if (!layer) return;
if (state == Qt::Checked) {
bool hasBottom = false;
for (int i = 0; i < layer->childCount(); ++i) {
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(layer->child(i), 0));
if (label && label->text() == tr("Bottom")) {
hasBottom = true;
break;
}
}
if (!hasBottom) {
QTreeWidgetItem* bottom = new QTreeWidgetItem(layer);
bottom->setFlags(bottom->flags() | Qt::ItemIsEditable);
QLabel* nameLabel = new QLabel(tr("Bottom"));
QComboBox* typeComboBox = createComboBox(tr("Constant"));
treeWidget->setItemWidget(bottom, 0, nameLabel);
treeWidget->setItemWidget(bottom, 1, typeComboBox);
int layerIndex = treeWidget->indexOfTopLevelItem(layer);
if (layerIndex >= 0 && layerIndex < m_layerData.size()) {
bottom->setText(2, QString::number(m_layerData[layerIndex]->getBottom(), 'f', 2));
}
}
}
else {
for (int i = 0; i < layer->childCount(); ++i) {
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(layer->child(i), 0));
if (label && label->text() == tr("Bottom")) {
delete layer->takeChild(i);
break;
}
}
}
}
void nmWxGeometryLayerDlg::onItemChanged(QTreeWidgetItem* item, int column) {
if (column != 2) return; // 只处理第三列的数据变化
QTreeWidgetItem* layerItem = item->parent();
if (!layerItem) return;
int layerIndex = treeWidget->indexOfTopLevelItem(layerItem);
bool ok;
double value = item->text(2).toDouble(&ok);
if (!ok) return;
if (layerIndex >= 0 && layerIndex < m_layerData.size()) {
nmDataLayer* currentLayer = m_layerData[layerIndex];
QLabel* label = qobject_cast<QLabel*>(treeWidget->itemWidget(item, 0));
if (label) {
if (label->text() == tr("Top")) {
currentLayer->setTop(value);
currentLayer->setBottom(currentLayer->getTop() + currentLayer->getThickness());
}
else if (label->text() == tr("Bottom")) {
currentLayer->setBottom(value);
currentLayer->setThickness(currentLayer->getBottom() - currentLayer->getTop());
}
else if (label->text() == tr("Thickness")) {
currentLayer->setThickness(value);
currentLayer->setBottom(currentLayer->getTop() + currentLayer->getThickness());
}
updateLayerData(layerIndex);
}
// 更新后续层的 top 和 bottom
for (int i = layerIndex + 1; i < m_layerData.size(); ++i) {
nmDataLayer* prevLayer = m_layerData[i - 1];
nmDataLayer* nextLayer = m_layerData[i];
nextLayer->setTop(prevLayer->getBottom());
nextLayer->setBottom(nextLayer->getTop() + nextLayer->getThickness());
updateLayerData(i);
}
}
}
void nmWxGeometryLayerDlg::onLayersComboBoxChanged(int index) {
int newNumLayers = index + 1;
int currentNumLayers = m_layerData.size();
if (newNumLayers < currentNumLayers) {
// 删除多余的层
for (int i = currentNumLayers - 1; i >= newNumLayers; --i) {
delete m_layerData[i];
}
m_layerData.resize(newNumLayers);
}
else if (newNumLayers > currentNumLayers) {
double defaultThickness = 15.0;
for (int i = currentNumLayers; i < newNumLayers; ++i) {
nmDataLayer* newLayer = new nmDataLayer();
newLayer->setTop((i == 0) ? 6000.0 : m_layerData[i - 1]->getBottom());
newLayer->setThickness(defaultThickness);
newLayer->setBottom(newLayer->getTop() + defaultThickness);
newLayer->setIsChecked(false); // 默认未选中
newLayer->setColor(getLayerColor(i)); // 设置储层颜色
m_layerData.append(newLayer);
}
}
updateLayers();
}
void nmWxGeometryLayerDlg::onGeometryComboBoxChanged(int index) {
updateLayers();
}
void nmWxGeometryLayerDlg::onResetButtonClicked() {
// 将 geometryComboBox 设置为 "1-top + n-thickness"
geometryComboBox->setCurrentIndex(0);
// 初始化层数据
initLayers();
// 更新层显示
updateLayers();
}
QVector<nmDataLayer*> nmWxGeometryLayerDlg::getLayerData() const {
// 返回 m_layerData 的副本
return m_layerData;
}