summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2021-07-07 20:50:28 +0200
committerCaolán McNamara <caolanm@redhat.com>2021-07-08 11:54:00 +0200
commitb92718fe3e9c873dc7d5a3aee66fb2adb780861a (patch)
tree2a70cec84a2539bb4826faff85b95b0d78d786e3 /svl
parent60d35f767781de4b8f1e7b264b12015f655c647d (diff)
Resolves: tdf#122191 BOOLEAN is a keyword, treat it as such
... to not end up with "BOOL"E"AN" instead, which is a date type with an era year and literal strings. This never worked but only was uncovered by commit ce4fc2fc08be8ea2773194e303ed42d2579e93a0 CommitDate: Fri Mar 2 20:27:45 2018 +0100 Resolves: tdf#115351 convert boolean equivalent format codes to proper Boolean if the format also had to be converted between locales. Also preserve boolean equivalent formats during Excel export and try hard to convert back as much as possible if a literal boolean string format is a Boolean equivalent of the target locale. Change-Id: I54f65c276cbf7bb99e960b6d7053c5fa95fbccb6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118591 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins (cherry picked from commit 7a58221f800e215934cbcb2d3907c35b44981611) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118510 Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'svl')
-rw-r--r--svl/source/numbers/zforlist.cxx104
-rw-r--r--svl/source/numbers/zformat.cxx6
-rw-r--r--svl/source/numbers/zforscan.cxx13
-rw-r--r--svl/source/numbers/zforscan.hxx2
4 files changed, 100 insertions, 25 deletions
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index b1885ad4a94a..0a2f699f81ec 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -569,7 +569,8 @@ bool SvNumberFormatter::PutEntry(OUString& rString,
sal_Int32& nCheckPos,
SvNumFormatType& nType,
sal_uInt32& nKey, // format key
- LanguageType eLnge)
+ LanguageType eLnge,
+ bool bReplaceBooleanEquivalent)
{
::osl::MutexGuard aGuard( GetInstanceMutex() );
nKey = 0;
@@ -589,7 +590,8 @@ bool SvNumberFormatter::PutEntry(OUString& rString,
pFormatScanner.get(),
pStringScanner.get(),
nCheckPos,
- eLge));
+ eLge,
+ bReplaceBooleanEquivalent));
if (nCheckPos == 0) // Format ok
{ // Type comparison:
@@ -637,7 +639,8 @@ bool SvNumberFormatter::PutandConvertEntry(OUString& rString,
sal_uInt32& nKey,
LanguageType eLnge,
LanguageType eNewLnge,
- bool bConvertDateOrder )
+ bool bConvertDateOrder,
+ bool bReplaceBooleanEquivalent )
{
::osl::MutexGuard aGuard( GetInstanceMutex() );
bool bRes;
@@ -646,8 +649,43 @@ bool SvNumberFormatter::PutandConvertEntry(OUString& rString,
eNewLnge = IniLnge;
}
pFormatScanner->SetConvertMode(eLnge, eNewLnge, false, bConvertDateOrder);
- bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge);
+ bRes = PutEntry(rString, nCheckPos, nType, nKey, eLnge, bReplaceBooleanEquivalent);
pFormatScanner->SetConvertMode(false);
+
+ if (bReplaceBooleanEquivalent && nType == SvNumFormatType::DEFINED && nCheckPos == 0
+ && nKey != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ // The boolean string formats are always "user defined" without any
+ // other type.
+ const SvNumberformat* pEntry = GetFormatEntry(nKey);
+ if (pEntry && pEntry->GetType() == SvNumFormatType::DEFINED)
+ {
+ // Replace boolean string format with Boolean in target locale, in
+ // case the source strings are the target locale's.
+ const OUString aSaveString = rString;
+ ChangeIntl(eNewLnge);
+ if (pFormatScanner->ReplaceBooleanEquivalent( rString))
+ {
+ const sal_Int32 nSaveCheckPos = nCheckPos;
+ const SvNumFormatType nSaveType = nType;
+ const sal_uInt32 nSaveKey = nKey;
+ const bool bTargetRes = PutEntry(rString, nCheckPos, nType, nKey, eNewLnge, false);
+ if (nCheckPos == 0 && nType == SvNumFormatType::LOGICAL && nKey != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ bRes = bTargetRes;
+ }
+ else
+ {
+ SAL_WARN("svl.numbers", "SvNumberFormatter::PutandConvertEntry: can't scan boolean replacement");
+ // Live with the source boolean string format.
+ rString = aSaveString;
+ nCheckPos = nSaveCheckPos;
+ nType = nSaveType;
+ nKey = nSaveKey;
+ }
+ }
+ }
+ }
return bRes;
}
@@ -838,6 +876,20 @@ void SvNumberFormatter::FillKeywordTableForExcel( NfKeywordTable& rKeywords )
}
+static OUString lcl_buildBooleanStringFormat( SvNumberformat* pEntry )
+{
+ // Build Boolean number format, which needs non-zero and zero subformat
+ // codes with TRUE and FALSE strings.
+ const Color* pColor = nullptr;
+ OUString aFormatStr, aTemp;
+ pEntry->GetOutputString( 1.0, aTemp, &pColor );
+ aFormatStr += "\"" + aTemp + "\";\"" + aTemp + "\";\"";
+ pEntry->GetOutputString( 0.0, aTemp, &pColor );
+ aFormatStr += aTemp + "\"";
+ return aFormatStr;
+}
+
+
OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKeywordTable& rKeywords,
SvNumberFormatter& rTempFormatter ) const
{
@@ -847,14 +899,13 @@ OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKe
{
if (pEntry->GetType() == SvNumFormatType::LOGICAL)
{
- // Build Boolean number format, which needs non-zero and zero
- // subformat codes with TRUE and FALSE strings.
- const Color* pColor = nullptr;
- OUString aTemp;
- const_cast< SvNumberformat* >( pEntry )->GetOutputString( 1.0, aTemp, &pColor );
- aFormatStr += "\"" + aTemp + "\";\"" + aTemp + "\";\"";
- const_cast< SvNumberformat* >( pEntry )->GetOutputString( 0.0, aTemp, &pColor );
- aFormatStr += aTemp + "\"";
+ // Build a source locale dependent string boolean. This is
+ // expected when loading the document in the same locale or if
+ // several locales are used, but not for other system/default
+ // locales. You can't have both. We could force to English for all
+ // locales like below, but Excel would display English strings then
+ // even for the system locale matching this locale. YMMV.
+ aFormatStr = lcl_buildBooleanStringFormat( const_cast< SvNumberformat* >(pEntry));
}
else
{
@@ -871,7 +922,10 @@ OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKe
SvNumFormatType nType = SvNumFormatType::DEFINED;
sal_uInt32 nTempKey;
OUString aTemp( pEntry->GetFormatstring());
- rTempFormatter.PutandConvertEntry( aTemp, nCheckPos, nType, nTempKey, nLang, LANGUAGE_ENGLISH_US, false);
+ /* TODO: do we want bReplaceBooleanEquivalent=true in any case
+ * to write it as English string boolean? */
+ rTempFormatter.PutandConvertEntry( aTemp, nCheckPos, nType, nTempKey, nLang, LANGUAGE_ENGLISH_US,
+ false /*bConvertDateOrder*/, false /*bReplaceBooleanEquivalent*/);
SAL_WARN_IF( nCheckPos != 0, "svl.numbers",
"SvNumberFormatter::GetFormatStringForExcel - format code not convertible");
if (nTempKey != NUMBERFORMAT_ENTRY_NOT_FOUND)
@@ -880,12 +934,24 @@ OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKe
if (pEntry)
{
- // GetLocaleData() returns the current locale's data, so switch
- // before (which doesn't do anything if it was the same locale
- // already).
- rTempFormatter.ChangeIntl( LANGUAGE_ENGLISH_US);
- aFormatStr = pEntry->GetMappedFormatstring( rKeywords, *rTempFormatter.GetLocaleData(), nLang,
- bSystemLanguage);
+ if (pEntry->GetType() == SvNumFormatType::LOGICAL)
+ {
+ // This would be reached if bReplaceBooleanEquivalent was
+ // true and the source format is a string boolean like
+ // >"VRAI";"VRAI";"FAUX"< recognized as real boolean and
+ // properly converted. Then written as
+ // >"TRUE";"TRUE";"FALSE"<
+ aFormatStr = lcl_buildBooleanStringFormat( const_cast< SvNumberformat* >(pEntry));
+ }
+ else
+ {
+ // GetLocaleData() returns the current locale's data, so switch
+ // before (which doesn't do anything if it was the same locale
+ // already).
+ rTempFormatter.ChangeIntl( LANGUAGE_ENGLISH_US);
+ aFormatStr = pEntry->GetMappedFormatstring( rKeywords, *rTempFormatter.GetLocaleData(), nLang,
+ bSystemLanguage);
+ }
}
}
}
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 19ee2134df35..d14bf73841ee 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -722,12 +722,14 @@ SvNumberformat::SvNumberformat(OUString& rString,
ImpSvNumberformatScan* pSc,
ImpSvNumberInputScan* pISc,
sal_Int32& nCheckPos,
- LanguageType& eLan)
+ LanguageType& eLan,
+ bool bReplaceBooleanEquivalent)
: rScan(*pSc)
, bAdditionalBuiltin( false )
, bStarFlag( false )
{
- rScan.ReplaceBooleanEquivalent( rString);
+ if (bReplaceBooleanEquivalent)
+ rScan.ReplaceBooleanEquivalent( rString);
OUStringBuffer sBuff(rString);
diff --git a/svl/source/numbers/zforscan.cxx b/svl/source/numbers/zforscan.cxx
index c3f97d89c949..f6cdfdb5b339 100644
--- a/svl/source/numbers/zforscan.cxx
+++ b/svl/source/numbers/zforscan.cxx
@@ -85,12 +85,12 @@ const NfKeywordTable ImpSvNumberformatScan::sEnglishKeyword =
// used with Thai locale and converted to [NatNum1], only
// exception as lowercase
"CCC", // NF_KEY_CCC Currency abbreviation
+ "BOOLEAN", // NF_KEY_BOOLEAN boolean
"GENERAL", // NF_KEY_GENERAL General / Standard
// Reserved words translated and color names follow:
"TRUE", // NF_KEY_TRUE boolean true
"FALSE", // NF_KEY_FALSE boolean false
- "BOOLEAN", // NF_KEY_BOOLEAN boolean
"COLOR", // NF_KEY_COLOR color
// colours
"BLACK", // NF_KEY_BLACK
@@ -1353,7 +1353,10 @@ sal_Int32 ImpSvNumberformatScan::ScanType()
case NF_KEY_CCC: // CCC
eNewType = SvNumFormatType::CURRENCY;
break;
- case NF_KEY_GENERAL: // Standard
+ case NF_KEY_BOOLEAN: // BOOLEAN
+ eNewType = SvNumFormatType::LOGICAL;
+ break;
+ case NF_KEY_GENERAL: // General
eNewType = SvNumFormatType::NUMBER;
bHaveGeneral = true;
break;
@@ -3274,14 +3277,18 @@ void ImpSvNumberformatScan::CopyInfo(ImpSvNumberformatInfo* pInfo, sal_uInt16 nC
pInfo->nCntExp = nCntExp;
}
-void ImpSvNumberformatScan::ReplaceBooleanEquivalent( OUString& rString )
+bool ImpSvNumberformatScan::ReplaceBooleanEquivalent( OUString& rString )
{
InitKeywords();
/* TODO: compare case insensitive? Or rather leave as is and case not
* matching indicates user supplied on purpose? Written to file / generated
* was always uppercase. */
if (rString == sBooleanEquivalent1 || rString == sBooleanEquivalent2)
+ {
rString = GetKeywords()[NF_KEY_BOOLEAN];
+ return true;
+ }
+ return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/numbers/zforscan.hxx b/svl/source/numbers/zforscan.hxx
index 95f5a0b9296f..3f0cea902991 100644
--- a/svl/source/numbers/zforscan.hxx
+++ b/svl/source/numbers/zforscan.hxx
@@ -146,7 +146,7 @@ public:
}
/// Replace Boolean equivalent format codes with proper Boolean format.
- void ReplaceBooleanEquivalent( OUString& rString );
+ bool ReplaceBooleanEquivalent( OUString& rString );
void SetConvertMode(LanguageType eTmpLge, LanguageType eNewLge,
bool bSystemToSystem, bool bConvertDateOrder)