include/sax/tools/converter.hxx | 6 +++ oox/source/core/xmlfilterbase.cxx | 29 ++++++++++++++++++ sax/source/tools/converter.cxx | 60 ++++++++++++++++++++++++++------------ sc/source/ui/view/tabvwshc.cxx | 4 -- 4 files changed, 77 insertions(+), 22 deletions(-)
New commits: commit fd1b7b7635fcddabafb3b6c4b27ebe5d5bac9e01 Author: Markus Mohrhard <[email protected]> AuthorDate: Wed Nov 19 11:28:53 2025 +0800 Commit: Xisco Fauli <[email protected]> CommitDate: Thu Nov 27 16:34:59 2025 +0100 tdf#157211: don't limit range to data range when opening DB name dialog This behavior is not what the user expects and we don't need to init the mark block mode again. This is already taken care off by the GetDBData code. Change-Id: I58556642ae696e32065e76e68b9eaca082863dad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194182 Tested-by: Jenkins Reviewed-by: Markus Mohrhard <[email protected]> (cherry picked from commit 512edf27d5593b2123034c5797b2bee3b27bf307) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194238 Reviewed-by: Xisco Fauli <[email protected]> Code-Style: Xisco Fauli <[email protected]> diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx index f63a670e22de..6766e5bcc3ec 100644 --- a/sc/source/ui/view/tabvwshc.cxx +++ b/sc/source/ui/view/tabvwshc.cxx @@ -257,10 +257,6 @@ std::shared_ptr<SfxModelessDialogController> ScTabViewShell::CreateRefDialogCont { // when called for an existing range, then mark GetDBData( true, SC_DB_OLD ); - const ScMarkData& rMark = GetViewData().GetMarkData(); - if ( !rMark.IsMarked() && !rMark.IsMultiMarked() ) - MarkDataArea( false ); - xResult = std::make_shared<ScDbNameDlg>(pB, pCW, pParent, GetViewData()); break; } commit 114ab9c93d241a83da3e0842ddbccf004687d966 Author: Noel Grandin <[email protected]> AuthorDate: Tue Nov 4 13:56:56 2025 +0200 Commit: Xisco Fauli <[email protected]> CommitDate: Thu Nov 27 16:34:48 2025 +0100 mso-test: invalid datetime in props This is using the test document from tdf119234-3.odt. When importing and exporting to DOCX, we generate an invalid entry in docprops/custom.xml because we dont know how to handle a DateTimeWithTimezone value.. Change-Id: I79981f8a09db432730a9b0c1cf186305b0055923 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193400 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit 97cf170c20c7ff1e1b3820a769cd3167a57d0c46) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193600 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins (cherry picked from commit 5a9e966b323a1605976a53ca6bac750741036eba) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193723 Reviewed-by: Xisco Fauli <[email protected]> Code-Style: Xisco Fauli <[email protected]> diff --git a/include/sax/tools/converter.hxx b/include/sax/tools/converter.hxx index 6b18cac11bf4..f39e293bdf98 100644 --- a/include/sax/tools/converter.hxx +++ b/include/sax/tools/converter.hxx @@ -259,6 +259,12 @@ public: sal_Int16 const* pTimeZoneOffset, bool bAddTimeIf0AM = false ); + /** convert util::DateTime to XMLSchema-2 "date" or "dateTime" string */ + static void convertDateTime( OStringBuffer& rBuffer, + const css::util::DateTime& rDateTime, + sal_Int16 const* pTimeZoneOffset, + bool bAddTimeIf0AM = false ); + /** convert util::DateTime to XMLSchema-2 "time" or "dateTime" string */ static void convertTimeOrDateTime(OUStringBuffer& rBuffer, const css::util::DateTime& rDateTime); diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index 85defeea3dfd..9a892e8a0736 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -28,6 +28,7 @@ #include <com/sun/star/embed/XRelationshipAccess.hpp> #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/util/DateTimeWithTimezone.hpp> #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp> #include <com/sun/star/xml/sax/XSAXSerializable.hpp> #include <com/sun/star/xml/sax/Writer.hpp> @@ -620,6 +621,31 @@ writeElement( const FSHelperPtr& pDoc, sal_Int32 nXmlElement, const util::DateTi pDoc->endElement( nXmlElement ); } +static void +writeElement( const FSHelperPtr& pDoc, sal_Int32 nXmlElement, const util::DateTimeWithTimezone& rTime ) +{ + if (rTime.Timezone == 0) + { + writeElement(pDoc, nXmlElement, rTime.DateTimeInTZ); + return; + } + + if( rTime.DateTimeInTZ.Year == 0 ) + return; + + if ( ( nXmlElement >> 16 ) != XML_dcterms ) + pDoc->startElement(nXmlElement); + else + pDoc->startElement(nXmlElement, FSNS(XML_xsi, XML_type), "dcterms:W3CDTF"); + + OStringBuffer aStr; + sax::Converter::convertDateTime(aStr, rTime.DateTimeInTZ, &rTime.Timezone); + + pDoc->write( aStr ); + + pDoc->endElement( nXmlElement ); +} + static void writeElement( const FSHelperPtr& pDoc, sal_Int32 nXmlElement, const Sequence< OUString >& aItems ) { @@ -972,6 +998,7 @@ writeCustomProperties( XmlFilterBase& rSelf, const Reference< XDocumentPropertie util::Date aDate; util::Duration aDuration; util::DateTime aDateTime; + util::DateTimeWithTimezone aDateTimeTZ; if ( rProp.Value >>= num ) { // i4 - 4-byte signed integer @@ -991,6 +1018,8 @@ writeCustomProperties( XmlFilterBase& rSelf, const Reference< XDocumentPropertie } else if ( rProp.Value >>= aDateTime ) writeElement( pAppProps, FSNS( XML_vt, XML_filetime ), aDateTime ); + else if ( rProp.Value >>= aDateTimeTZ ) + writeElement( pAppProps, FSNS( XML_vt, XML_filetime ), aDateTimeTZ ); else //no other options OSL_FAIL( "XMLFilterBase::writeCustomProperties unsupported value type!" ); diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx index 360b4cd32918..422ec4212e4a 100644 --- a/sax/source/tools/converter.cxx +++ b/sax/source/tools/converter.cxx @@ -1575,8 +1575,9 @@ bool Converter::convertDuration(util::Duration& rDuration, return convertDurationHelper(rDuration, o3tl::trim(rString)); } +template<typename TStringBuffer> static void -lcl_AppendTimezone(OUStringBuffer & i_rBuffer, int const nOffset) +lcl_AppendTimezone(TStringBuffer & i_rBuffer, int const nOffset) { if (0 == nOffset) { @@ -1621,18 +1622,19 @@ void Converter::convertDate( convertDateTime(i_rBuffer, dt, pTimeZoneOffset); } +template<typename TStringBuffer, typename TString> static void convertTime( - OUStringBuffer& i_rBuffer, + TStringBuffer& i_rBuffer, const css::util::DateTime& i_rDateTime) { if (i_rDateTime.Hours < 10) { i_rBuffer.append('0'); } - i_rBuffer.append( OUString::number(static_cast<sal_Int32>(i_rDateTime.Hours)) + ":"); + i_rBuffer.append( TString::number(static_cast<sal_Int32>(i_rDateTime.Hours)) + ":"); if (i_rDateTime.Minutes < 10) { i_rBuffer.append('0'); } - i_rBuffer.append( OUString::number(static_cast<sal_Int32>(i_rDateTime.Minutes) ) + ":"); + i_rBuffer.append( TString::number(static_cast<sal_Int32>(i_rDateTime.Minutes) ) + ":"); if (i_rDateTime.Seconds < 10) { i_rBuffer.append('0'); } @@ -1640,16 +1642,17 @@ static void convertTime( if (i_rDateTime.NanoSeconds > 0) { OSL_ENSURE(i_rDateTime.NanoSeconds < 1000000000,"NanoSeconds cannot be more than 999 999 999"); i_rBuffer.append('.'); - std::ostringstream ostr; - ostr.fill('0'); - ostr.width(9); - ostr << i_rDateTime.NanoSeconds; - i_rBuffer.appendAscii(ostr.str().c_str()); + // pad to 9 characters length + auto sNanoStr = TString::number(i_rDateTime.NanoSeconds); + for (int i=0; i < 9 - sNanoStr.length; i++) + i_rBuffer.append('0'); + i_rBuffer.append(sNanoStr); } } +template<typename TStringBuffer> static void convertTimeZone( - OUStringBuffer& i_rBuffer, + TStringBuffer& i_rBuffer, const css::util::DateTime& i_rDateTime, sal_Int16 const* pTimeZoneOffset) { @@ -1672,7 +1675,7 @@ void Converter::convertTimeOrDateTime( i_rDateTime.Month < 1 || i_rDateTime.Month > 12 || i_rDateTime.Day < 1 || i_rDateTime.Day > 31) { - convertTime(i_rBuffer, i_rDateTime); + convertTime<OUStringBuffer, OUString>(i_rBuffer, i_rDateTime); convertTimeZone(i_rBuffer, i_rDateTime, nullptr); } else @@ -1682,14 +1685,15 @@ void Converter::convertTimeOrDateTime( } /** convert util::DateTime to ISO "date" or "dateTime" string */ -void Converter::convertDateTime( - OUStringBuffer& i_rBuffer, +template<typename TStringBuffer, typename TString, typename TStringChar> +static void lcl_convertDateTime( + TStringBuffer& i_rBuffer, const css::util::DateTime& i_rDateTime, sal_Int16 const*const pTimeZoneOffset, bool i_bAddTimeIf0AM ) { - const sal_Unicode dash('-'); - const sal_Unicode zero('0'); + const char dash('-'); + const char zero('0'); sal_Int32 const nYear(abs(i_rDateTime.Year)); if (i_rDateTime.Year < 0) { @@ -1704,11 +1708,11 @@ void Converter::convertDateTime( if (nYear < 10) { i_rBuffer.append(zero); } - i_rBuffer.append( OUString::number(nYear) + OUStringChar(dash) ); + i_rBuffer.append( TString::number(nYear) + TStringChar(dash) ); if( i_rDateTime.Month < 10 ) { i_rBuffer.append(zero); } - i_rBuffer.append( OUString::number(i_rDateTime.Month) + OUStringChar(dash) ); + i_rBuffer.append( TString::number(i_rDateTime.Month) + TStringChar(dash) ); if( i_rDateTime.Day < 10 ) { i_rBuffer.append(zero); } @@ -1720,12 +1724,32 @@ void Converter::convertDateTime( i_bAddTimeIf0AM ) { i_rBuffer.append('T'); - convertTime(i_rBuffer, i_rDateTime); + convertTime<TStringBuffer, TString>(i_rBuffer, i_rDateTime); } convertTimeZone(i_rBuffer, i_rDateTime, pTimeZoneOffset); } +/** convert util::DateTime to ISO "date" or "dateTime" string */ +void Converter::convertDateTime( + OUStringBuffer& i_rBuffer, + const css::util::DateTime& i_rDateTime, + sal_Int16 const*const pTimeZoneOffset, + bool i_bAddTimeIf0AM ) +{ + lcl_convertDateTime<OUStringBuffer, OUString, OUStringChar>(i_rBuffer, i_rDateTime, pTimeZoneOffset, i_bAddTimeIf0AM); +} + +/** convert util::DateTime to ISO "date" or "dateTime" string */ +void Converter::convertDateTime( + OStringBuffer& i_rBuffer, + const css::util::DateTime& i_rDateTime, + sal_Int16 const*const pTimeZoneOffset, + bool i_bAddTimeIf0AM ) +{ + lcl_convertDateTime<OStringBuffer, OString, OStringChar>(i_rBuffer, i_rDateTime, pTimeZoneOffset, i_bAddTimeIf0AM); +} + /** convert ISO "date" or "dateTime" string to util::DateTime */ bool Converter::parseDateTime( util::DateTime& rDateTime, std::u16string_view rString )
