#include "nmReservoirParameterField.h" #include "iParaItemCtrl.h" #include "iParameter.h" #include "iSysParaHelper.h" #include "mModuleDefines.h" #include #include #include #include #include #include namespace { /* Qt 4.8的lupdate需要显式标记间接翻译字符串。 */ static const char* const s_pFieldTranslationMarkers[] = { QT_TRANSLATE_NOOP("nmReservoirParameterField", "The parameter layout is unavailable."), QT_TRANSLATE_NOOP("nmReservoirParameterField", "Parameter definition not found: %1"), QT_TRANSLATE_NOOP("nmReservoirParameterField", "Failed to bind the unit for parameter: %1") }; /** @brief 返回轻量字段类使用的翻译文字。 */ QString fieldText(const char* pText) { Q_UNUSED(s_pFieldTranslationMarkers); return QCoreApplication::translate( "nmReservoirParameterField", pText); } } nmReservoirParameterField::nmReservoirParameterField( const nmReservoirParameterFieldInfo& oFieldInfo, nmIReservoirParameterUnitService* pUnitService, QObject* pParent) : QObject(pParent), m_oFieldInfo(oFieldInfo), m_pUnitService(pUnitService), m_pParameter(nullptr), m_pLabel(nullptr), m_pLineEdit(nullptr), m_pValueComboBox(nullptr), m_pUnitComboBox(nullptr), m_pUnitLabel(nullptr), m_bVisible(true), m_bUpdating(false) { } nmReservoirParameterField::~nmReservoirParameterField() { m_pUnitService = nullptr; m_pParameter = nullptr; m_pLabel = nullptr; m_pLineEdit = nullptr; m_pValueComboBox = nullptr; m_pUnitComboBox = nullptr; m_pUnitLabel = nullptr; } bool nmReservoirParameterField::initialize(QGridLayout* pLayout, int nRow, int nColumnOffset, QString& sError) { if (pLayout == nullptr) { sError = fieldText("The parameter layout is unavailable."); return false; } // 第一步:枚举字段不依赖XML数值定义,直接创建稳定code下拉框。 if (isEnum()) { createEnumEditor(pLayout, nRow, nColumnOffset); sError.clear(); return true; } // 第二步:数值字段必须取得NM系列的基础参数定义。 m_pParameter = _paraHelper->getPara( m_oFieldInfo.m_sBaseParameterId, s_Nm_Serie); if (m_pParameter == nullptr) { sError = fieldText("Parameter definition not found: %1") .arg(m_oFieldInfo.m_sBaseParameterId); return false; } // 第三步:创建原型中的标签、输入框和单位列,不增加字段外框。 return createNumericEditor(pLayout, nRow, nColumnOffset, sError); } QString nmReservoirParameterField::parameterId() const { return m_oFieldInfo.m_sParameterId; } QString nmReservoirParameterField::baseParameterId() const { return m_oFieldInfo.m_sBaseParameterId; } bool nmReservoirParameterField::isEnum() const { return m_oFieldInfo.m_eEditorType == NM_RESERVOIR_EDITOR_ENUM; } void nmReservoirParameterField::setValueRightAligned(bool bRightAligned) { if (m_pLineEdit != nullptr) { m_pLineEdit->setAlignment( (bRightAligned ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter); } } int nmReservoirParameterField::editorMinimumWidth() { return 140; } int nmReservoirParameterField::unitMinimumWidth() { return 86; } int nmReservoirParameterField::editorHeight() { return 25; } bool nmReservoirParameterField::createNumericEditor( QGridLayout* pLayout, int nRow, int nColumnOffset, QString& sError) { QWidget* pParentWidget = pLayout->parentWidget(); m_pLabel = new QLabel(m_pParameter->m_sAlias, pParentWidget); m_pLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); m_pLabel->setWordWrap(false); m_pLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); m_pLineEdit = new QLineEdit(pParentWidget); m_pLineEdit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); m_pLineEdit->setFixedHeight(editorHeight()); m_pLineEdit->setMinimumWidth(editorMinimumWidth()); m_pLineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); pLayout->addWidget(m_pLabel, nRow, nColumnOffset); pLayout->addWidget(m_pLineEdit, nRow, nColumnOffset + 1); // 有单位参数直接注册到主对话框绑定器;字段只按控件指针读写, // 因此多口井共用同一基础参数ID时也不会发生串值。 if (m_oFieldInfo.m_bUnitEnabled && !m_pParameter->m_sUnit.isEmpty()) { m_pUnitComboBox = new QComboBox(pParentWidget); m_pUnitComboBox->setFixedHeight(editorHeight()); m_pUnitComboBox->setMinimumWidth(unitMinimumWidth()); m_pUnitComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); pLayout->addWidget(m_pUnitComboBox, nRow, nColumnOffset + 2); if (m_pUnitService == nullptr || !m_pUnitService->bindUnitField( m_pLineEdit, m_pUnitComboBox, m_oFieldInfo.m_sBaseParameterId)) { sError = fieldText( "Failed to bind the unit for parameter: %1") .arg(m_oFieldInfo.m_sBaseParameterId); return false; } } else { // 无单位参数保留空列用于对齐,不显示额外的单位说明文字。 m_pUnitLabel = new QLabel(pParentWidget); m_pUnitLabel->setMinimumWidth(unitMinimumWidth()); m_pUnitLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); pLayout->addWidget(m_pUnitLabel, nRow, nColumnOffset + 2); } updateValidationAppearance(true); sError.clear(); return true; } void nmReservoirParameterField::createEnumEditor(QGridLayout* pLayout, int nRow, int nColumnOffset) { QWidget* pParentWidget = pLayout->parentWidget(); m_pLabel = new QLabel(m_oFieldInfo.m_sLabel, pParentWidget); m_pLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); m_pLabel->setWordWrap(false); m_pLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); m_pValueComboBox = new QComboBox(pParentWidget); m_pValueComboBox->setFixedHeight(editorHeight()); m_pValueComboBox->setMinimumWidth(editorMinimumWidth()); m_pValueComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); for (int nIndex = 0; nIndex < m_oFieldInfo.m_listOptions.size(); ++nIndex) { const nmReservoirEnumOption& oOption = m_oFieldInfo.m_listOptions[nIndex]; m_pValueComboBox->addItem(oOption.m_sText, oOption.m_sCode); } // 枚举参数没有单位,空白单位列仅用于保持各行编辑器对齐。 m_pUnitLabel = new QLabel(pParentWidget); m_pUnitLabel->setMinimumWidth(unitMinimumWidth()); m_pUnitLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); pLayout->addWidget(m_pLabel, nRow, nColumnOffset); pLayout->addWidget(m_pValueComboBox, nRow, nColumnOffset + 1); pLayout->addWidget(m_pUnitLabel, nRow, nColumnOffset + 2); } void nmReservoirParameterField::setBaseValue(const QVariant& oValue) { if (m_pLineEdit == nullptr || !oValue.isValid()) { return; } m_bUpdating = true; double dValue = oValue.toDouble(); if (m_pUnitComboBox != nullptr && m_pUnitService != nullptr) { m_pUnitService->setUnitBaseValue(m_pLineEdit, dValue); } else { m_pLineEdit->setText(formatBaseValue(dValue)); } m_bUpdating = false; validate(); } QVariant nmReservoirParameterField::baseValue(bool& bValid) { bValid = validate(); if (!bValid || m_pLineEdit == nullptr) { return QVariant(); } if (m_pUnitComboBox != nullptr && m_pUnitService != nullptr) { return QVariant(m_pUnitService->unitBaseValue(m_pLineEdit)); } bool bNumberOk = false; double dValue = m_pLineEdit->text().trimmed().toDouble(&bNumberOk); return bNumberOk ? QVariant(dValue) : QVariant(); } void nmReservoirParameterField::setEnumCode(const QString& sCode) { if (m_pValueComboBox == nullptr) { return; } int nIndex = m_pValueComboBox->findData(sCode); m_bUpdating = true; m_pValueComboBox->setCurrentIndex(nIndex >= 0 ? nIndex : 0); m_bUpdating = false; } QString nmReservoirParameterField::enumCode() const { if (m_pValueComboBox == nullptr || m_pValueComboBox->currentIndex() < 0) { return QString(); } return m_pValueComboBox->itemData( m_pValueComboBox->currentIndex()).toString(); } bool nmReservoirParameterField::validate() { if (!m_bVisible || isEnum()) { return true; } if (m_pLineEdit == nullptr || m_pParameter == nullptr) { return false; } bool bValid = false; if (m_pUnitComboBox != nullptr && m_pUnitService != nullptr) { bValid = m_pUnitService->isUnitInputValid(m_pLineEdit); } else { bool bNumberOk = false; double dValue = m_pLineEdit->text().trimmed() .toDouble(&bNumberOk); bValid = bNumberOk && dValue == dValue && dValue >= m_pParameter->m_dMin && dValue <= m_pParameter->m_dMax; if (bValid && m_oFieldInfo.m_eEditorType == NM_RESERVOIR_EDITOR_INTEGER) { bValid = dValue == static_cast(dValue); } } updateValidationAppearance(bValid); return bValid; } void nmReservoirParameterField::setFieldVisible(bool bVisible) { m_bVisible = bVisible; if (m_pLabel != nullptr) { m_pLabel->setVisible(bVisible); } if (m_pLineEdit != nullptr) { m_pLineEdit->setVisible(bVisible); } if (m_pValueComboBox != nullptr) { m_pValueComboBox->setVisible(bVisible); } if (m_pUnitComboBox != nullptr) { m_pUnitComboBox->setVisible(bVisible); } if (m_pUnitLabel != nullptr) { m_pUnitLabel->setVisible(bVisible); } } bool nmReservoirParameterField::isFieldVisible() const { return m_bVisible; } QLineEdit* nmReservoirParameterField::valueEditor() const { return m_pLineEdit; } QComboBox* nmReservoirParameterField::enumEditor() const { return m_pValueComboBox; } QString nmReservoirParameterField::formatBaseValue(double dValue) const { if (m_pParameter == nullptr) { return QString::number(dValue, 'g', 15); } if (m_oFieldInfo.m_eEditorType == NM_RESERVOIR_EDITOR_INTEGER || m_pParameter->m_nDigit == 0) { return QString::number(dValue, 'f', 0); } if (m_pParameter->m_bScientific) { return QString::number(dValue, 'e', m_pParameter->m_nDigit); } QString sValue = QString::number( dValue, 'f', m_pParameter->m_nDigit); while (sValue.contains('.') && sValue.endsWith('0')) { sValue.chop(1); } if (sValue.endsWith('.')) { sValue.chop(1); } return sValue; } void nmReservoirParameterField::updateValidationAppearance(bool bValid) { Q_UNUSED(bValid); if (m_pLineEdit == nullptr || m_pParameter == nullptr) { return; } QString sCurrentUnit; iUnitGroup* pUnitGroup = nullptr; if (m_pUnitComboBox != nullptr && m_pUnitService != nullptr) { sCurrentUnit = m_pUnitService->currentUnit(m_pLineEdit); pUnitGroup = m_pUnitService->unitGroup(m_pLineEdit); } QString sRange = iParaItemCtrl::getScaleStrOf( m_pParameter, sCurrentUnit, pUnitGroup); QString sHelp = m_pParameter->m_sDesc; if (!sRange.isEmpty()) { if (!sHelp.isEmpty()) { sHelp += "\n"; } sHelp += sRange; } m_pLineEdit->setToolTip(sHelp); m_pLineEdit->setWhatsThis(sHelp); if (m_pLabel != nullptr) { m_pLabel->setWhatsThis(sHelp); } }