summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xmloff/xmlnumfe.hxx3
-rw-r--r--include/xmloff/xmlnumfi.hxx2
-rw-r--r--xmloff/source/style/xmlnumfe.cxx16
-rw-r--r--xmloff/source/style/xmlnumfi.cxx20
4 files changed, 37 insertions, 4 deletions
diff --git a/include/xmloff/xmlnumfe.hxx b/include/xmloff/xmlnumfe.hxx
index 98584ac93873..28bfe8d1a2ad 100644
--- a/include/xmloff/xmlnumfe.hxx
+++ b/include/xmloff/xmlnumfe.hxx
@@ -50,7 +50,8 @@ private:
SvXMLExport& rExport;
OUString sPrefix;
SvNumberFormatter* pFormatter;
- OUStringBuffer sTextContent;
+ OUStringBuffer sTextContent;
+ bool bHasText;
std::unique_ptr<SvXMLNumUsedList_Impl> pUsedList;
std::unique_ptr<CharClass> pCharClass;
std::unique_ptr<LocaleDataWrapper> pLocaleData;
diff --git a/include/xmloff/xmlnumfi.hxx b/include/xmloff/xmlnumfi.hxx
index 0f6384f3b785..8026b4e1846b 100644
--- a/include/xmloff/xmlnumfi.hxx
+++ b/include/xmloff/xmlnumfi.hxx
@@ -145,6 +145,7 @@ private:
bool bAutoDec; // set in AddNumber
bool bAutoInt; // set in AddNumber
bool bHasExtraText;
+ bool bHasTrailingEmptyText;
OUStringBuffer aFormatCode{64};
OUStringBuffer aConditions{32};
bool bHasLongDoW;
@@ -189,6 +190,7 @@ public:
bool HasLongDoW() const { return bHasLongDoW; }
void SetHasLongDoW(bool bSet) { bHasLongDoW = bSet; }
+ void SetHasTrailingEmptyText(bool bSet) { bHasTrailingEmptyText = bSet; }
void UpdateCalendar( const OUString& rNewCalendar );
ImplicitCalendar GetImplicitCalendarState() const { return eImplicitCalendar; }
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index 2695a84fa38b..caba160252f3 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -210,7 +210,8 @@ SvXMLNumFmtExport::SvXMLNumFmtExport(
const uno::Reference< util::XNumberFormatsSupplier >& rSupp ) :
rExport( rExp ),
sPrefix( OUString("N") ),
- pFormatter( nullptr )
+ pFormatter( nullptr ),
+ bHasText( false )
{
// supplier must be SvNumberFormatsSupplierObj
SvNumberFormatsSupplierObj* pObj =
@@ -242,7 +243,8 @@ SvXMLNumFmtExport::SvXMLNumFmtExport(
const OUString& rPrefix ) :
rExport( rExp ),
sPrefix( rPrefix ),
- pFormatter( nullptr )
+ pFormatter( nullptr ),
+ bHasText( false )
{
// supplier must be SvNumberFormatsSupplierObj
SvNumberFormatsSupplierObj* pObj =
@@ -320,16 +322,21 @@ void SvXMLNumFmtExport::AddToTextElement_Impl( std::u16string_view rString )
// to avoid several text elements following each other
sTextContent.append( rString );
+ // Also empty string leads to a number:text element as it may separate
+ // keywords of the same letter (e.g. MM""MMM) that otherwise would be
+ // concatenated when reading back in.
+ bHasText = true;
}
void SvXMLNumFmtExport::FinishTextElement_Impl(bool bUseExtensionNS)
{
- if ( !sTextContent.isEmpty() )
+ if ( bHasText )
{
sal_uInt16 nNS = bUseExtensionNS ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_NUMBER;
SvXMLElementExport aElem( rExport, nNS, XML_TEXT,
true, false );
rExport.Characters( sTextContent.makeStringAndClear() );
+ bHasText = false;
}
}
@@ -1415,6 +1422,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
{
case 0:
bEnd = true; // end of format reached
+ if (bHasText && sTextContent.isEmpty())
+ bHasText = false; // don't write trailing empty text
break;
case NF_SYMBOLTYPE_STRING:
case NF_SYMBOLTYPE_DATESEP:
@@ -1463,6 +1472,7 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
break;
case NF_KEY_GENERAL :
WriteNumberElement_Impl( -1, -1, 1, OUString(), false, 0, aEmbeddedEntries );
+ bAnyContent = true;
break;
case NF_KEY_CCC:
if (pElemStr)
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 863a9f55d2cb..121831c395bf 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -878,6 +878,13 @@ void SvXMLNumFmtElementContext::endFastElement(sal_Int32 )
lcl_EnquoteIfNecessary( aContent, rParent );
rParent.AddToCode( aContent.makeStringAndClear() );
}
+ else
+ {
+ // Quoted empty text may be significant to separate.
+ aContent.append("\"\"");
+ rParent.AddToCode( aContent.makeStringAndClear() );
+ rParent.SetHasTrailingEmptyText(true); // *after* AddToCode()
+ }
break;
case SvXMLStyleTokens::Number:
@@ -1131,6 +1138,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
bAutoDec( false ),
bAutoInt( false ),
bHasExtraText( false ),
+ bHasTrailingEmptyText( false ),
bHasLongDoW( false ),
bHasDateTime( false ),
bRemoveAfterUse( false ),
@@ -1267,6 +1275,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
bAutoDec( false ),
bAutoInt( false ),
bHasExtraText( false ),
+ bHasTrailingEmptyText( false ),
bHasLongDoW( false ),
bHasDateTime( false ),
bRemoveAfterUse( false ),
@@ -1486,12 +1495,22 @@ sal_Int32 SvXMLNumFormatContext::CreateAndInsert(SvNumberFormatter* pFormatter)
}
}
+ sal_Int32 nBufLen;
if ( aFormatCode.isEmpty() )
{
// insert empty format as empty string (with quotes)
// #93901# this check has to be done before inserting the conditions
aFormatCode.append("\"\""); // ""
}
+ else if (bHasTrailingEmptyText && (nBufLen = aFormatCode.getLength()) >= 3)
+ {
+ // Remove a trailing empty text. Earlier this may had been written to
+ // file, like in "General;General" written with elements for
+ // 'General"";General""' (whyever); when reading, empty text was
+ // ignored, which it isn't anymore, so get rid of those.
+ if (aFormatCode[nBufLen-1] == '"' && aFormatCode[nBufLen-2] == '"')
+ aFormatCode.truncate( nBufLen - 2);
+ }
aFormatCode.insert( 0, aConditions.makeStringAndClear() );
OUString sFormat = aFormatCode.makeStringAndClear();
@@ -1631,6 +1650,7 @@ void SvXMLNumFormatContext::AddToCode( std::u16string_view rString )
{
aFormatCode.append( rString );
bHasExtraText = true;
+ bHasTrailingEmptyText = false; // is set by caller again if so
}
void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )