diff --git a/forms/source/component/DatabaseForm.cxx b/forms/source/component/DatabaseForm.cxx index 18d0d854da57..2ebab406beac 100644 --- a/forms/source/component/DatabaseForm.cxx +++ b/forms/source/component/DatabaseForm.cxx @@ -53,11 +53,13 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -68,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -1923,6 +1926,70 @@ void SAL_CALL ODatabaseForm::reset() } } +Reference ODatabaseForm::getFormatter() +{ + if (auto xSupplier = dbtools::getNumberFormats(getConnection(), true, m_xContext)) + { + auto result = NumberFormatter::create(m_xContext); + result->attachNumberFormatsSupplier(xSupplier); + return result; + } + return {}; +} + +static void maybeConvertDefaultStringToDate(Any& def, const auto& getFieldPropOrDefault, + const auto& getFormatter) +{ + OUString sDefault; + if (!(def >>= sDefault)) + return; + + sal_Int32 dataType = getFieldPropOrDefault(PROPERTY_FIELDTYPE, sal_Int32()); + if (dataType != css::sdbc::DataType::DATE && dataType != css::sdbc::DataType::TIMESTAMP) + return; + + Reference xFormatter = getFormatter(); + if (!xFormatter) + return; + + // Convert to a date + sal_uInt32 nFormatKey = xFormatter->detectNumberFormat( + getFieldPropOrDefault(PROPERTY_FORMATKEY, sal_uInt32()), sDefault); + sal_Int16 nType = comphelper::getNumberFormatType(xFormatter, nFormatKey); + if ((nType & css::util::NumberFormat::DATE) == 0) + return; + + Reference xSupplier = xFormatter->getNumberFormatsSupplier(); + css::util::Date aNull; + try + { + if (!(xSupplier->getNumberFormatSettings()->getPropertyValue(u"NullDate"_ustr) >>= aNull)) + return; + } + catch (const Exception&) + { + return; + } + ::Date d(aNull); + + double value = xFormatter->convertStringToNumber(nFormatKey, sDefault); + switch (dataType) + { + case css::sdbc::DataType::DATE: + { + d.AddDays(value); + def <<= d.GetUNODate(); + break; + } + case css::sdbc::DataType::TIMESTAMP: + { + ::DateTime dt(d); + dt.AddTime(value); + def <<= dt.GetUNODateTime(); + break; + } + } +} void ODatabaseForm::reset_impl(bool _bApproveByListeners) { @@ -1956,24 +2023,27 @@ void ODatabaseForm::reset_impl(bool _bApproveByListeners) if ( !xColUpdate.is() ) continue; - Reference< XPropertySetInfo > xPSI; - if ( xColProps.is() ) - xPSI = xColProps->getPropertySetInfo( ); + auto getPropValOrDefault = [&xColProps, xPSI = xColProps->getPropertySetInfo()]( + const OUString& propname, auto default_value) + { + if (xPSI && xPSI->hasPropertyByName(propname)) + fromAny(xColProps->getPropertyValue(propname), &default_value); + return default_value; + }; - static constexpr OUString PROPERTY_CONTROLDEFAULT = u"ControlDefault"_ustr; - if (!xPSI || !xPSI->hasPropertyByName(PROPERTY_CONTROLDEFAULT)) - continue; - - Any aDefault = xColProps->getPropertyValue( PROPERTY_CONTROLDEFAULT ); + Any aDefault = getPropValOrDefault(u"ControlDefault"_ustr, Any()); if (!aDefault.hasValue()) continue; - bool bReadOnly = false; - if ( xPSI->hasPropertyByName( PROPERTY_ISREADONLY ) ) - xColProps->getPropertyValue( PROPERTY_ISREADONLY ) >>= bReadOnly; - if (bReadOnly) + if (getPropValOrDefault(PROPERTY_ISREADONLY, false)) continue; + // If the column is a date, and the default is a string, it may be + // impossible to convert the string to date at a later stage (namely, in + // DBTypeConversion::getValue, where the column formatting is unknown). + maybeConvertDefaultStringToDate(aDefault, getPropValOrDefault, + [this]() { return getFormatter(); }); + try { xColUpdate->updateObject( aDefault ); diff --git a/forms/source/component/DatabaseForm.hxx b/forms/source/component/DatabaseForm.hxx index 73831a9c67ba..a9c4badb6545 100644 --- a/forms/source/component/DatabaseForm.hxx +++ b/forms/source/component/DatabaseForm.hxx @@ -54,6 +54,7 @@ #include #include #include +#include #include @@ -518,6 +519,9 @@ private: void impl_construct(); DECL_LINK( OnTimeout, Timer*, void ); + + css::uno::Reference getFormatter(); + protected: using OPropertySetHelper::getPropertyValues; };