editeng/source/editeng/editdoc.cxx | 2 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 8 files changed, 107 insertions(+), 29 deletions(-)
New commits: commit b92718fe3e9c873dc7d5a3aee66fb2adb780861a Author: Eike Rathke <er...@redhat.com> AuthorDate: Wed Jul 7 20:50:28 2021 +0200 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu Jul 8 11:54:00 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 <er...@redhat.com> Tested-by: Jenkins (cherry picked from commit 7a58221f800e215934cbcb2d3907c35b44981611) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118510 Reviewed-by: Caolán McNamara <caol...@redhat.com> 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 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) commit 60d35f767781de4b8f1e7b264b12015f655c647d Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue Jul 6 18:51:38 2021 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Jul 8 11:53:49 2021 +0200 tdf#132740 don't broadcast if modified status has not changed take 10% of the time off Change-Id: I75c8d5e1297de342df711d15260073db59946116 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118531 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> (cherry picked from commit 73c9ef661d9ef6237d3fd3c259fd040a545b44cf) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118508 diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index 2a7f43032245..270b17923390 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -2199,6 +2199,8 @@ void EditDoc::ClearSpellErrors() void EditDoc::SetModified( bool b ) { + if (bModified == b) + return; bModified = b; if ( bModified ) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits