[Libreoffice-commits] core.git: include/svl svl/source
Eike Rathke (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 7 22:14:50 UTC 2021
include/svl/nfkeytab.hxx | 2
include/svl/zforlist.hxx | 4 -
include/svl/zformat.hxx | 3 -
svl/source/numbers/zforlist.cxx | 104 ++++++++++++++++++++++++++++++++--------
svl/source/numbers/zformat.cxx | 6 +-
svl/source/numbers/zforscan.cxx | 13 +++--
svl/source/numbers/zforscan.hxx | 2
7 files changed, 105 insertions(+), 29 deletions(-)
New commits:
commit 7a58221f800e215934cbcb2d3907c35b44981611
Author: Eike Rathke <erack at redhat.com>
AuthorDate: Wed Jul 7 20:50:28 2021 +0200
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Thu Jul 8 00:14:08 2021 +0200
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 at redhat.com>
Tested-by: Jenkins
diff --git a/include/svl/nfkeytab.hxx b/include/svl/nfkeytab.hxx
index fe1e3bb69ec5..3b8140498128 100644
--- a/include/svl/nfkeytab.hxx
+++ b/include/svl/nfkeytab.hxx
@@ -71,13 +71,13 @@ enum NfKeywordIndex
NF_KEY_WW, // week of year, as of version 8, 19.06.98
NF_KEY_THAI_T, // Thai T modifier, speciality of Thai Excel, only used with Thai locale and converted to [NatNum1]
NF_KEY_CCC, // currency bank symbol (old version)
+ NF_KEY_BOOLEAN, // boolean
NF_KEY_GENERAL, // General / Standard
NF_KEY_LASTKEYWORD = NF_KEY_GENERAL,
// Reserved words translated and color names follow:
NF_KEY_TRUE, // boolean true
NF_KEY_FALSE, // boolean false
- NF_KEY_BOOLEAN, // boolean
NF_KEY_COLOR, // color
NF_KEY_FIRSTCOLOR,
NF_KEY_BLACK = NF_KEY_FIRSTCOLOR, // you do know colors, don't you?
diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx
index 7a8703873460..c3d82d7b109a 100644
--- a/include/svl/zforlist.hxx
+++ b/include/svl/zforlist.hxx
@@ -473,7 +473,7 @@ public:
nKey contains the index key of the format.
*/
bool PutEntry( OUString& rString, sal_Int32& nCheckPos, SvNumFormatType& nType, sal_uInt32& nKey,
- LanguageType eLnge = LANGUAGE_DONTKNOW );
+ LanguageType eLnge = LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent = true );
/** Same as <method>PutEntry</method> but the format code string is
considered to be of language/country eLnge and is converted to
@@ -481,7 +481,7 @@ public:
bool PutandConvertEntry( OUString& rString, sal_Int32& nCheckPos,
SvNumFormatType& nType, sal_uInt32& nKey,
LanguageType eLnge, LanguageType eNewLnge,
- bool bConvertDateOrder );
+ bool bConvertDateOrder, bool bReplaceBooleanEquivalent = true );
/** Same as <method>PutandConvertEntry</method> but the format code string
is considered to be of the System language/country eLnge and is
diff --git a/include/svl/zformat.hxx b/include/svl/zformat.hxx
index 543c5967804c..976488257218 100644
--- a/include/svl/zformat.hxx
+++ b/include/svl/zformat.hxx
@@ -171,7 +171,8 @@ public:
ImpSvNumberformatScan* pSc,
ImpSvNumberInputScan* pISc,
sal_Int32& nCheckPos,
- LanguageType& eLan );
+ LanguageType& eLan,
+ bool bReplaceBooleanEquivalent = true );
// Copy ctor
SvNumberformat( SvNumberformat const & rFormat );
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 2c43d22087c9..6cedc976c74c 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)
More information about the Libreoffice-commits
mailing list