[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