#include "nmWxPropertyInterpolationDlg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nmGuiPlot.h" #include "nmObjPoint.h" #include "tCurvePlotView.h" #include "ZxObjText.h" #include "ZxPlot.h" namespace { // 使用独立翻译上下文,便于统一维护对话框文本. QString interpolationText(const char* sourceText) { return QCoreApplication::translate("nmWxPropertyInterpolationDlg", sourceText); } // 创建统一格式的非负数值输入框. QDoubleSpinBox* createNumberSpinBox(QWidget* parent, double value) { QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); spinBox->setRange(0.0, 1.0e12); spinBox->setDecimals(6); spinBox->setValue(value); spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); return spinBox; } // 插值测点使用独立的小方块标记,避免与井图元混淆. class PropertyInterpolationMarker : public nmObjPoint { public: PropertyInterpolationMarker(const QString& name, ZxSubAxisX* axisX, ZxSubAxisY* axisY) : nmObjPoint(name, axisX, axisY) { setDotRadius(1.0); } virtual bool drawWellPos(QPainter* painter, QPointF point) override { if(painter == NULL) { return false; } const QTransform transform = painter->combinedTransform(); qreal scaleX = qAbs(transform.m11()); qreal scaleY = qAbs(transform.m22()); if(scaleX < 0.0001) { scaleX = 1.0; } if(scaleY < 0.0001) { scaleY = 1.0; } const qreal halfPixelSize = 3.0; QRectF markerRect(point.x() - halfPixelSize / scaleX, point.y() - halfPixelSize / scaleY, halfPixelSize * 2.0 / scaleX, halfPixelSize * 2.0 / scaleY); painter->save(); QPen pen(QColor(0, 25, 100)); pen.setWidthF(1.0); pen.setCosmetic(true); painter->setPen(pen); painter->setBrush(QColor(0, 70, 200)); painter->drawRect(markerRect); painter->restore(); return true; } }; void setMarkerLabel(nmObjPoint* marker, const QString& text) { if(marker == NULL || marker->getChildren().isEmpty()) { return; } ZxObjText* label = dynamic_cast(marker->at(0)); if(label != NULL) { label->setText(text); label->setTextColor(QColor(30, 30, 30)); } } } nmWxPropertyInterpolationDlg::nmWxPropertyInterpolationDlg( nmGuiPlot* plot, nmDataAnalyzeManager* dataManager, QWidget* parent) : iDlgBase(parent), m_pPlot(plot), m_pDataManager(dataManager), m_pDataSetCombo(NULL), m_pAddDataSetButton(NULL), m_pDeleteDataSetButton(NULL), m_nCurrentDataSetIndex(-1), m_nNextPointId(0), m_bUpdatingUi(true), m_pPropertyCombo(NULL), m_pNameEdit(NULL), m_pNewValueSpin(NULL), m_pMapPickButton(NULL), m_pPointTable(NULL), m_pDeletePointButton(NULL), m_pClearPointsButton(NULL), m_pShowPointsCheck(NULL), m_pShowLabelsCheck(NULL), m_pNuggetSpin(NULL), m_pSillSpin(NULL), m_pRangeSpin(NULL), m_pModelCombo(NULL), m_pPreviewButton(NULL), m_pApplyButton(NULL) { setWindowTitle(interpolationText("Property Interpolation")); setWindowModality(Qt::NonModal); setModal(false); setMinimumSize(520, 620); resize(560, 680); initInterpolationUI(); initializeDataSets(); if(qApp != NULL) { qApp->installEventFilter(this); } } nmWxPropertyInterpolationDlg::~nmWxPropertyInterpolationDlg() { if(qApp != NULL) { qApp->removeEventFilter(this); } onMapPickToggled(false); saveCurrentDataSet(); syncDataSetsToManager(false); removeAllMarkers(); } void nmWxPropertyInterpolationDlg::initInterpolationUI() { QVBoxLayout* mainLayout = new QVBoxLayout(this); // 数据组创建、切换及删除. QHBoxLayout* dataSetSelectLayout = new QHBoxLayout; dataSetSelectLayout->addWidget(new QLabel(interpolationText("Dataset:"), this)); m_pDataSetCombo = new QComboBox(this); dataSetSelectLayout->addWidget(m_pDataSetCombo, 1); QString iconDir = QCoreApplication::applicationDirPath(); iconDir = iconDir.section('/', 0, -2) + "/Res/Icon/"; m_pAddDataSetButton = new QPushButton(this); m_pAddDataSetButton->setIcon(QIcon(iconDir + "Add.png")); m_pAddDataSetButton->setIconSize(QSize(18, 18)); m_pAddDataSetButton->setFixedSize(28, 28); m_pAddDataSetButton->setToolTip(interpolationText("Add dataset")); dataSetSelectLayout->addWidget(m_pAddDataSetButton); m_pDeleteDataSetButton = new QPushButton(this); m_pDeleteDataSetButton->setIcon(QIcon(iconDir + "NmDelete.png")); m_pDeleteDataSetButton->setIconSize(QSize(18, 18)); m_pDeleteDataSetButton->setFixedSize(28, 28); m_pDeleteDataSetButton->setToolTip(interpolationText("Delete dataset")); dataSetSelectLayout->addWidget(m_pDeleteDataSetButton); mainLayout->addLayout(dataSetSelectLayout); // 当前数据组的名称和属性. QFormLayout* dataSetLayout = new QFormLayout; m_pNameEdit = new QLineEdit(this); dataSetLayout->addRow(interpolationText("Name:"), m_pNameEdit); m_pPropertyCombo = new QComboBox(this); m_pPropertyCombo->addItem(interpolationText("Permeability k"), QString("k")); m_pPropertyCombo->addItem(interpolationText("Porosity phi"), QString("phi")); m_pPropertyCombo->addItem(interpolationText("Reservoir thickness h"), QString("h")); dataSetLayout->addRow(interpolationText("Property:"), m_pPropertyCombo); mainLayout->addLayout(dataSetLayout); // 测点数据录入区域. QGroupBox* pointGroup = new QGroupBox(interpolationText("Measurement Points"), this); QVBoxLayout* pointLayout = new QVBoxLayout(pointGroup); QHBoxLayout* newPointLayout = new QHBoxLayout; newPointLayout->addWidget(new QLabel(interpolationText("New value:"), pointGroup)); m_pNewValueSpin = createNumberSpinBox(pointGroup, 0.0); newPointLayout->addWidget(m_pNewValueSpin, 1); m_pMapPickButton = new QPushButton(interpolationText("Select on Map"), pointGroup); m_pMapPickButton->setCheckable(true); m_pMapPickButton->setEnabled(!m_pPlot.isNull() && m_pPlot->m_pPlotView != NULL && m_pPlot->m_pPlot != NULL); newPointLayout->addWidget(m_pMapPickButton); pointLayout->addLayout(newPointLayout); m_pPointTable = new QTableWidget(0, 3, pointGroup); QStringList headers; headers << interpolationText("X") << interpolationText("Y") << interpolationText("Value"); m_pPointTable->setHorizontalHeaderLabels(headers); m_pPointTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); m_pPointTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_pPointTable->setSelectionMode(QAbstractItemView::SingleSelection); m_pPointTable->setAlternatingRowColors(true); pointLayout->addWidget(m_pPointTable, 1); QHBoxLayout* pointButtonLayout = new QHBoxLayout; pointButtonLayout->addStretch(); m_pDeletePointButton = new QPushButton(interpolationText("Delete Selected"), pointGroup); m_pDeletePointButton->setEnabled(false); pointButtonLayout->addWidget(m_pDeletePointButton); m_pClearPointsButton = new QPushButton(interpolationText("Clear"), pointGroup); m_pClearPointsButton->setEnabled(false); pointButtonLayout->addWidget(m_pClearPointsButton); pointLayout->addLayout(pointButtonLayout); QHBoxLayout* displayLayout = new QHBoxLayout; m_pShowPointsCheck = new QCheckBox(interpolationText("Show measurement points"), pointGroup); m_pShowPointsCheck->setChecked(true); displayLayout->addWidget(m_pShowPointsCheck); m_pShowLabelsCheck = new QCheckBox(interpolationText("Show labels"), pointGroup); m_pShowLabelsCheck->setChecked(true); displayLayout->addWidget(m_pShowLabelsCheck); displayLayout->addStretch(); pointLayout->addLayout(displayLayout); mainLayout->addWidget(pointGroup, 1); // Kriging插值参数设置. QGroupBox* parameterGroup = new QGroupBox(interpolationText("Kriging Parameters"), this); QFormLayout* parameterLayout = new QFormLayout(parameterGroup); m_pNuggetSpin = createNumberSpinBox(parameterGroup, 0.01); parameterLayout->addRow(interpolationText("Nugget:"), m_pNuggetSpin); m_pSillSpin = createNumberSpinBox(parameterGroup, 100.0); parameterLayout->addRow(interpolationText("Sill:"), m_pSillSpin); m_pRangeSpin = createNumberSpinBox(parameterGroup, 1000.0); parameterLayout->addRow(interpolationText("Range:"), m_pRangeSpin); m_pModelCombo = new QComboBox(parameterGroup); m_pModelCombo->addItem(interpolationText("Spherical (0)"), 0); m_pModelCombo->addItem(interpolationText("Exponential (1)"), 1); m_pModelCombo->addItem(interpolationText("Gaussian (2)"), 2); parameterLayout->addRow(interpolationText("Model:"), m_pModelCombo); mainLayout->addWidget(parameterGroup); // 底部操作按钮. QHBoxLayout* buttonLayout = new QHBoxLayout; m_pPreviewButton = new QPushButton(interpolationText("Preview"), this); m_pPreviewButton->setEnabled(false); buttonLayout->addWidget(m_pPreviewButton); buttonLayout->addStretch(); m_pApplyButton = new QPushButton(interpolationText("Apply"), this); m_pApplyButton->setEnabled(false); buttonLayout->addWidget(m_pApplyButton); QPushButton* closeButton = new QPushButton(interpolationText("Close"), this); buttonLayout->addWidget(closeButton); mainLayout->addLayout(buttonLayout); connect(m_pDataSetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onDataSetChanged(int))); connect(m_pAddDataSetButton, SIGNAL(clicked()), this, SLOT(onAddDataSet())); connect(m_pDeleteDataSetButton, SIGNAL(clicked()), this, SLOT(onDeleteDataSet())); connect(m_pNameEdit, SIGNAL(textChanged(QString)), this, SLOT(onDataSetNameChanged(QString))); connect(m_pPropertyCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentDataSetEdited())); connect(m_pNuggetSpin, SIGNAL(valueChanged(double)), this, SLOT(onCurrentDataSetEdited())); connect(m_pSillSpin, SIGNAL(valueChanged(double)), this, SLOT(onCurrentDataSetEdited())); connect(m_pRangeSpin, SIGNAL(valueChanged(double)), this, SLOT(onCurrentDataSetEdited())); connect(m_pModelCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentDataSetEdited())); connect(m_pMapPickButton, SIGNAL(toggled(bool)), this, SLOT(onMapPickToggled(bool))); connect(m_pPointTable, SIGNAL(itemSelectionChanged()), this, SLOT(onPointSelectionChanged())); connect(m_pPointTable, SIGNAL(itemChanged(QTableWidgetItem*)), this, SLOT(onPointItemChanged(QTableWidgetItem*))); connect(m_pDeletePointButton, SIGNAL(clicked()), this, SLOT(onDeleteSelectedPoint())); connect(m_pClearPointsButton, SIGNAL(clicked()), this, SLOT(onClearPoints())); connect(m_pShowPointsCheck, SIGNAL(toggled(bool)), this, SLOT(onShowPointsToggled(bool))); connect(m_pShowLabelsCheck, SIGNAL(toggled(bool)), this, SLOT(onShowLabelsToggled(bool))); connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); } void nmWxPropertyInterpolationDlg::initializeDataSets() { m_bUpdatingUi = true; if(!m_pDataManager.isNull()) { m_vecDataSets = m_pDataManager->getPropertyInterpolationDataSets(); } bool dataChanged = false; for(int i = 0; i < m_vecDataSets.size(); ++i) { if(m_vecDataSets[i].name.isEmpty()) { m_vecDataSets[i].name = nextDataSetName(); dataChanged = true; } } m_vecMarkerNames.resize(m_vecDataSets.size()); createMarkersForAllDataSets(); bool oldBlock = m_pDataSetCombo->blockSignals(true); m_pDataSetCombo->clear(); for(int i = 0; i < m_vecDataSets.size(); ++i) { m_pDataSetCombo->addItem(m_vecDataSets[i].name); } const int initialIndex = m_vecDataSets.isEmpty() ? -1 : 0; m_pDataSetCombo->setCurrentIndex(initialIndex); m_pDataSetCombo->blockSignals(oldBlock); m_nCurrentDataSetIndex = initialIndex; loadDataSet(initialIndex); m_bUpdatingUi = false; updateDataSetButtons(); if(dataChanged) { syncDataSetsToManager(false); } } nmPropertyInterpolationDataSet nmWxPropertyInterpolationDlg::createDefaultDataSet() { nmPropertyInterpolationDataSet dataSet; dataSet.name = nextDataSetName(); dataSet.property = "k"; dataSet.showPoints = true; dataSet.showLabels = true; dataSet.nugget = 0.01; dataSet.sill = 100.0; dataSet.range = 1000.0; dataSet.model = 0; return dataSet; } QString nmWxPropertyInterpolationDlg::nextDataSetName() { for(int number = 1; ; ++number) { const QString name = interpolationText("Dataset #%1").arg(number); bool exists = false; for(int i = 0; i < m_vecDataSets.size(); ++i) { if(m_vecDataSets[i].name == name) { exists = true; break; } } if(!exists) { return name; } } } void nmWxPropertyInterpolationDlg::loadDataSet(int index) { if(index < 0 || index >= m_vecDataSets.size()) { clearCurrentDataSet(); return; } bool wasUpdating = m_bUpdatingUi; m_bUpdatingUi = true; const nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[index]; m_pNameEdit->setText(dataSet.name); int propertyIndex = m_pPropertyCombo->findData(dataSet.property); m_pPropertyCombo->setCurrentIndex(propertyIndex < 0 ? 0 : propertyIndex); m_pNuggetSpin->setValue(dataSet.nugget); m_pSillSpin->setValue(dataSet.sill); m_pRangeSpin->setValue(dataSet.range); int modelIndex = m_pModelCombo->findData(dataSet.model); m_pModelCombo->setCurrentIndex(modelIndex < 0 ? 0 : modelIndex); m_pShowPointsCheck->setChecked(dataSet.showPoints); m_pShowLabelsCheck->setChecked(dataSet.showLabels); bool oldTableBlock = m_pPointTable->blockSignals(true); m_pPointTable->setRowCount(0); const QStringList markerNames = m_vecMarkerNames.value(index); for(int i = 0; i < dataSet.points.size(); ++i) { appendPointRow(dataSet.points[i], markerNames.value(i)); } m_pPointTable->blockSignals(oldTableBlock); clearTableSelection(); updatePointButtons(); updateCurrentMarkerVisibility(); m_bUpdatingUi = wasUpdating; updateDataSetButtons(); } void nmWxPropertyInterpolationDlg::clearCurrentDataSet() { bool wasUpdating = m_bUpdatingUi; m_bUpdatingUi = true; if(m_pMapPickButton->isChecked()) { m_pMapPickButton->setChecked(false); } m_pNameEdit->clear(); m_pPropertyCombo->setCurrentIndex(-1); m_pNewValueSpin->setValue(0.0); m_pPointTable->setRowCount(0); m_pShowPointsCheck->setChecked(false); m_pShowLabelsCheck->setChecked(false); m_pNuggetSpin->setValue(0.01); m_pSillSpin->setValue(100.0); m_pRangeSpin->setValue(1000.0); m_pModelCombo->setCurrentIndex(-1); clearTableSelection(); m_bUpdatingUi = wasUpdating; updateDataSetButtons(); } void nmWxPropertyInterpolationDlg::saveCurrentDataSet() { if(m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[m_nCurrentDataSetIndex]; dataSet.name = m_pNameEdit->text(); dataSet.property = m_pPropertyCombo->itemData(m_pPropertyCombo->currentIndex()).toString(); dataSet.nugget = m_pNuggetSpin->value(); dataSet.sill = m_pSillSpin->value(); dataSet.range = m_pRangeSpin->value(); dataSet.model = m_pModelCombo->itemData(m_pModelCombo->currentIndex()).toInt(); dataSet.showPoints = m_pShowPointsCheck->isChecked(); dataSet.showLabels = m_pShowLabelsCheck->isChecked(); } void nmWxPropertyInterpolationDlg::syncDataSetsToManager(bool markModified) { if(!m_pDataManager.isNull()) { m_pDataManager->setPropertyInterpolationDataSets(m_vecDataSets); } if(markModified && !m_pPlot.isNull()) { m_pPlot->setModified(true); } } void nmWxPropertyInterpolationDlg::updateDataSetButtons() { const bool hasCurrent = m_nCurrentDataSetIndex >= 0 && m_nCurrentDataSetIndex < m_vecDataSets.size(); const bool canPickOnMap = hasCurrent && !m_pPlot.isNull() && m_pPlot->m_pPlotView != NULL && m_pPlot->m_pPlot != NULL; m_pDataSetCombo->setEnabled(hasCurrent); m_pDeleteDataSetButton->setEnabled(hasCurrent); m_pNameEdit->setEnabled(hasCurrent); m_pPropertyCombo->setEnabled(hasCurrent); m_pNewValueSpin->setEnabled(hasCurrent); m_pMapPickButton->setEnabled(canPickOnMap); m_pPointTable->setEnabled(hasCurrent); m_pShowPointsCheck->setEnabled(hasCurrent); m_pShowLabelsCheck->setEnabled(hasCurrent); m_pNuggetSpin->setEnabled(hasCurrent); m_pSillSpin->setEnabled(hasCurrent); m_pRangeSpin->setEnabled(hasCurrent); m_pModelCombo->setEnabled(hasCurrent); updatePointButtons(); } void nmWxPropertyInterpolationDlg::onDataSetChanged(int index) { if(m_bUpdatingUi || index < 0 || index >= m_vecDataSets.size() || index == m_nCurrentDataSetIndex) { return; } saveCurrentDataSet(); syncDataSetsToManager(false); m_nCurrentDataSetIndex = index; loadDataSet(index); } void nmWxPropertyInterpolationDlg::onAddDataSet() { saveCurrentDataSet(); m_vecDataSets.append(createDefaultDataSet()); m_vecMarkerNames.append(QStringList()); int newIndex = m_vecDataSets.size() - 1; bool oldBlock = m_pDataSetCombo->blockSignals(true); m_pDataSetCombo->addItem(m_vecDataSets[newIndex].name); m_pDataSetCombo->setCurrentIndex(newIndex); m_pDataSetCombo->blockSignals(oldBlock); m_nCurrentDataSetIndex = newIndex; loadDataSet(newIndex); updateDataSetButtons(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onDeleteDataSet() { if(m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } int removedIndex = m_nCurrentDataSetIndex; removeDataSetMarkers(removedIndex); m_vecDataSets.remove(removedIndex); m_vecMarkerNames.remove(removedIndex); const int newIndex = m_vecDataSets.isEmpty() ? -1 : qMin(removedIndex, m_vecDataSets.size() - 1); bool oldBlock = m_pDataSetCombo->blockSignals(true); m_pDataSetCombo->removeItem(removedIndex); m_pDataSetCombo->setCurrentIndex(newIndex); m_pDataSetCombo->blockSignals(oldBlock); m_nCurrentDataSetIndex = newIndex; loadDataSet(newIndex); updateDataSetButtons(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onDataSetNameChanged(const QString& name) { if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } m_vecDataSets[m_nCurrentDataSetIndex].name = name; m_pDataSetCombo->setItemText(m_nCurrentDataSetIndex, name); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onCurrentDataSetEdited() { if(m_bUpdatingUi) { return; } saveCurrentDataSet(); syncDataSetsToManager(true); } bool nmWxPropertyInterpolationDlg::eventFilter(QObject* watched, QEvent* event) { if(event != NULL && event->type() == QEvent::MouseButtonPress && m_pPointTable != NULL) { QWidget* clickedWidget = qobject_cast(watched); if(clickedWidget != NULL) { bool isTableViewport = clickedWidget == m_pPointTable->viewport() || m_pPointTable->viewport()->isAncestorOf(clickedWidget); if(clickedWidget == m_pPointTable->viewport()) { QMouseEvent* mouseEvent = static_cast(event); if(m_pPointTable->itemAt(mouseEvent->pos()) == NULL) { clearTableSelection(); } } else if(!isTableViewport && clickedWidget != m_pDeletePointButton) { clearTableSelection(); } } } return iDlgBase::eventFilter(watched, event); } void nmWxPropertyInterpolationDlg::onMapPickToggled(bool checked) { if(m_pPlot.isNull() || m_pPlot->m_pPlotView == NULL) { return; } disconnect(m_pPlot->m_pPlotView, SIGNAL(sigLeftClick(QPointF)), this, SLOT(onMapClicked(QPointF))); if(checked) { m_pPlot->cancelActiveTools(); connect(m_pPlot->m_pPlotView, SIGNAL(sigLeftClick(QPointF)), this, SLOT(onMapClicked(QPointF))); m_pPlot->m_pPlotView->setCursor(Qt::CrossCursor); } else { m_pPlot->m_pPlotView->restoreCursor(); } } void nmWxPropertyInterpolationDlg::onMapClicked(const QPointF& position) { if(!m_pMapPickButton->isChecked() || m_pPlot.isNull() || m_pPlot->m_pPlot == NULL || m_nCurrentDataSetIndex < 0) { return; } if(!m_pPlot->m_pPlot->getInnerRectF().contains(position)) { return; } QPointF plotPosition = position; QPointF valuePoint = m_pPlot->m_pPlot->getValueForPos(plotPosition); appendPoint(valuePoint); } void nmWxPropertyInterpolationDlg::appendPoint(const QPointF& valuePoint) { if(m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[m_nCurrentDataSetIndex]; double pointValue = m_pNewValueSpin->value(); nmPropertyInterpolationPointData point(valuePoint.x(), valuePoint.y(), pointValue); QString markerName = createMarker(valuePoint, pointValue, dataSet.showPoints, dataSet.showLabels); dataSet.points.append(point); m_vecMarkerNames[m_nCurrentDataSetIndex].append(markerName); bool oldBlock = m_pPointTable->blockSignals(true); appendPointRow(point, markerName); m_pPointTable->blockSignals(oldBlock); m_pPointTable->scrollToBottom(); updatePointButtons(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::appendPointRow( const nmPropertyInterpolationPointData& point, const QString& markerName) { int row = m_pPointTable->rowCount(); m_pPointTable->insertRow(row); QTableWidgetItem* xItem = new QTableWidgetItem(QString::number(point.x, 'g', 15)); xItem->setFlags(xItem->flags() & ~Qt::ItemIsEditable); xItem->setData(Qt::UserRole, markerName); m_pPointTable->setItem(row, 0, xItem); QTableWidgetItem* yItem = new QTableWidgetItem(QString::number(point.y, 'g', 15)); yItem->setFlags(yItem->flags() & ~Qt::ItemIsEditable); m_pPointTable->setItem(row, 1, yItem); m_pPointTable->setItem(row, 2, new QTableWidgetItem(QString::number(point.value, 'f', 6))); } QString nmWxPropertyInterpolationDlg::createMarker(const QPointF& valuePosition, double value, bool showPoints, bool showLabels) { if(m_pPlot.isNull() || m_pPlot->m_pPlot == NULL) { return QString(); } QString markerName; do { markerName = QString("__PropertyInterpolationPoint_%1").arg(++m_nNextPointId); } while(m_pPlot->m_pPlot->getObjByName(markerName) != NULL); bool wasModified = m_pPlot->isModified(); PropertyInterpolationMarker* marker = new PropertyInterpolationMarker( markerName, m_pPlot->m_pPlot->getMainAxisX(), m_pPlot->m_pPlot->getMainAxisY()); m_pPlot->bindObjSignals(marker); if(!m_pPlot->m_pPlot->addOneObj(marker)) { delete marker; m_pPlot->setModified(wasModified); return QString(); } QVector values; values.append(valuePosition); marker->setAllValues(values); m_pPlot->slotObjCompleted(marker); setMarkerLabel(marker, QString::number(value, 'g', 10)); marker->setReadOnly(true); marker->setLockPos(true); marker->showSubObjs(showPoints && showLabels); marker->setVisible(showPoints); marker->deselect(true); marker->update(); m_pPlot->setModified(wasModified); return markerName; } void nmWxPropertyInterpolationDlg::createMarkersForAllDataSets() { if(m_pPlot.isNull() || m_pPlot->m_pPlot == NULL) { return; } for(int dataSetIndex = 0; dataSetIndex < m_vecDataSets.size(); ++dataSetIndex) { const nmPropertyInterpolationDataSet& dataSet = m_vecDataSets[dataSetIndex]; QStringList markerNames; for(int pointIndex = 0; pointIndex < dataSet.points.size(); ++pointIndex) { const nmPropertyInterpolationPointData& point = dataSet.points[pointIndex]; QPointF valuePosition(point.x, point.y); markerNames.append(createMarker(valuePosition, point.value, dataSet.showPoints, dataSet.showLabels)); } m_vecMarkerNames[dataSetIndex] = markerNames; } } void nmWxPropertyInterpolationDlg::removeDataSetMarkers(int dataSetIndex) { if(dataSetIndex < 0 || dataSetIndex >= m_vecMarkerNames.size()) { return; } const QStringList markerNames = m_vecMarkerNames[dataSetIndex]; for(int i = 0; i < markerNames.size(); ++i) { removeMarkerByName(markerNames[i]); } m_vecMarkerNames[dataSetIndex].clear(); } void nmWxPropertyInterpolationDlg::removeAllMarkers() { for(int i = 0; i < m_vecMarkerNames.size(); ++i) { removeDataSetMarkers(i); } m_vecMarkerNames.clear(); } QString nmWxPropertyInterpolationDlg::markerNameAt(int row) const { if(m_pPointTable == NULL || row < 0 || row >= m_pPointTable->rowCount()) { return QString(); } QTableWidgetItem* item = m_pPointTable->item(row, 0); return item == NULL ? QString() : item->data(Qt::UserRole).toString(); } nmObjPoint* nmWxPropertyInterpolationDlg::markerByName(const QString& markerName) const { if(m_pPlot.isNull() || m_pPlot->m_pPlot == NULL || markerName.isEmpty()) { return NULL; } return dynamic_cast(m_pPlot->m_pPlot->getObjByName(markerName)); } nmObjPoint* nmWxPropertyInterpolationDlg::markerAt(int row) const { return markerByName(markerNameAt(row)); } void nmWxPropertyInterpolationDlg::removeMarkerByName(const QString& markerName) { if(m_pPlot.isNull() || m_pPlot->m_pPlot == NULL || markerName.isEmpty() || m_pPlot->m_pPlot->getObjByName(markerName) == NULL) { return; } bool wasModified = m_pPlot->isModified(); m_pPlot->m_pPlot->removeObjByName(markerName); m_pPlot->setModified(wasModified); } void nmWxPropertyInterpolationDlg::onPointSelectionChanged() { updatePointButtons(); } void nmWxPropertyInterpolationDlg::onPointItemChanged(QTableWidgetItem* item) { if(m_bUpdatingUi || item == NULL || item->column() != 2 || m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size() || item->row() >= m_vecDataSets[m_nCurrentDataSetIndex].points.size()) { return; } m_vecDataSets[m_nCurrentDataSetIndex].points[item->row()].value = item->text().toDouble(); nmObjPoint* marker = markerAt(item->row()); if(marker != NULL) { setMarkerLabel(marker, item->text()); marker->update(); } syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onDeleteSelectedPoint() { int row = m_pPointTable->currentRow(); if(row < 0 || m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } removeMarkerByName(markerNameAt(row)); if(row < m_vecDataSets[m_nCurrentDataSetIndex].points.size()) { m_vecDataSets[m_nCurrentDataSetIndex].points.remove(row); } if(row < m_vecMarkerNames[m_nCurrentDataSetIndex].size()) { m_vecMarkerNames[m_nCurrentDataSetIndex].removeAt(row); } m_pPointTable->removeRow(row); clearTableSelection(); updatePointButtons(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onClearPoints() { if(m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } removeDataSetMarkers(m_nCurrentDataSetIndex); m_vecDataSets[m_nCurrentDataSetIndex].points.clear(); m_pPointTable->setRowCount(0); clearTableSelection(); updatePointButtons(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onShowPointsToggled(bool checked) { if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } m_vecDataSets[m_nCurrentDataSetIndex].showPoints = checked; updateCurrentMarkerVisibility(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::onShowLabelsToggled(bool checked) { if(m_bUpdatingUi || m_nCurrentDataSetIndex < 0 || m_nCurrentDataSetIndex >= m_vecDataSets.size()) { return; } m_vecDataSets[m_nCurrentDataSetIndex].showLabels = checked; updateCurrentMarkerVisibility(); syncDataSetsToManager(true); } void nmWxPropertyInterpolationDlg::clearTableSelection() { m_pPointTable->clearSelection(); m_pPointTable->setCurrentCell(-1, -1); } void nmWxPropertyInterpolationDlg::updatePointButtons() { const bool hasCurrent = m_nCurrentDataSetIndex >= 0 && m_nCurrentDataSetIndex < m_vecDataSets.size(); m_pDeletePointButton->setEnabled(hasCurrent && m_pPointTable->currentRow() >= 0); m_pClearPointsButton->setEnabled(hasCurrent && m_pPointTable->rowCount() > 0); } void nmWxPropertyInterpolationDlg::updateCurrentMarkerVisibility() { // 地图上只显示当前数据组的测点,其他数据组统一隐藏. for(int dataSetIndex = 0; dataSetIndex < m_vecMarkerNames.size(); ++dataSetIndex) { const bool isCurrentDataSet = dataSetIndex == m_nCurrentDataSetIndex && dataSetIndex < m_vecDataSets.size(); const bool showPoints = isCurrentDataSet && m_vecDataSets[dataSetIndex].showPoints; const bool showLabels = showPoints && m_vecDataSets[dataSetIndex].showLabels; const QStringList markerNames = m_vecMarkerNames[dataSetIndex]; for(int markerIndex = 0; markerIndex < markerNames.size(); ++markerIndex) { nmObjPoint* marker = markerByName(markerNames[markerIndex]); if(marker != NULL) { marker->setVisible(showPoints); marker->showSubObjs(showLabels); marker->update(); } } } if(!m_pPlot.isNull() && m_pPlot->m_pPlotView != NULL) { m_pPlot->m_pPlotView->updateViewport(); } }