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

430 lines
12 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 "nmReservoirParameterField.h"
#include "iParaItemCtrl.h"
#include "iParameter.h"
#include "iSysParaHelper.h"
#include "mModuleDefines.h"
#include <QComboBox>
#include <QCoreApplication>
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QSizePolicy>
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,
QString& sError)
{
if (pLayout == nullptr)
{
sError = fieldText("The parameter layout is unavailable.");
return false;
}
// 第一步枚举字段不依赖XML数值定义直接创建稳定code下拉框。
if (isEnum())
{
createEnumEditor(pLayout, nRow);
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, 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,
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, 0);
pLayout->addWidget(m_pLineEdit, nRow, 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, 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, 2);
}
updateValidationAppearance(true);
sError.clear();
return true;
}
void nmReservoirParameterField::createEnumEditor(QGridLayout* pLayout,
int nRow)
{
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, 0);
pLayout->addWidget(m_pValueComboBox, nRow, 1);
pLayout->addWidget(m_pUnitLabel, nRow, 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<int>(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);
}
}