Hi Samphan, On Monday, 2011-08-01 11:54:31 +0700, Samphan Raruenrom wrote:
We're reading this discussion and patches.
Great, could you please apply the attached patches and check if that suits the needs of the Thai community? Thanks Eike -- PGP/OpenPGP/GnuPG encrypted mail preferred in all private communication. Key ID: 0x293C05FD - 997A 4C60 CE41 0149 0DB3 9E96 2F1A D073 293C 05FD
fdo#38956 related changes in split components repository to support LCID changes From: Eike Rathke <ooo@erack.de> --- cui/source/tabpages/numfmt.cxx | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx index 03fb706..b92831e 100644 --- a/cui/source/tabpages/numfmt.cxx +++ b/cui/source/tabpages/numfmt.cxx @@ -1394,6 +1394,10 @@ IMPL_LINK( SvxNumberFormatTabPage, ClickHdl_Impl, ImageButton*, pIB) if ( !nErrPos ) // Syntax ok? { + // May be sorted under a different locale if LCID was parsed. + if (bAdded) + aLbLanguage.SelectLanguage( pNumFmtShell->GetCurLanguage() ); + if(nCatLbSelPos==CAT_CURRENCY) { aLbCurrency.SelectEntryPos((sal_uInt16)pNumFmtShell->GetCurrencySymbol());
fdo#38956 related changes in split libs-core repository to support LCID changes From: Eike Rathke <ooo@erack.de> --- svx/source/items/numfmtsh.cxx | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/svx/source/items/numfmtsh.cxx b/svx/source/items/numfmtsh.cxx index 837fdea..9f70817 100644 --- a/svx/source/items/numfmtsh.cxx +++ b/svx/source/items/numfmtsh.cxx @@ -289,6 +289,20 @@ sal_Bool SvxNumberFormatShell::AddFormat( String& rFormat, xub_StrLen& rErrPos, bInserted = pFormatter->PutEntry( rFormat, rErrPos, nCurCategory, nAddKey, eCurLanguage ); + if (bInserted) + { + // May be sorted under a different locale if LCID was parsed. + const SvNumberformat* pEntry = pFormatter->GetEntry( nAddKey); + if (pEntry) + { + LanguageType nLang = pEntry->GetLanguage(); + if (eCurLanguage != nLang) + { + // Current language's list would not show entry, adapt. + eCurLanguage = nLang; + } + } + } } if ( bInserted ) // eingefuegt
Fix fdo#38956 discarding bracketed prefixes in number formats, such as [RED] From: Eike Rathke <ooo@erack.de> * Fixed discarding of prefixes. * Fixed the broken handling of Thai calendar and numerals speciality. * Added bits to actually display a format with embedded LCID in the dialog. --- svl/inc/svl/zforlist.hxx | 16 ++++ svl/source/numbers/zforlist.cxx | 2 + svl/source/numbers/zformat.cxx | 139 ++++++++++++++++++++++++++++++--------- 3 files changed, 125 insertions(+), 32 deletions(-) diff --git a/svl/inc/svl/zforlist.hxx b/svl/inc/svl/zforlist.hxx index eef1904..d1519ea 100644 --- a/svl/inc/svl/zforlist.hxx +++ b/svl/inc/svl/zforlist.hxx @@ -42,6 +42,7 @@ #include <svl/nfkeytab.hxx> #include <map> +#include <set> class Date; class SvStream; @@ -225,6 +226,8 @@ typedef Table SvNumberFormatterIndexTable; typedef ::std::map< sal_uInt32, sal_uInt32 > SvNumberFormatterMergeMap; +typedef ::std::set< LanguageType > NfInstalledLocales; + /** Language/country dependent currency entries */ @@ -343,6 +346,9 @@ public: */ static const sal_uInt16 INPUTSTRING_PRECISION; + /** THE set of installed locales. */ + static NfInstalledLocales theInstalledLocales; + /// Preferred ctor with service manager and language/country enum SvNumberFormatter( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMgr, @@ -801,6 +807,16 @@ public: /// Skip a NumberFormatter in stream, Chart needs this static void SkipNumberFormatterInStream( SvStream& ); + /** Check if a specific locale has supported locale data. */ + static bool IsLocaleInstalled( LanguageType eLang ) + { + // The set is initialized as a side effect of the currency table + // created, make sure that exists, which usually is the case unless a + // SvNumberFormatter was never instanciated. + GetTheCurrencyTable(); + return theInstalledLocales.find( eLang) != theInstalledLocales.end(); + } + private: ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager; diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx index bc0df6a..a4a0c82 100644 --- a/svl/source/numbers/zforlist.cxx +++ b/svl/source/numbers/zforlist.cxx @@ -195,6 +195,7 @@ SV_IMPL_PTRARR( NfWSStringsDtor, String* ); const sal_uInt16 SvNumberFormatter::UNLIMITED_PRECISION = ::std::numeric_limits<sal_uInt16>::max(); const sal_uInt16 SvNumberFormatter::INPUTSTRING_PRECISION = ::std::numeric_limits<sal_uInt16>::max()-1; +NfInstalledLocales SvNumberFormatter::theInstalledLocales; SvNumberFormatter::SvNumberFormatter( const Reference< XMultiServiceFactory >& xSMgr, @@ -3633,6 +3634,7 @@ void SvNumberFormatter::ImpInitCurrencyTable() { LanguageType eLang = MsLangId::convertLocaleToLanguage( pLocales[nLocale]); + theInstalledLocales.insert( eLang); pLocaleData->setLocale( pLocales[nLocale] ); Sequence< Currency2 > aCurrSeq = pLocaleData->getAllCurrencies(); sal_Int32 nCurrencyCount = aCurrSeq.getLength(); diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx index dbe5ced..80b9b14 100644 --- a/svl/source/numbers/zformat.cxx +++ b/svl/source/numbers/zformat.cxx @@ -650,6 +650,7 @@ SvNumberformat::SvNumberformat(String& rString, if (rScan.GetConvertMode()) (rScan.GetNumberformatter())->ChangeIntl(rScan.GetTmpLnge()); + bool bInsertCalendar = false; // if a calendar results from parsing LCID String sStr; nPosOld = nPos; // Start position of substring // first get bracketed prefixes; e.g. conditions, color @@ -709,6 +710,7 @@ SvNumberformat::SvNumberformat(String& rString, } else if ( lcl_SvNumberformat_IsBracketedPrefix( eSymbolType ) ) { + String sSymbol( sStr); switch ( eSymbolType ) { case BRACKET_SYMBOLTYPE_COLOR : @@ -793,7 +795,11 @@ SvNumberformat::SvNumberformat(String& rString, break; case BRACKET_SYMBOLTYPE_LOCALE : { - if ( NumFor[nIndex].GetNatNum().GetLang() != LANGUAGE_DONTKNOW ) + if ( NumFor[nIndex].GetNatNum().GetLang() != LANGUAGE_DONTKNOW || + rString.GetChar(nPos-1) != ']' ) + // Check also for ']' to avoid pulling in + // locale data for the preview string for not + // yet completed LCIDs in the dialog. { bCancel = sal_True; // break for nCheckPos = nPosOld; @@ -801,17 +807,81 @@ SvNumberformat::SvNumberformat(String& rString, else { xub_StrLen nTmp = 2; - maLocale = ImpGetLocaleType( sStr, nTmp ); - if (maLocale.meLanguage == LANGUAGE_DONTKNOW) + LocaleType aTmpLocale( ImpGetLocaleType( sStr, nTmp)); + if (aTmpLocale.meLanguage == LANGUAGE_DONTKNOW) { bCancel = sal_True; // break for nCheckPos = nPosOld; } - else if (maLocale.meLanguage != 0) + else { + // Only the first sub format's locale will be + // used as the format's overall locale. + // Sorts this also under the corresponding + // locale for the dialog. + // If we don't support the locale this would + // result in an unknown (empty) language + // listbox entry and the user would never see + // this format. + if (nIndex == 0 && (aTmpLocale.meLanguage == 0 || + SvNumberFormatter::IsLocaleInstalled( aTmpLocale.meLanguage))) + { + maLocale = aTmpLocale; + eLan = aTmpLocale.meLanguage; // return to caller + /* TODO: fiddle with scanner to make this + * known? */ + } sStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM("$-") ); - sStr = sStr + maLocale.generateCode(); - NumFor[nIndex].SetNatNumLang(maLocale.meLanguage); + sStr += String( aTmpLocale.generateCode()); + NumFor[nIndex].SetNatNumLang( MsLangId::getRealLanguage( aTmpLocale.meLanguage)); + + // "$-NNCCLLLL" Numerals and Calendar + if (sSymbol.Len() > 6) + { + /* TODO: this could be enhanced to allow + * other possible locale dependent + * calendars and numerals. BUT only if our + * locale data allows it! For LCID numerals + * and calendars see + * http://office.microsoft.com/en-us/excel/HA010346351033.aspx + * */ + if (MsLangId::getRealLanguage( aTmpLocale.meLanguage) == LANGUAGE_THAI) + { + // Numeral shape code "D" = Thai digits. + if (aTmpLocale.mnNumeralShape == 0xD) + rString.InsertAscii( "[NatNum1]", nPos); + + // Calendar type code "07" = Thai + // Buddhist calendar, insert this after + // all prefixes have been consumed as + // it is actually a format modifier and + // not a prefix. + if (aTmpLocale.mnCalendarType == 0x07) + { + // Currently calendars are tied to + // the locale of the entire number + // format, e.g. [~buddhist] in + // en_US doesn't work. + // => Having different locales in + // sub formats does not work! + /* TODO: calendars could be tied to + * a sub format's NatNum info + * instead, or even better be + * available for any locale. Needs + * a different implementation of + * GetCal() and locale data + * calendars. */ + // If this is not Thai yet, make it + // so. + if (MsLangId::getRealLanguage( maLocale.meLanguage) != LANGUAGE_THAI) + { + maLocale = aTmpLocale; + eLan = maLocale.meLanguage = LANGUAGE_THAI; + } + bInsertCalendar = true; + } + } + } } } } @@ -819,19 +889,24 @@ SvNumberformat::SvNumberformat(String& rString, } if ( !bCancel ) { - rString.Erase(nPosOld,nPos-nPosOld); - if (maLocale.meLanguage != 0) - { - rString.Insert(sStr,nPosOld); - nPos = nPosOld + sStr.Len(); - rString.Insert(']', nPos); - rString.Insert('[', nPosOld); - nPos += 2; - nPosOld = nPos; // position before string - } + if (sStr == sSymbol) + nPosOld = nPos; else { - nPos = nPosOld; // Excel LCID removed + rString.Erase(nPosOld,nPos-nPosOld); + if (sStr.Len()) + { + rString.Insert(sStr,nPosOld); + nPos = nPosOld + sStr.Len(); + rString.Insert(']', nPos); + rString.Insert('[', nPosOld); + nPos += 2; + nPosOld = nPos; // position before string + } + else + { + nPos = nPosOld; // prefix removed for whatever reason + } } } } @@ -851,6 +926,11 @@ SvNumberformat::SvNumberformat(String& rString, } else { + /* TODO: if we generalized LCID parsing above this would + * need to support other calendars as well. */ + if (bInsertCalendar) + sStr.InsertAscii( "[~buddhist]", 0); + xub_StrLen nStrPos = pSc->ScanFormat( sStr, aComment ); sal_uInt16 nAnz = pSc->GetAnzResStrings(); if (nAnz == 0) // error @@ -1130,7 +1210,8 @@ OUString SvNumberformat::LocaleType::generateCode() const for (sal_uInt8 i = 0; i < 2; ++i) { sal_uInt8 n = (nVal & 0xF0) >> 4; - aBuf.append(toUniChar(n)); + if (n || aBuf.getLength()) + aBuf.append(toUniChar(n)); nVal = nVal << 4; } } @@ -1141,7 +1222,8 @@ OUString SvNumberformat::LocaleType::generateCode() const for (sal_uInt8 i = 0; i < 2; ++i) { sal_uInt8 n = (nVal & 0xF0) >> 4; - aBuf.append(toUniChar(n)); + if (n || aBuf.getLength()) + aBuf.append(toUniChar(n)); nVal = nVal << 4; } } @@ -1151,7 +1233,9 @@ OUString SvNumberformat::LocaleType::generateCode() const for (sal_uInt8 i = 0; i < 4; ++i) { sal_uInt8 n = static_cast<sal_uInt8>((n16 & 0xF000) >> 12); - aBuf.append(toUniChar(n)); + // Omit leading zeros for consistency. + if (n || aBuf.getLength() || i == 3) + aBuf.append(toUniChar(n)); n16 = n16 << 4; } @@ -1183,8 +1267,9 @@ SvNumberformat::LocaleType SvNumberformat::ImpGetLocaleType( { sal_uInt32 nNum = 0; sal_Unicode cToken = 0; + xub_StrLen nStart = nPos; xub_StrLen nLen = rString.Len(); - while ( nPos < nLen && ((cToken = rString.GetChar(nPos)) != ']') ) + while ( nPos < nLen && (nPos - nStart < 8) && ((cToken = rString.GetChar(nPos)) != ']') ) { if ( '0' <= cToken && cToken <= '9' ) { @@ -1206,7 +1291,7 @@ SvNumberformat::LocaleType SvNumberformat::ImpGetLocaleType( ++nPos; } - return (nNum && (cToken == ']' || nPos == nLen)) ? LocaleType(nNum) : LocaleType(); + return (cToken == ']' || nPos == nLen) ? LocaleType(nNum) : LocaleType(); } short SvNumberformat::ImpNextSymbol(String& rString, @@ -1290,16 +1375,6 @@ short SvNumberformat::ImpNextSymbol(String& rString, { if ( rString.GetChar(nPos) == '-' ) { // [$-xxx] locale - if ( rString.GetChar(nPos+2) == '0' && rString.GetChar(nPos+3) == '7' ) // calendar type code "07" = Thai - { - rString.InsertAscii( "[~buddhist]", nPos+9 ); - nLen += 11; - } - if ( rString.GetChar(nPos+1) == 'D' ) // numeral shape code "D" = Thai digits - { - rString.InsertAscii( "[NatNum1]", nPos+9 ); - nLen += 9; - } sSymbol.EraseAllChars('['); eSymbolType = BRACKET_SYMBOLTYPE_LOCALE; eState = SsGetPrefix;
Attachment:
pgpHr3fafkCpb.pgp
Description: PGP signature