[Libreoffice] problems in number format dialog

Eike Rathke ooo at erack.de
Mon Aug 1 09:29:49 PDT 2011


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
-------------- next part --------------
fdo#38956 related changes in split components repository to support LCID changes

From: Eike Rathke <ooo at 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());
-------------- next part --------------
fdo#38956 related changes in split libs-core repository to support LCID changes

From: Eike Rathke <ooo at 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
-------------- next part --------------
Fix fdo#38956 discarding bracketed prefixes in number formats, such as [RED]

From: Eike Rathke <ooo at 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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/libreoffice/attachments/20110801/85842b37/attachment-0001.pgp>


More information about the LibreOffice mailing list