LCOV - code coverage report
Current view: top level - xmloff/source/style - xmlnumfi.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 672 842 79.8 %
Date: 2014-11-03 Functions: 60 76 78.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <comphelper/string.hxx>
      21             : #include <unotools/syslocale.hxx>
      22             : 
      23             : #include <svl/zforlist.hxx>
      24             : 
      25             : #include <svl/zformat.hxx>
      26             : #include <svl/numuno.hxx>
      27             : #include <rtl/math.hxx>
      28             : #include <i18nlangtag/languagetag.hxx>
      29             : #include <tools/color.hxx>
      30             : #include <tools/debug.hxx>
      31             : #include <rtl/ustrbuf.hxx>
      32             : 
      33             : #include <sax/tools/converter.hxx>
      34             : 
      35             : #include <xmloff/xmlnumfi.hxx>
      36             : #include <xmloff/xmltkmap.hxx>
      37             : #include <xmloff/xmlnmspe.hxx>
      38             : #include <xmloff/xmlictxt.hxx>
      39             : #include <xmloff/xmlimp.hxx>
      40             : #include <xmloff/xmluconv.hxx>
      41             : #include <xmloff/nmspmap.hxx>
      42             : #include <xmloff/families.hxx>
      43             : #include <xmloff/xmltoken.hxx>
      44             : #include <xmloff/languagetagodf.hxx>
      45             : 
      46             : #include <boost/ptr_container/ptr_vector.hpp>
      47             : #include <boost/ptr_container/ptr_set.hpp>
      48             : 
      49             : using namespace ::com::sun::star;
      50             : using namespace ::xmloff::token;
      51             : 
      52        3630 : struct SvXMLNumFmtEntry
      53             : {
      54             :     OUString   aName;
      55             :     sal_uInt32  nKey;
      56             :     bool        bRemoveAfterUse;
      57             : 
      58        3630 :     SvXMLNumFmtEntry( const OUString& rN, sal_uInt32 nK, bool bR ) :
      59        3630 :         aName(rN), nKey(nK), bRemoveAfterUse(bR) {}
      60             : };
      61             : 
      62             : typedef ::boost::ptr_vector<SvXMLNumFmtEntry> SvXMLNumFmtEntryArr;
      63             : 
      64           0 : struct SvXMLEmbeddedElement
      65             : {
      66             :     sal_Int32       nFormatPos;
      67             :     OUString   aText;
      68             : 
      69           0 :     SvXMLEmbeddedElement( sal_Int32 nFP, const OUString& rT ) :
      70           0 :         nFormatPos(nFP), aText(rT) {}
      71             : 
      72           0 :     bool operator < ( const SvXMLEmbeddedElement& r ) const { return nFormatPos <  r.nFormatPos; }
      73             : };
      74             : 
      75             : typedef boost::ptr_set<SvXMLEmbeddedElement> SvXMLEmbeddedElementArr;
      76             : 
      77             : class SvXMLNumImpData
      78             : {
      79             :     SvNumberFormatter*  pFormatter;
      80             :     SvXMLTokenMap*      pStylesElemTokenMap;
      81             :     SvXMLTokenMap*      pStyleElemTokenMap;
      82             :     SvXMLTokenMap*      pStyleAttrTokenMap;
      83             :     SvXMLTokenMap*      pStyleElemAttrTokenMap;
      84             :     LocaleDataWrapper*  pLocaleData;
      85             :     SvXMLNumFmtEntryArr aNameEntries;
      86             : 
      87             :     uno::Reference< uno::XComponentContext > m_xContext;
      88             : 
      89             : public:
      90             :     SvXMLNumImpData(
      91             :         SvNumberFormatter* pFmt,
      92             :         const uno::Reference<uno::XComponentContext>& rxContext );
      93             :     ~SvXMLNumImpData();
      94             : 
      95        9934 :     SvNumberFormatter*      GetNumberFormatter() const  { return pFormatter; }
      96             :     const SvXMLTokenMap&    GetStylesElemTokenMap();
      97             :     const SvXMLTokenMap&    GetStyleElemTokenMap();
      98             :     const SvXMLTokenMap&    GetStyleAttrTokenMap();
      99             :     const SvXMLTokenMap&    GetStyleElemAttrTokenMap();
     100             :     const LocaleDataWrapper&    GetLocaleData( LanguageType nLang );
     101             :     sal_uInt32              GetKeyForName( const OUString& rName );
     102             :     void                    AddKey( sal_uInt32 nKey, const OUString& rName, bool bRemoveAfterUse );
     103             :     void                    SetUsed( sal_uInt32 nKey );
     104             :     void                    RemoveVolatileFormats();
     105             : };
     106             : 
     107        9524 : struct SvXMLNumberInfo
     108             : {
     109             :     sal_Int32   nDecimals;
     110             :     sal_Int32   nInteger;
     111             :     sal_Int32   nExpDigits;
     112             :     sal_Int32   nNumerDigits;
     113             :     sal_Int32   nDenomDigits;
     114             :     sal_Int32   nFracDenominator;
     115             :     bool        bGrouping;
     116             :     bool        bDecReplace;
     117             :     bool        bVarDecimals;
     118             :     double      fDisplayFactor;
     119             :     SvXMLEmbeddedElementArr aEmbeddedElements;
     120             : 
     121        9524 :     SvXMLNumberInfo()
     122        9524 :     {
     123        9524 :         nDecimals = nInteger = nExpDigits = nNumerDigits = nDenomDigits = nFracDenominator = -1;
     124        9524 :         bGrouping = bDecReplace = bVarDecimals = false;
     125        9524 :         fDisplayFactor = 1.0;
     126        9524 :     }
     127             : };
     128             : 
     129             : class SvXMLNumFmtElementContext : public SvXMLImportContext
     130             : {
     131             :     SvXMLNumFormatContext&  rParent;
     132             :     sal_uInt16              nType;
     133             :     OUStringBuffer          aContent;
     134             :     SvXMLNumberInfo         aNumInfo;
     135             :     LanguageType            nElementLang;
     136             :     bool                    bLong;
     137             :     bool                    bTextual;
     138             :     OUString                sCalendar;
     139             : 
     140             : public:
     141             :                 SvXMLNumFmtElementContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
     142             :                                     const OUString& rLName,
     143             :                                     SvXMLNumFormatContext& rParentContext, sal_uInt16 nNewType,
     144             :                                     const ::com::sun::star::uno::Reference<
     145             :                                         ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
     146             :     virtual     ~SvXMLNumFmtElementContext();
     147             : 
     148             :     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
     149             :                                     const OUString& rLocalName,
     150             :                                     const ::com::sun::star::uno::Reference<
     151             :                                           ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) SAL_OVERRIDE;
     152             :     virtual void Characters( const OUString& rChars ) SAL_OVERRIDE;
     153             :     virtual void EndElement() SAL_OVERRIDE;
     154             : 
     155             :     void    AddEmbeddedElement( sal_Int32 nFormatPos, const OUString& rContent );
     156             : };
     157             : 
     158             : class SvXMLNumFmtEmbeddedTextContext : public SvXMLImportContext
     159             : {
     160             :     SvXMLNumFmtElementContext&  rParent;
     161             :     OUStringBuffer         aContent;
     162             :     sal_Int32                   nTextPosition;
     163             : 
     164             : public:
     165             :                 SvXMLNumFmtEmbeddedTextContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
     166             :                                     const OUString& rLName,
     167             :                                     SvXMLNumFmtElementContext& rParentContext,
     168             :                                     const ::com::sun::star::uno::Reference<
     169             :                                         ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
     170             :     virtual     ~SvXMLNumFmtEmbeddedTextContext();
     171             : 
     172             :     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
     173             :                                     const OUString& rLocalName,
     174             :                                     const ::com::sun::star::uno::Reference<
     175             :                                           ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) SAL_OVERRIDE;
     176             :     virtual void Characters( const OUString& rChars ) SAL_OVERRIDE;
     177             :     virtual void EndElement() SAL_OVERRIDE;
     178             : };
     179             : 
     180             : class SvXMLNumFmtMapContext : public SvXMLImportContext
     181             : {
     182             :     SvXMLNumFormatContext&  rParent;
     183             :     OUString           sCondition;
     184             :     OUString           sName;
     185             : 
     186             : public:
     187             :                 SvXMLNumFmtMapContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
     188             :                                     const OUString& rLName,
     189             :                                     SvXMLNumFormatContext& rParentContext,
     190             :                                     const ::com::sun::star::uno::Reference<
     191             :                                         ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
     192             :     virtual     ~SvXMLNumFmtMapContext();
     193             : 
     194             :     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
     195             :                                     const OUString& rLocalName,
     196             :                                     const ::com::sun::star::uno::Reference<
     197             :                                           ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) SAL_OVERRIDE;
     198             :     virtual void Characters( const OUString& rChars ) SAL_OVERRIDE;
     199             :     virtual void EndElement() SAL_OVERRIDE;
     200             : };
     201             : 
     202             : class SvXMLNumFmtPropContext : public SvXMLImportContext
     203             : {
     204             :     SvXMLNumFormatContext&  rParent;
     205             :         sal_Int32                               m_nColor;
     206             :     bool                    bColSet;
     207             : 
     208             : public:
     209             :                 SvXMLNumFmtPropContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
     210             :                                     const OUString& rLName,
     211             :                                     SvXMLNumFormatContext& rParentContext,
     212             :                                     const ::com::sun::star::uno::Reference<
     213             :                                         ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
     214             :     virtual     ~SvXMLNumFmtPropContext();
     215             : 
     216             :     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
     217             :                                     const OUString& rLocalName,
     218             :                                     const ::com::sun::star::uno::Reference<
     219             :                                           ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) SAL_OVERRIDE;
     220             :     virtual void Characters( const OUString& rChars ) SAL_OVERRIDE;
     221             :     virtual void EndElement() SAL_OVERRIDE;
     222             : };
     223             : 
     224             : enum SvXMLStyleTokens
     225             : {
     226             :     XML_TOK_STYLE_TEXT,
     227             :     XML_TOK_STYLE_FILL_CHARACTER,
     228             :     XML_TOK_STYLE_NUMBER,
     229             :     XML_TOK_STYLE_SCIENTIFIC_NUMBER,
     230             :     XML_TOK_STYLE_FRACTION,
     231             :     XML_TOK_STYLE_CURRENCY_SYMBOL,
     232             :     XML_TOK_STYLE_DAY,
     233             :     XML_TOK_STYLE_MONTH,
     234             :     XML_TOK_STYLE_YEAR,
     235             :     XML_TOK_STYLE_ERA,
     236             :     XML_TOK_STYLE_DAY_OF_WEEK,
     237             :     XML_TOK_STYLE_WEEK_OF_YEAR,
     238             :     XML_TOK_STYLE_QUARTER,
     239             :     XML_TOK_STYLE_HOURS,
     240             :     XML_TOK_STYLE_AM_PM,
     241             :     XML_TOK_STYLE_MINUTES,
     242             :     XML_TOK_STYLE_SECONDS,
     243             :     XML_TOK_STYLE_BOOLEAN,
     244             :     XML_TOK_STYLE_TEXT_CONTENT,
     245             :     XML_TOK_STYLE_PROPERTIES,
     246             :     XML_TOK_STYLE_MAP
     247             : };
     248             : 
     249             : enum SvXMLStyleAttrTokens
     250             : {
     251             :     XML_TOK_STYLE_ATTR_NAME,
     252             :     XML_TOK_STYLE_ATTR_RFC_LANGUAGE_TAG,
     253             :     XML_TOK_STYLE_ATTR_LANGUAGE,
     254             :     XML_TOK_STYLE_ATTR_SCRIPT,
     255             :     XML_TOK_STYLE_ATTR_COUNTRY,
     256             :     XML_TOK_STYLE_ATTR_TITLE,
     257             :     XML_TOK_STYLE_ATTR_AUTOMATIC_ORDER,
     258             :     XML_TOK_STYLE_ATTR_FORMAT_SOURCE,
     259             :     XML_TOK_STYLE_ATTR_TRUNCATE_ON_OVERFLOW,
     260             :     XML_TOK_STYLE_ATTR_VOLATILE,
     261             :     XML_TOK_STYLE_ATTR_TRANSL_FORMAT,
     262             :     XML_TOK_STYLE_ATTR_TRANSL_RFC_LANGUAGE_TAG,
     263             :     XML_TOK_STYLE_ATTR_TRANSL_LANGUAGE,
     264             :     XML_TOK_STYLE_ATTR_TRANSL_SCRIPT,
     265             :     XML_TOK_STYLE_ATTR_TRANSL_COUNTRY,
     266             :     XML_TOK_STYLE_ATTR_TRANSL_STYLE
     267             : };
     268             : 
     269             : enum SvXMLStyleElemAttrTokens
     270             : {
     271             :     XML_TOK_ELEM_ATTR_DECIMAL_PLACES,
     272             :     XML_TOK_ELEM_ATTR_MIN_INTEGER_DIGITS,
     273             :     XML_TOK_ELEM_ATTR_GROUPING,
     274             :     XML_TOK_ELEM_ATTR_DISPLAY_FACTOR,
     275             :     XML_TOK_ELEM_ATTR_DECIMAL_REPLACEMENT,
     276             :     XML_TOK_ELEM_ATTR_DENOMINATOR_VALUE,
     277             :     XML_TOK_ELEM_ATTR_MIN_EXPONENT_DIGITS,
     278             :     XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS,
     279             :     XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS,
     280             :     XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG,
     281             :     XML_TOK_ELEM_ATTR_LANGUAGE,
     282             :     XML_TOK_ELEM_ATTR_SCRIPT,
     283             :     XML_TOK_ELEM_ATTR_COUNTRY,
     284             :     XML_TOK_ELEM_ATTR_STYLE,
     285             :     XML_TOK_ELEM_ATTR_TEXTUAL,
     286             :     XML_TOK_ELEM_ATTR_CALENDAR
     287             : };
     288             : 
     289             : 
     290             : //  standard colors
     291             : 
     292             : 
     293             : #define XML_NUMF_COLORCOUNT     10
     294             : 
     295             : static const ColorData aNumFmtStdColors[XML_NUMF_COLORCOUNT] =
     296             : {
     297             :     COL_BLACK,
     298             :     COL_LIGHTBLUE,
     299             :     COL_LIGHTGREEN,
     300             :     COL_LIGHTCYAN,
     301             :     COL_LIGHTRED,
     302             :     COL_LIGHTMAGENTA,
     303             :     COL_BROWN,
     304             :     COL_GRAY,
     305             :     COL_YELLOW,
     306             :     COL_WHITE
     307             : };
     308             : 
     309             : 
     310             : //  token maps
     311             : 
     312             : 
     313             : // maps for SvXMLUnitConverter::convertEnum
     314             : 
     315             : static const SvXMLEnumMapEntry aStyleValueMap[] =
     316             : {
     317             :     { XML_SHORT,            sal_False   },
     318             :     { XML_LONG,             sal_True    },
     319             :     { XML_TOKEN_INVALID,    0 }
     320             : };
     321             : 
     322             : static const SvXMLEnumMapEntry aFormatSourceMap[] =
     323             : {
     324             :     { XML_FIXED,            sal_False },
     325             :     { XML_LANGUAGE,         sal_True  },
     326             :     { XML_TOKEN_INVALID,    0 }
     327             : };
     328             : 
     329             : struct SvXMLDefaultDateFormat
     330             : {
     331             :     NfIndexTableOffset          eFormat;
     332             :     SvXMLDateElementAttributes  eDOW;
     333             :     SvXMLDateElementAttributes  eDay;
     334             :     SvXMLDateElementAttributes  eMonth;
     335             :     SvXMLDateElementAttributes  eYear;
     336             :     SvXMLDateElementAttributes  eHours;
     337             :     SvXMLDateElementAttributes  eMins;
     338             :     SvXMLDateElementAttributes  eSecs;
     339             :     bool                        bSystem;
     340             : };
     341             : 
     342             : static const SvXMLDefaultDateFormat aDefaultDateFormats[] =
     343             : {
     344             :     // format                           day-of-week     day             month               year            hours           minutes         seconds         format-source
     345             : 
     346             :     { NF_DATE_SYSTEM_SHORT,             XML_DEA_NONE,   XML_DEA_ANY,    XML_DEA_ANY,        XML_DEA_ANY,    XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   true },
     347             :     { NF_DATE_SYSTEM_LONG,              XML_DEA_ANY,    XML_DEA_ANY,    XML_DEA_ANY,        XML_DEA_ANY,    XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   true },
     348             :     { NF_DATE_SYS_MMYY,                 XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_LONG,       XML_DEA_SHORT,  XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     349             :     { NF_DATE_SYS_DDMMM,                XML_DEA_NONE,   XML_DEA_LONG,   XML_DEA_TEXTSHORT,  XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     350             :     { NF_DATE_SYS_DDMMYYYY,             XML_DEA_NONE,   XML_DEA_LONG,   XML_DEA_LONG,       XML_DEA_LONG,   XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     351             :     { NF_DATE_SYS_DDMMYY,               XML_DEA_NONE,   XML_DEA_LONG,   XML_DEA_LONG,       XML_DEA_SHORT,  XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     352             :     { NF_DATE_SYS_DMMMYY,               XML_DEA_NONE,   XML_DEA_SHORT,  XML_DEA_TEXTSHORT,  XML_DEA_SHORT,  XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     353             :     { NF_DATE_SYS_DMMMYYYY,             XML_DEA_NONE,   XML_DEA_SHORT,  XML_DEA_TEXTSHORT,  XML_DEA_LONG,   XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     354             :     { NF_DATE_SYS_DMMMMYYYY,            XML_DEA_NONE,   XML_DEA_SHORT,  XML_DEA_TEXTLONG,   XML_DEA_LONG,   XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     355             :     { NF_DATE_SYS_NNDMMMYY,             XML_DEA_SHORT,  XML_DEA_SHORT,  XML_DEA_TEXTSHORT,  XML_DEA_SHORT,  XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     356             :     { NF_DATE_SYS_NNDMMMMYYYY,          XML_DEA_SHORT,  XML_DEA_SHORT,  XML_DEA_TEXTLONG,   XML_DEA_LONG,   XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     357             :     { NF_DATE_SYS_NNNNDMMMMYYYY,        XML_DEA_LONG,   XML_DEA_SHORT,  XML_DEA_TEXTLONG,   XML_DEA_LONG,   XML_DEA_NONE,   XML_DEA_NONE,   XML_DEA_NONE,   false },
     358             :     { NF_DATETIME_SYSTEM_SHORT_HHMM,    XML_DEA_NONE,   XML_DEA_ANY,    XML_DEA_ANY,        XML_DEA_ANY,    XML_DEA_ANY,    XML_DEA_ANY,    XML_DEA_NONE,   true },
     359             :     { NF_DATETIME_SYS_DDMMYYYY_HHMMSS,  XML_DEA_NONE,   XML_DEA_ANY,    XML_DEA_ANY,        XML_DEA_ANY,    XML_DEA_ANY,    XML_DEA_ANY,    XML_DEA_ANY,    false }
     360             : };
     361             : 
     362             : 
     363             : //  SvXMLNumImpData
     364             : 
     365             : 
     366        1822 : SvXMLNumImpData::SvXMLNumImpData(
     367             :     SvNumberFormatter* pFmt,
     368             :     const uno::Reference<uno::XComponentContext>& rxContext )
     369             : :   pFormatter(pFmt),
     370             :     pStylesElemTokenMap(NULL),
     371             :     pStyleElemTokenMap(NULL),
     372             :     pStyleAttrTokenMap(NULL),
     373             :     pStyleElemAttrTokenMap(NULL),
     374             :     pLocaleData(NULL),
     375        1822 :     m_xContext(rxContext)
     376             : {
     377             :     DBG_ASSERT( rxContext.is(), "got no service manager" );
     378        1822 : }
     379             : 
     380        3644 : SvXMLNumImpData::~SvXMLNumImpData()
     381             : {
     382        1822 :     delete pStylesElemTokenMap;
     383        1822 :     delete pStyleElemTokenMap;
     384        1822 :     delete pStyleAttrTokenMap;
     385        1822 :     delete pStyleElemAttrTokenMap;
     386        1822 :     delete pLocaleData;
     387        1822 : }
     388             : 
     389        1116 : sal_uInt32 SvXMLNumImpData::GetKeyForName( const OUString& rName )
     390             : {
     391        1116 :     sal_uInt16 nCount = aNameEntries.size();
     392       82704 :     for (sal_uInt16 i=0; i<nCount; i++)
     393             :     {
     394       82704 :         const SvXMLNumFmtEntry* pObj = &aNameEntries[i];
     395       82704 :         if ( pObj->aName == rName )
     396        1116 :             return pObj->nKey;              // found
     397             :     }
     398           0 :     return NUMBERFORMAT_ENTRY_NOT_FOUND;
     399             : }
     400             : 
     401        3630 : void SvXMLNumImpData::AddKey( sal_uInt32 nKey, const OUString& rName, bool bRemoveAfterUse )
     402             : {
     403        3630 :     if ( bRemoveAfterUse )
     404             :     {
     405             :         //  if there is already an entry for this key without the bRemoveAfterUse flag,
     406             :         //  clear the flag for this entry, too
     407             : 
     408        1116 :         sal_uInt16 nCount = aNameEntries.size();
     409       77966 :         for (sal_uInt16 i=0; i<nCount; i++)
     410             :         {
     411       76908 :             SvXMLNumFmtEntry* pObj = &aNameEntries[i];
     412       76908 :             if ( pObj->nKey == nKey && !pObj->bRemoveAfterUse )
     413             :             {
     414          58 :                 bRemoveAfterUse = false;        // clear flag for new entry
     415          58 :                 break;
     416             :             }
     417             :         }
     418             :     }
     419             :     else
     420             :     {
     421             :         //  call SetUsed to clear the bRemoveAfterUse flag for other entries for this key
     422        2514 :         SetUsed( nKey );
     423             :     }
     424             : 
     425        3630 :     SvXMLNumFmtEntry* pObj = new SvXMLNumFmtEntry( rName, nKey, bRemoveAfterUse );
     426        3630 :     aNameEntries.push_back( pObj );
     427        3630 : }
     428             : 
     429        2514 : void SvXMLNumImpData::SetUsed( sal_uInt32 nKey )
     430             : {
     431        2514 :     sal_uInt16 nCount = aNameEntries.size();
     432       98084 :     for (sal_uInt16 i=0; i<nCount; i++)
     433             :     {
     434       95570 :         SvXMLNumFmtEntry* pObj = &aNameEntries[i];
     435       95570 :         if ( pObj->nKey == nKey )
     436             :         {
     437          18 :             pObj->bRemoveAfterUse = false;      // used -> don't remove
     438             : 
     439             :             //  continue searching - there may be several entries for the same key
     440             :             //  (with different names), the format must not be deleted if any one of
     441             :             //  them is used
     442             :         }
     443             :     }
     444        2514 : }
     445             : 
     446        1822 : void SvXMLNumImpData::RemoveVolatileFormats()
     447             : {
     448             :     //  remove temporary (volatile) formats from NumberFormatter
     449             :     //  called at the end of each import (styles and content), so volatile formats
     450             :     //  from styles can't be used in content
     451             : 
     452        1822 :     if ( !pFormatter )
     453        1822 :         return;
     454             : 
     455        1822 :     sal_uInt16 nCount = aNameEntries.size();
     456        5452 :     for (sal_uInt16 i=0; i<nCount; i++)
     457             :     {
     458        3630 :         const SvXMLNumFmtEntry* pObj = &aNameEntries[i];
     459        3630 :         if ( pObj->bRemoveAfterUse )
     460             :         {
     461        1056 :             const SvNumberformat* pFormat = pFormatter->GetEntry(pObj->nKey);
     462        1056 :             if (pFormat && (pFormat->GetType() & NUMBERFORMAT_DEFINED))
     463         844 :                 pFormatter->DeleteEntry( pObj->nKey );
     464             :         }
     465             :     }
     466             : }
     467             : 
     468       32354 : const SvXMLTokenMap& SvXMLNumImpData::GetStylesElemTokenMap()
     469             : {
     470       32354 :     if( !pStylesElemTokenMap )
     471             :     {
     472             :         static const SvXMLTokenMapEntry aStylesElemMap[] =
     473             :         {
     474             :             //  style elements
     475             :             { XML_NAMESPACE_NUMBER, XML_NUMBER_STYLE,      XML_TOK_STYLES_NUMBER_STYLE      },
     476             :             { XML_NAMESPACE_NUMBER, XML_CURRENCY_STYLE,    XML_TOK_STYLES_CURRENCY_STYLE    },
     477             :             { XML_NAMESPACE_NUMBER, XML_PERCENTAGE_STYLE,  XML_TOK_STYLES_PERCENTAGE_STYLE  },
     478             :             { XML_NAMESPACE_NUMBER, XML_DATE_STYLE,        XML_TOK_STYLES_DATE_STYLE        },
     479             :             { XML_NAMESPACE_NUMBER, XML_TIME_STYLE,        XML_TOK_STYLES_TIME_STYLE        },
     480             :             { XML_NAMESPACE_NUMBER, XML_BOOLEAN_STYLE,     XML_TOK_STYLES_BOOLEAN_STYLE     },
     481             :             { XML_NAMESPACE_NUMBER, XML_TEXT_STYLE,        XML_TOK_STYLES_TEXT_STYLE        },
     482             :             XML_TOKEN_MAP_END
     483             :         };
     484             : 
     485        1770 :         pStylesElemTokenMap = new SvXMLTokenMap( aStylesElemMap );
     486             :     }
     487       32354 :     return *pStylesElemTokenMap;
     488             : }
     489             : 
     490       11154 : const SvXMLTokenMap& SvXMLNumImpData::GetStyleElemTokenMap()
     491             : {
     492       11154 :     if( !pStyleElemTokenMap )
     493             :     {
     494             :         static const SvXMLTokenMapEntry aStyleElemMap[] =
     495             :         {
     496             :             //  elements in a style
     497             :             { XML_NAMESPACE_LO_EXT, XML_TEXT,               XML_TOK_STYLE_TEXT              },
     498             :             { XML_NAMESPACE_NUMBER, XML_TEXT,               XML_TOK_STYLE_TEXT              },
     499             :             { XML_NAMESPACE_LO_EXT, XML_FILL_CHARACTER,     XML_TOK_STYLE_FILL_CHARACTER    },
     500             :             { XML_NAMESPACE_NUMBER, XML_FILL_CHARACTER,     XML_TOK_STYLE_FILL_CHARACTER    },
     501             :             { XML_NAMESPACE_NUMBER, XML_NUMBER,             XML_TOK_STYLE_NUMBER            },
     502             :             { XML_NAMESPACE_NUMBER, XML_SCIENTIFIC_NUMBER,  XML_TOK_STYLE_SCIENTIFIC_NUMBER },
     503             :             { XML_NAMESPACE_NUMBER, XML_FRACTION,           XML_TOK_STYLE_FRACTION          },
     504             :             { XML_NAMESPACE_NUMBER, XML_CURRENCY_SYMBOL,    XML_TOK_STYLE_CURRENCY_SYMBOL   },
     505             :             { XML_NAMESPACE_NUMBER, XML_DAY,                XML_TOK_STYLE_DAY               },
     506             :             { XML_NAMESPACE_NUMBER, XML_MONTH,              XML_TOK_STYLE_MONTH             },
     507             :             { XML_NAMESPACE_NUMBER, XML_YEAR,               XML_TOK_STYLE_YEAR              },
     508             :             { XML_NAMESPACE_NUMBER, XML_ERA,                XML_TOK_STYLE_ERA               },
     509             :             { XML_NAMESPACE_NUMBER, XML_DAY_OF_WEEK,        XML_TOK_STYLE_DAY_OF_WEEK       },
     510             :             { XML_NAMESPACE_NUMBER, XML_WEEK_OF_YEAR,       XML_TOK_STYLE_WEEK_OF_YEAR      },
     511             :             { XML_NAMESPACE_NUMBER, XML_QUARTER,            XML_TOK_STYLE_QUARTER           },
     512             :             { XML_NAMESPACE_NUMBER, XML_HOURS,              XML_TOK_STYLE_HOURS             },
     513             :             { XML_NAMESPACE_NUMBER, XML_AM_PM,              XML_TOK_STYLE_AM_PM             },
     514             :             { XML_NAMESPACE_NUMBER, XML_MINUTES,            XML_TOK_STYLE_MINUTES           },
     515             :             { XML_NAMESPACE_NUMBER, XML_SECONDS,            XML_TOK_STYLE_SECONDS           },
     516             :             { XML_NAMESPACE_NUMBER, XML_BOOLEAN,            XML_TOK_STYLE_BOOLEAN           },
     517             :             { XML_NAMESPACE_NUMBER, XML_TEXT_CONTENT,       XML_TOK_STYLE_TEXT_CONTENT      },
     518             :             { XML_NAMESPACE_STYLE,  XML_TEXT_PROPERTIES,    XML_TOK_STYLE_PROPERTIES        },
     519             :             { XML_NAMESPACE_STYLE,  XML_MAP,                XML_TOK_STYLE_MAP               },
     520             :             XML_TOKEN_MAP_END
     521             :         };
     522             : 
     523         618 :         pStyleElemTokenMap = new SvXMLTokenMap( aStyleElemMap );
     524             :     }
     525       11154 :     return *pStyleElemTokenMap;
     526             : }
     527             : 
     528        6620 : const SvXMLTokenMap& SvXMLNumImpData::GetStyleAttrTokenMap()
     529             : {
     530        6620 :     if( !pStyleAttrTokenMap )
     531             :     {
     532             :         static const SvXMLTokenMapEntry aStyleAttrMap[] =
     533             :         {
     534             :             //  attributes for a style
     535             :             { XML_NAMESPACE_STYLE,  XML_NAME,                  XML_TOK_STYLE_ATTR_NAME                  },
     536             :             { XML_NAMESPACE_NUMBER, XML_RFC_LANGUAGE_TAG,      XML_TOK_STYLE_ATTR_RFC_LANGUAGE_TAG,     },
     537             :             { XML_NAMESPACE_NUMBER, XML_LANGUAGE,              XML_TOK_STYLE_ATTR_LANGUAGE              },
     538             :             { XML_NAMESPACE_NUMBER, XML_SCRIPT,                XML_TOK_STYLE_ATTR_SCRIPT                },
     539             :             { XML_NAMESPACE_NUMBER, XML_COUNTRY,               XML_TOK_STYLE_ATTR_COUNTRY               },
     540             :             { XML_NAMESPACE_NUMBER, XML_TITLE,                 XML_TOK_STYLE_ATTR_TITLE                 },
     541             :             { XML_NAMESPACE_NUMBER, XML_AUTOMATIC_ORDER,       XML_TOK_STYLE_ATTR_AUTOMATIC_ORDER       },
     542             :             { XML_NAMESPACE_NUMBER, XML_FORMAT_SOURCE,         XML_TOK_STYLE_ATTR_FORMAT_SOURCE         },
     543             :             { XML_NAMESPACE_NUMBER, XML_TRUNCATE_ON_OVERFLOW,  XML_TOK_STYLE_ATTR_TRUNCATE_ON_OVERFLOW  },
     544             :             { XML_NAMESPACE_STYLE,  XML_VOLATILE,              XML_TOK_STYLE_ATTR_VOLATILE              },
     545             :             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_FORMAT,     XML_TOK_STYLE_ATTR_TRANSL_FORMAT    },
     546             :             // not defined in ODF { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_RFC_LANGUAGE_TAG, XML_TOK_STYLE_ATTR_TRANSL_RFC_LANGUAGE_TAG   },
     547             :             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_LANGUAGE,   XML_TOK_STYLE_ATTR_TRANSL_LANGUAGE  },
     548             :             // not defined in ODF { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_SCRIPT,     XML_TOK_STYLE_ATTR_TRANSL_SCRIPT    },
     549             :             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_COUNTRY,    XML_TOK_STYLE_ATTR_TRANSL_COUNTRY   },
     550             :             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_STYLE,      XML_TOK_STYLE_ATTR_TRANSL_STYLE     },
     551             :             XML_TOKEN_MAP_END
     552             :         };
     553             : 
     554         618 :         pStyleAttrTokenMap = new SvXMLTokenMap( aStyleAttrMap );
     555             :     }
     556        6620 :     return *pStyleAttrTokenMap;
     557             : }
     558             : 
     559        9434 : const SvXMLTokenMap& SvXMLNumImpData::GetStyleElemAttrTokenMap()
     560             : {
     561        9434 :     if( !pStyleElemAttrTokenMap )
     562             :     {
     563             :         static const SvXMLTokenMapEntry aStyleElemAttrMap[] =
     564             :         {
     565             :             //  attributes for an element within a style
     566             :             { XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,          XML_TOK_ELEM_ATTR_DECIMAL_PLACES       },
     567             :             { XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,      XML_TOK_ELEM_ATTR_MIN_INTEGER_DIGITS   },
     568             :             { XML_NAMESPACE_NUMBER, XML_GROUPING,                XML_TOK_ELEM_ATTR_GROUPING             },
     569             :             { XML_NAMESPACE_NUMBER, XML_DISPLAY_FACTOR,          XML_TOK_ELEM_ATTR_DISPLAY_FACTOR       },
     570             :             { XML_NAMESPACE_NUMBER, XML_DECIMAL_REPLACEMENT,     XML_TOK_ELEM_ATTR_DECIMAL_REPLACEMENT  },
     571             :             { XML_NAMESPACE_NUMBER, XML_DENOMINATOR_VALUE,       XML_TOK_ELEM_ATTR_DENOMINATOR_VALUE  },
     572             :             { XML_NAMESPACE_NUMBER, XML_MIN_EXPONENT_DIGITS,     XML_TOK_ELEM_ATTR_MIN_EXPONENT_DIGITS  },
     573             :             { XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS,    XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS },
     574             :             { XML_NAMESPACE_NUMBER, XML_MIN_DENOMINATOR_DIGITS,  XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS },
     575             :             { XML_NAMESPACE_NUMBER, XML_RFC_LANGUAGE_TAG,        XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG     },
     576             :             { XML_NAMESPACE_NUMBER, XML_LANGUAGE,                XML_TOK_ELEM_ATTR_LANGUAGE             },
     577             :             { XML_NAMESPACE_NUMBER, XML_SCRIPT,                  XML_TOK_ELEM_ATTR_SCRIPT               },
     578             :             { XML_NAMESPACE_NUMBER, XML_COUNTRY,                 XML_TOK_ELEM_ATTR_COUNTRY              },
     579             :             { XML_NAMESPACE_NUMBER, XML_STYLE,                   XML_TOK_ELEM_ATTR_STYLE                },
     580             :             { XML_NAMESPACE_NUMBER, XML_TEXTUAL,                 XML_TOK_ELEM_ATTR_TEXTUAL              },
     581             :             { XML_NAMESPACE_NUMBER, XML_CALENDAR,                XML_TOK_ELEM_ATTR_CALENDAR             },
     582             :             XML_TOKEN_MAP_END
     583             :         };
     584             : 
     585         614 :         pStyleElemAttrTokenMap = new SvXMLTokenMap( aStyleElemAttrMap );
     586             :     }
     587        9434 :     return *pStyleElemAttrTokenMap;
     588             : }
     589             : 
     590        2060 : const LocaleDataWrapper& SvXMLNumImpData::GetLocaleData( LanguageType nLang )
     591             : {
     592        2060 :     if ( !pLocaleData )
     593             :         pLocaleData = new LocaleDataWrapper(
     594             :                pFormatter ? pFormatter->GetComponentContext() : m_xContext,
     595         344 :             LanguageTag( nLang ) );
     596             :     else
     597        1716 :         pLocaleData->setLanguageTag( LanguageTag( nLang ) );
     598        2060 :     return *pLocaleData;
     599             : }
     600             : 
     601             : 
     602             : //  SvXMLNumFmtMapContext
     603             : 
     604             : 
     605        1116 : SvXMLNumFmtMapContext::SvXMLNumFmtMapContext( SvXMLImport& rImport,
     606             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     607             :                                     SvXMLNumFormatContext& rParentContext,
     608             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
     609             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     610        1116 :     rParent( rParentContext )
     611             : {
     612        1116 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     613        3348 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     614             :     {
     615        2232 :         OUString sAttrName = xAttrList->getNameByIndex( i );
     616        4464 :         OUString sValue = xAttrList->getValueByIndex( i );
     617        4464 :         OUString aLocalName;
     618        2232 :         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     619        2232 :         if ( nPrefix == XML_NAMESPACE_STYLE )
     620             :         {
     621        2232 :             if ( IsXMLToken( aLocalName, XML_CONDITION) )
     622        1116 :                 sCondition = sValue;
     623        1116 :             else if ( IsXMLToken( aLocalName, XML_APPLY_STYLE_NAME) )
     624        1116 :                 sName = sValue;
     625             :         }
     626        2232 :     }
     627        1116 : }
     628             : 
     629        2232 : SvXMLNumFmtMapContext::~SvXMLNumFmtMapContext()
     630             : {
     631        2232 : }
     632             : 
     633           0 : SvXMLImportContext* SvXMLNumFmtMapContext::CreateChildContext(
     634             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     635             :                                     const uno::Reference<xml::sax::XAttributeList>& )
     636             : {
     637             :     // no elements supported - use default context
     638           0 :     return new SvXMLImportContext( GetImport(), nPrfx, rLName );
     639             : }
     640             : 
     641           0 : void SvXMLNumFmtMapContext::Characters( const OUString& )
     642             : {
     643           0 : }
     644             : 
     645        1116 : void SvXMLNumFmtMapContext::EndElement()
     646             : {
     647        1116 :     rParent.AddCondition( sCondition, sName );
     648        1116 : }
     649             : 
     650             : 
     651             : //  SvXMLNumFmtPropContext
     652             : 
     653             : 
     654         514 : SvXMLNumFmtPropContext::SvXMLNumFmtPropContext( SvXMLImport& rImport,
     655             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     656             :                                     SvXMLNumFormatContext& rParentContext,
     657             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
     658             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     659             :     rParent( rParentContext ),
     660             :     m_nColor( 0 ),
     661         514 :     bColSet( false )
     662             : {
     663         514 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     664        1028 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     665             :     {
     666         514 :         OUString sAttrName = xAttrList->getNameByIndex( i );
     667        1028 :         OUString sValue = xAttrList->getValueByIndex( i );
     668        1028 :         OUString aLocalName;
     669         514 :         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     670         514 :         if ( nPrefix == XML_NAMESPACE_FO && IsXMLToken( aLocalName, XML_COLOR ) )
     671             :         {
     672         514 :             bColSet = ::sax::Converter::convertColor( m_nColor, sValue );
     673             :         }
     674         514 :     }
     675         514 : }
     676             : 
     677        1028 : SvXMLNumFmtPropContext::~SvXMLNumFmtPropContext()
     678             : {
     679        1028 : }
     680             : 
     681           0 : SvXMLImportContext* SvXMLNumFmtPropContext::CreateChildContext(
     682             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     683             :                                     const uno::Reference<xml::sax::XAttributeList>& )
     684             : {
     685             :     // no elements supported - use default context
     686           0 :     return new SvXMLImportContext( GetImport(), nPrfx, rLName );
     687             : }
     688             : 
     689           0 : void SvXMLNumFmtPropContext::Characters( const OUString& )
     690             : {
     691           0 : }
     692             : 
     693         514 : void SvXMLNumFmtPropContext::EndElement()
     694             : {
     695         514 :     if (bColSet)
     696         514 :         rParent.AddColor( m_nColor );
     697         514 : }
     698             : 
     699             : 
     700             : //  SvXMLNumFmtEmbeddedTextContext
     701             : 
     702             : 
     703           0 : SvXMLNumFmtEmbeddedTextContext::SvXMLNumFmtEmbeddedTextContext( SvXMLImport& rImport,
     704             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     705             :                                     SvXMLNumFmtElementContext& rParentContext,
     706             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
     707             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     708             :     rParent( rParentContext ),
     709           0 :     nTextPosition( 0 )
     710             : {
     711             :     sal_Int32 nAttrVal;
     712             : 
     713           0 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     714           0 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     715             :     {
     716           0 :         OUString sAttrName = xAttrList->getNameByIndex( i );
     717           0 :         OUString sValue = xAttrList->getValueByIndex( i );
     718           0 :         OUString aLocalName;
     719           0 :         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     720           0 :         if ( nPrefix == XML_NAMESPACE_NUMBER && IsXMLToken( aLocalName, XML_POSITION ) )
     721             :         {
     722           0 :             if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     723           0 :                 nTextPosition = nAttrVal;
     724             :         }
     725           0 :     }
     726           0 : }
     727             : 
     728           0 : SvXMLNumFmtEmbeddedTextContext::~SvXMLNumFmtEmbeddedTextContext()
     729             : {
     730           0 : }
     731             : 
     732           0 : SvXMLImportContext* SvXMLNumFmtEmbeddedTextContext::CreateChildContext(
     733             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     734             :                                     const uno::Reference<xml::sax::XAttributeList>& )
     735             : {
     736             :     // no elements supported - use default context
     737           0 :     return new SvXMLImportContext( GetImport(), nPrfx, rLName );
     738             : }
     739             : 
     740           0 : void SvXMLNumFmtEmbeddedTextContext::Characters( const OUString& rChars )
     741             : {
     742           0 :     aContent.append( rChars );
     743           0 : }
     744             : 
     745           0 : void SvXMLNumFmtEmbeddedTextContext::EndElement()
     746             : {
     747           0 :     rParent.AddEmbeddedElement( nTextPosition, aContent.makeStringAndClear() );
     748           0 : }
     749             : 
     750        3324 : static bool lcl_ValidChar( sal_Unicode cChar, const SvXMLNumFormatContext& rParent )
     751             : {
     752        3324 :     sal_uInt16 nFormatType = rParent.GetType();
     753             : 
     754             :     // Treat space equal to non-breaking space separator.
     755        3324 :     const sal_Unicode cNBSP = 0x00A0;
     756             :     sal_Unicode cTS;
     757        5606 :     if ( ( nFormatType == XML_TOK_STYLES_NUMBER_STYLE ||
     758        1422 :            nFormatType == XML_TOK_STYLES_CURRENCY_STYLE ||
     759        5350 :            nFormatType == XML_TOK_STYLES_PERCENTAGE_STYLE ) &&
     760        3984 :             (cChar == (cTS = rParent.GetLocaleData().getNumThousandSep()[0]) ||
     761         766 :              (cChar == ' ' && cTS == cNBSP)) )
     762             :     {
     763             :         //  #i22394# Extra occurrences of thousands separator must be quoted, so they
     764             :         //  aren't mis-interpreted as display-factor.
     765             :         //  This must be limited to the format types that can contain a number element,
     766             :         //  because the same character can be a date separator that should not be quoted
     767             :         //  in date formats.
     768             : 
     769          34 :         return false;   // force quotes
     770             :     }
     771             : 
     772             :     //  see ImpSvNumberformatScan::Next_Symbol
     773        3290 :     if ( cChar == ' ' ||
     774        1446 :          cChar == '-' ||
     775         966 :          cChar == '/' ||
     776         924 :          cChar == '.' ||
     777         898 :          cChar == ',' ||
     778         556 :          cChar == ':' ||
     779             :          cChar == '\'' )
     780        2734 :         return true;    // for all format types
     781             : 
     782             :     //  percent sign must be used without quotes for percentage styles only
     783         556 :     if ( nFormatType == XML_TOK_STYLES_PERCENTAGE_STYLE && cChar == '%' )
     784          90 :         return true;
     785             : 
     786             :     //  don't put quotes around single parentheses (often used for negative numbers)
     787         466 :     if ( ( nFormatType == XML_TOK_STYLES_NUMBER_STYLE ||
     788          22 :            nFormatType == XML_TOK_STYLES_CURRENCY_STYLE ||
     789         444 :            nFormatType == XML_TOK_STYLES_PERCENTAGE_STYLE ) &&
     790         274 :          ( cChar == '(' || cChar == ')' ) )
     791         348 :         return true;
     792             : 
     793         118 :     return false;
     794             : }
     795             : 
     796        3740 : static void lcl_EnquoteIfNecessary( OUStringBuffer& rContent, const SvXMLNumFormatContext& rParent )
     797             : {
     798        3740 :     bool bQuote = true;
     799        3740 :     sal_Int32 nLength = rContent.getLength();
     800             : 
     801        6718 :     if ( ( nLength == 1 &&
     802        7544 :             lcl_ValidChar( rContent[0], rParent ) ) ||
     803         346 :          ( nLength == 2 &&
     804         632 :              lcl_ValidChar( rContent[0], rParent ) &&
     805         286 :              rContent[1] == ' ' ) )
     806             :     {
     807             :         //  don't quote single separator characters like space or percent,
     808             :         //  or separator characters followed by space (used in date formats)
     809        2950 :         bQuote = false;
     810             :     }
     811         790 :     else if ( rParent.GetType() == XML_TOK_STYLES_PERCENTAGE_STYLE && nLength > 1 )
     812             :     {
     813             :         //  the percent character in percentage styles must be left out of quoting
     814             :         //  (one occurrence is enough even if there are several percent characters in the string)
     815             : 
     816           0 :         OUString aString( rContent.getStr() );
     817           0 :         sal_Int32 nPos = aString.indexOf( '%' );
     818           0 :         if ( nPos >= 0 )
     819             :         {
     820           0 :             if ( nPos + 1 < nLength )
     821             :             {
     822           0 :                 if ( nPos + 2 == nLength && lcl_ValidChar( rContent[nPos + 1], rParent ) )
     823             :                 {
     824             :                     //  single character that doesn't need quoting
     825             :                 }
     826             :                 else
     827             :                 {
     828             :                     //  quote text behind percent character
     829           0 :                     rContent.insert( nPos + 1, '"' );
     830           0 :                     rContent.append( '"' );
     831             :                 }
     832             :             }
     833           0 :             if ( nPos > 0 )
     834             :             {
     835           0 :                 if ( nPos == 1 && lcl_ValidChar( rContent[0], rParent ) )
     836             :                 {
     837             :                     //  single character that doesn't need quoting
     838             :                 }
     839             :                 else
     840             :                 {
     841             :                     //  quote text before percent character
     842           0 :                     rContent.insert( nPos, '"' );
     843           0 :                     rContent.insert( 0, '"' );
     844             :                 }
     845             :             }
     846           0 :             bQuote = false;
     847           0 :         }
     848             :         // else: normal quoting (below)
     849             :     }
     850             : 
     851        3740 :     if ( bQuote )
     852             :     {
     853             :         // #i55469# quotes in the string itself have to be escaped
     854         790 :         bool bEscape = ( rContent.indexOf( '"' ) >= 0 );
     855         790 :         if ( bEscape )
     856             :         {
     857             :             // A quote is turned into "\"" - a quote to end quoted text, an escaped quote,
     858             :             // and a quote to resume quoting.
     859          88 :             OUString aInsert(  "\"\\\""  );
     860             : 
     861          88 :             sal_Int32 nPos = 0;
     862         488 :             while ( nPos < rContent.getLength() )
     863             :             {
     864         312 :                 if ( rContent[nPos] == '"' )
     865             :                 {
     866          88 :                     rContent.insert( nPos, aInsert );
     867          88 :                     nPos += aInsert.getLength();
     868             :                 }
     869         312 :                 ++nPos;
     870          88 :             }
     871             :         }
     872             : 
     873             :         //  quote string literals
     874         790 :         rContent.insert( 0, '"' );
     875         790 :         rContent.append( '"' );
     876             : 
     877             :         // remove redundant double quotes at start or end
     878         790 :         if ( bEscape )
     879             :         {
     880         264 :             if ( rContent.getLength() > 2 &&
     881         176 :                  rContent[0] == '"' &&
     882          88 :                  rContent[1] == '"' )
     883             :             {
     884           0 :                 rContent.remove(0, 2);
     885             :             }
     886             : 
     887          88 :             sal_Int32 nLen = rContent.getLength();
     888         176 :             if ( nLen > 2 &&
     889         176 :                  rContent[nLen - 1] == '"' &&
     890          88 :                  rContent[nLen - 2] == '"' )
     891             :             {
     892          88 :                 rContent.truncate(nLen - 2);
     893             :             }
     894             :         }
     895             :     }
     896        3740 : }
     897             : 
     898             : 
     899             : //  SvXMLNumFmtElementContext
     900             : 
     901             : 
     902             : const sal_Int32 MAX_SECOND_DIGITS = 20; // fdo#58539 & gnome#627420: limit number of digits during import
     903             : 
     904        9524 : SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
     905             :                                     sal_uInt16 nPrfx, const OUString& rLName,
     906             :                                     SvXMLNumFormatContext& rParentContext, sal_uInt16 nNewType,
     907             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
     908             :     SvXMLImportContext( rImport, nPrfx, rLName ),
     909             :     rParent( rParentContext ),
     910             :     nType( nNewType ),
     911             :     nElementLang( LANGUAGE_SYSTEM ),
     912             :     bLong( false ),
     913        9524 :     bTextual( false )
     914             : {
     915        9524 :     LanguageTagODF aLanguageTagODF;
     916             :     sal_Int32 nAttrVal;
     917        9524 :     bool bAttrBool(false);
     918             :     sal_uInt16 nAttrEnum;
     919             :     double fAttrDouble;
     920             : 
     921        9524 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     922       18958 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
     923             :     {
     924        9434 :         OUString sAttrName = xAttrList->getNameByIndex( i );
     925       18868 :         OUString sValue = xAttrList->getValueByIndex( i );
     926       18868 :         OUString aLocalName;
     927        9434 :         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
     928             : 
     929        9434 :         const SvXMLTokenMap& rTokenMap = rParent.GetData()->GetStyleElemAttrTokenMap();
     930        9434 :         sal_uInt16 nToken = rTokenMap.Get( nPrefix, aLocalName );
     931             : 
     932        9434 :         switch (nToken)
     933             :         {
     934             :             case XML_TOK_ELEM_ATTR_DECIMAL_PLACES:
     935        2194 :                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     936        2194 :                     aNumInfo.nDecimals = std::min<sal_Int32>(nAttrVal, MAX_SECOND_DIGITS);
     937        2194 :                 break;
     938             :             case XML_TOK_ELEM_ATTR_MIN_INTEGER_DIGITS:
     939        2740 :                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     940        2740 :                     aNumInfo.nInteger = nAttrVal;
     941        2740 :                 break;
     942             :             case XML_TOK_ELEM_ATTR_GROUPING:
     943        1674 :                 if (::sax::Converter::convertBool( bAttrBool, sValue ))
     944        1674 :                     aNumInfo.bGrouping = bAttrBool;
     945        1674 :                 break;
     946             :             case XML_TOK_ELEM_ATTR_DISPLAY_FACTOR:
     947          32 :                 if (::sax::Converter::convertDouble( fAttrDouble, sValue ))
     948          32 :                     aNumInfo.fDisplayFactor = fAttrDouble;
     949          32 :                 break;
     950             :             case XML_TOK_ELEM_ATTR_DECIMAL_REPLACEMENT:
     951           6 :                 if ( !sValue.isEmpty() )
     952           4 :                     aNumInfo.bDecReplace = true;    // only a default string is supported
     953             :                 else
     954           2 :                     aNumInfo.bVarDecimals = true;   // empty replacement string: variable decimals
     955           6 :                 break;
     956             :             case XML_TOK_ELEM_ATTR_MIN_EXPONENT_DIGITS:
     957          68 :                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     958          68 :                     aNumInfo.nExpDigits = nAttrVal;
     959          68 :                 break;
     960             :             case XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS:
     961          14 :                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     962          14 :                     aNumInfo.nNumerDigits = nAttrVal;
     963          14 :                 break;
     964             :             case XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS:
     965          14 :                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     966          14 :                     aNumInfo.nDenomDigits = nAttrVal;
     967          14 :                 break;
     968             :             case XML_TOK_ELEM_ATTR_DENOMINATOR_VALUE:
     969           0 :                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
     970           0 :                     aNumInfo.nFracDenominator = nAttrVal;
     971           0 :                 break;
     972             :             case XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG:
     973           0 :                 aLanguageTagODF.maRfcLanguageTag = sValue;
     974           0 :                 break;
     975             :             case XML_TOK_ELEM_ATTR_LANGUAGE:
     976         742 :                 aLanguageTagODF.maLanguage = sValue;
     977         742 :                 break;
     978             :             case XML_TOK_ELEM_ATTR_SCRIPT:
     979           0 :                 aLanguageTagODF.maScript = sValue;
     980           0 :                 break;
     981             :             case XML_TOK_ELEM_ATTR_COUNTRY:
     982         742 :                 aLanguageTagODF.maCountry = sValue;
     983         742 :                 break;
     984             :             case XML_TOK_ELEM_ATTR_STYLE:
     985        1064 :                 if ( SvXMLUnitConverter::convertEnum( nAttrEnum, sValue, aStyleValueMap ) )
     986        1064 :                     bLong = (bool) nAttrEnum;
     987        1064 :                 break;
     988             :             case XML_TOK_ELEM_ATTR_TEXTUAL:
     989         128 :                 if (::sax::Converter::convertBool( bAttrBool, sValue ))
     990         128 :                     bTextual = bAttrBool;
     991         128 :                 break;
     992             :             case XML_TOK_ELEM_ATTR_CALENDAR:
     993          16 :                 sCalendar = sValue;
     994          16 :                 break;
     995             :         }
     996        9434 :     }
     997             : 
     998        9524 :     if ( !aLanguageTagODF.isEmpty() )
     999             :     {
    1000         742 :         nElementLang = aLanguageTagODF.getLanguageTag().getLanguageType( false);
    1001         742 :         if ( nElementLang == LANGUAGE_DONTKNOW )
    1002           0 :             nElementLang = LANGUAGE_SYSTEM;         //! error handling for unknown locales?
    1003        9524 :     }
    1004        9524 : }
    1005             : 
    1006       19048 : SvXMLNumFmtElementContext::~SvXMLNumFmtElementContext()
    1007             : {
    1008       19048 : }
    1009             : 
    1010           0 : SvXMLImportContext* SvXMLNumFmtElementContext::CreateChildContext(
    1011             :                                     sal_uInt16 nPrfx, const OUString& rLName,
    1012             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList )
    1013             : {
    1014             :     //  only number:number supports number:embedded-text child element
    1015             : 
    1016           0 :     if ( nType == XML_TOK_STYLE_NUMBER &&
    1017           0 :          nPrfx == XML_NAMESPACE_NUMBER && IsXMLToken( rLName, XML_EMBEDDED_TEXT ) )
    1018             :     {
    1019           0 :         return new SvXMLNumFmtEmbeddedTextContext( GetImport(), nPrfx, rLName, *this, xAttrList );
    1020             :     }
    1021             :     else
    1022           0 :         return new SvXMLImportContext( GetImport(), nPrfx, rLName );
    1023             : }
    1024             : 
    1025        4786 : void SvXMLNumFmtElementContext::Characters( const OUString& rChars )
    1026             : {
    1027        4786 :     aContent.append( rChars );
    1028        4786 : }
    1029             : 
    1030           0 : void SvXMLNumFmtElementContext::AddEmbeddedElement( sal_Int32 nFormatPos, const OUString& rContent )
    1031             : {
    1032           0 :     if ( !rContent.isEmpty() )
    1033             :     {
    1034           0 :         SvXMLEmbeddedElement* pObj = new SvXMLEmbeddedElement( nFormatPos, rContent );
    1035           0 :         if ( !aNumInfo.aEmbeddedElements.insert( pObj ).second )
    1036             :         {
    1037             :             //  there's already an element at this position - append text to existing element
    1038             : 
    1039           0 :             delete pObj;
    1040           0 :             for (SvXMLEmbeddedElementArr::iterator it = aNumInfo.aEmbeddedElements.begin();
    1041           0 :                  it != aNumInfo.aEmbeddedElements.end(); ++it)
    1042             :             {
    1043           0 :                 pObj = &*it;
    1044           0 :                 if ( pObj->nFormatPos == nFormatPos )
    1045             :                 {
    1046           0 :                     pObj->aText += rContent;
    1047           0 :                     break;
    1048             :                 }
    1049             :             }
    1050             :         }
    1051             :     }
    1052           0 : }
    1053             : 
    1054        9524 : void SvXMLNumFmtElementContext::EndElement()
    1055             : {
    1056        9524 :     bool bEffLong = bLong;
    1057        9524 :     switch (nType)
    1058             :     {
    1059             :         case XML_TOK_STYLE_TEXT:
    1060       11272 :             if ( rParent.HasLongDoW() &&
    1061        3784 :                  aContent.toString().equals(rParent.GetLocaleData().getLongDateDayOfWeekSep()) )
    1062             :             {
    1063             :                 //  skip separator constant after long day of week
    1064             :                 //  (NF_KEY_NNNN contains the separator)
    1065             : 
    1066          10 :                 if ( rParent.ReplaceNfKeyword( NF_KEY_NNN, NF_KEY_NNNN ) )
    1067             :                 {
    1068          10 :                     aContent = OUStringBuffer();
    1069             :                 }
    1070             : 
    1071          10 :                 rParent.SetHasLongDoW( false );     // only once
    1072             :             }
    1073        3754 :             if ( !aContent.isEmpty() )
    1074             :             {
    1075        3740 :                 lcl_EnquoteIfNecessary( aContent, rParent );
    1076        3740 :                 rParent.AddToCode( aContent.makeStringAndClear() );
    1077             :             }
    1078        3754 :             break;
    1079             : 
    1080             :         case XML_TOK_STYLE_NUMBER:
    1081        2658 :             rParent.AddNumber( aNumInfo );
    1082        2658 :             break;
    1083             : 
    1084             :         case XML_TOK_STYLE_CURRENCY_SYMBOL:
    1085         922 :             rParent.AddCurrency( aContent.makeStringAndClear(), nElementLang );
    1086         922 :             break;
    1087             : 
    1088             :         case XML_TOK_STYLE_TEXT_CONTENT:
    1089         134 :             rParent.AddToCode( '@');
    1090         134 :             break;
    1091             :         case XML_TOK_STYLE_FILL_CHARACTER:
    1092         174 :             if ( !aContent.isEmpty() )
    1093             :             {
    1094         174 :                 rParent.AddToCode( '*' );
    1095         174 :                 rParent.AddToCode( aContent[0] );
    1096             :             }
    1097         174 :             break;
    1098             :         case XML_TOK_STYLE_BOOLEAN:
    1099             :             // ignored - only default boolean format is supported
    1100          26 :             break;
    1101             : 
    1102             :         case XML_TOK_STYLE_DAY:
    1103         364 :             rParent.UpdateCalendar( sCalendar );
    1104             : //! I18N doesn't provide SYSTEM or extended date information yet
    1105             : 
    1106             :             rParent.AddNfKeyword(
    1107             :                 sal::static_int_cast< sal_uInt16 >(
    1108         364 :                     bEffLong ? NF_KEY_DD : NF_KEY_D ) );
    1109         364 :             break;
    1110             :         case XML_TOK_STYLE_MONTH:
    1111         400 :             rParent.UpdateCalendar( sCalendar );
    1112             : //! I18N doesn't provide SYSTEM or extended date information yet
    1113             : 
    1114             :             rParent.AddNfKeyword(
    1115             :                 sal::static_int_cast< sal_uInt16 >(
    1116             :                     bTextual
    1117             :                     ? ( bEffLong ? NF_KEY_MMMM : NF_KEY_MMM )
    1118         400 :                     : ( bEffLong ? NF_KEY_MM : NF_KEY_M ) ) );
    1119         400 :             break;
    1120             :         case XML_TOK_STYLE_YEAR:
    1121         348 :             rParent.UpdateCalendar( sCalendar );
    1122             : //! I18N doesn't provide SYSTEM or extended date information yet
    1123             :             // Y after G (era) is replaced by E
    1124         348 :             if ( rParent.HasEra() )
    1125             :                 rParent.AddNfKeyword(
    1126             :                     sal::static_int_cast< sal_uInt16 >(
    1127           4 :                         bEffLong ? NF_KEY_EEC : NF_KEY_EC ) );
    1128             :             else
    1129             :                 rParent.AddNfKeyword(
    1130             :                     sal::static_int_cast< sal_uInt16 >(
    1131         344 :                         bEffLong ? NF_KEY_YYYY : NF_KEY_YY ) );
    1132         348 :             break;
    1133             :         case XML_TOK_STYLE_ERA:
    1134           4 :             rParent.UpdateCalendar( sCalendar );
    1135             : //! I18N doesn't provide SYSTEM or extended date information yet
    1136             :             rParent.AddNfKeyword(
    1137             :                 sal::static_int_cast< sal_uInt16 >(
    1138           4 :                     bEffLong ? NF_KEY_GGG : NF_KEY_G ) );
    1139             :             //  HasEra flag is set
    1140           4 :             break;
    1141             :         case XML_TOK_STYLE_DAY_OF_WEEK:
    1142          24 :             rParent.UpdateCalendar( sCalendar );
    1143             : //! I18N doesn't provide SYSTEM or extended date information yet
    1144             :             rParent.AddNfKeyword(
    1145             :                 sal::static_int_cast< sal_uInt16 >(
    1146          24 :                     bEffLong ? NF_KEY_NNNN : NF_KEY_NN ) );
    1147          24 :             break;
    1148             :         case XML_TOK_STYLE_WEEK_OF_YEAR:
    1149           0 :             rParent.UpdateCalendar( sCalendar );
    1150           0 :             rParent.AddNfKeyword( NF_KEY_WW );
    1151           0 :             break;
    1152             :         case XML_TOK_STYLE_QUARTER:
    1153           0 :             rParent.UpdateCalendar( sCalendar );
    1154             :             rParent.AddNfKeyword(
    1155             :                 sal::static_int_cast< sal_uInt16 >(
    1156           0 :                     bEffLong ? NF_KEY_QQ : NF_KEY_Q ) );
    1157           0 :             break;
    1158             :         case XML_TOK_STYLE_HOURS:
    1159             :             rParent.AddNfKeyword(
    1160             :                 sal::static_int_cast< sal_uInt16 >(
    1161         194 :                     bEffLong ? NF_KEY_HH : NF_KEY_H ) );
    1162         194 :             break;
    1163             :         case XML_TOK_STYLE_AM_PM:
    1164             :             //! short/long?
    1165          66 :             rParent.AddNfKeyword( NF_KEY_AMPM );
    1166          66 :             break;
    1167             :         case XML_TOK_STYLE_MINUTES:
    1168             :             rParent.AddNfKeyword(
    1169             :                 sal::static_int_cast< sal_uInt16 >(
    1170         234 :                     bEffLong ? NF_KEY_MMI : NF_KEY_MI ) );
    1171         234 :             break;
    1172             :         case XML_TOK_STYLE_SECONDS:
    1173             :             rParent.AddNfKeyword(
    1174             :                 sal::static_int_cast< sal_uInt16 >(
    1175         140 :                     bEffLong ? NF_KEY_SS : NF_KEY_S ) );
    1176         140 :             if ( aNumInfo.nDecimals > 0 )
    1177             :             {
    1178             :                 //  manually add the decimal places
    1179          20 :                 rParent.AddToCode(rParent.GetLocaleData().getNumDecimalSep());
    1180          40 :                 for (sal_Int32 i=0; i<aNumInfo.nDecimals; i++)
    1181             :                 {
    1182          20 :                     rParent.AddToCode( '0');
    1183             :                 }
    1184             :             }
    1185         140 :             break;
    1186             : 
    1187             :         case XML_TOK_STYLE_FRACTION:
    1188             :             {
    1189          14 :                 if ( aNumInfo.nInteger >= 0 )
    1190             :                 {
    1191             :                     // add integer part only if min-integer-digits attribute is there
    1192          14 :                     aNumInfo.nDecimals = 0;
    1193          14 :                     rParent.AddNumber( aNumInfo );      // number without decimals
    1194          14 :                     rParent.AddToCode( ' ' );
    1195             :                 }
    1196             : 
    1197             :                 //! build string and add at once
    1198             : 
    1199             :                 sal_Int32 i;
    1200          34 :                 for (i=0; i<aNumInfo.nNumerDigits; i++)
    1201             :                 {
    1202          20 :                     rParent.AddToCode( '?' );
    1203             :                 }
    1204          14 :                 rParent.AddToCode( '/' );
    1205          14 :                 if ( aNumInfo.nFracDenominator > 0 )
    1206             :                 {
    1207           0 :                     rParent.AddToCode(  OUString::number( aNumInfo.nFracDenominator ) );
    1208             :                 }
    1209             :                 else
    1210             :                 {
    1211          34 :                     for (i=0; i<aNumInfo.nDenomDigits; i++)
    1212             :                     {
    1213          20 :                         rParent.AddToCode( '?');
    1214             :                     }
    1215             :                 }
    1216             :             }
    1217          14 :             break;
    1218             : 
    1219             :         case XML_TOK_STYLE_SCIENTIFIC_NUMBER:
    1220             :             {
    1221          68 :                 rParent.AddNumber( aNumInfo );      // simple number
    1222             : 
    1223          68 :                 rParent.AddToCode( OUString("E+") );
    1224         190 :                 for (sal_Int32 i=0; i<aNumInfo.nExpDigits; i++)
    1225             :                 {
    1226         122 :                     rParent.AddToCode( '0' );
    1227             :                 }
    1228             :             }
    1229          68 :             break;
    1230             : 
    1231             :         default:
    1232             :             OSL_FAIL("invalid element ID");
    1233             :     }
    1234        9524 : }
    1235             : 
    1236         636 : sal_uInt16 SvXMLNumFmtDefaults::GetDefaultDateFormat( SvXMLDateElementAttributes eDOW,
    1237             :                 SvXMLDateElementAttributes eDay, SvXMLDateElementAttributes eMonth,
    1238             :                 SvXMLDateElementAttributes eYear, SvXMLDateElementAttributes eHours,
    1239             :                 SvXMLDateElementAttributes eMins, SvXMLDateElementAttributes eSecs,
    1240             :                 bool bSystem )
    1241             : {
    1242             :     static const sal_uInt16 nCount = sizeof(aDefaultDateFormats) / sizeof(SvXMLDefaultDateFormat);
    1243        4026 :     for (sal_uInt16 nPos=0; nPos<nCount; nPos++)
    1244             :     {
    1245        3958 :         const SvXMLDefaultDateFormat& rEntry = aDefaultDateFormats[nPos];
    1246        6584 :         if ( bSystem == rEntry.bSystem &&
    1247        5252 :             ( eDOW   == rEntry.eDOW   || ( rEntry.eDOW   == XML_DEA_ANY && eDOW   != XML_DEA_NONE ) ) &&
    1248        4672 :             ( eDay   == rEntry.eDay   || ( rEntry.eDay   == XML_DEA_ANY && eDay   != XML_DEA_NONE ) ) &&
    1249        2848 :             ( eMonth == rEntry.eMonth || ( rEntry.eMonth == XML_DEA_ANY && eMonth != XML_DEA_NONE ) ) &&
    1250        1392 :             ( eYear  == rEntry.eYear  || ( rEntry.eYear  == XML_DEA_ANY && eYear  != XML_DEA_NONE ) ) &&
    1251        1240 :             ( eHours == rEntry.eHours || ( rEntry.eHours == XML_DEA_ANY && eHours != XML_DEA_NONE ) ) &&
    1252        1136 :             ( eMins  == rEntry.eMins  || ( rEntry.eMins  == XML_DEA_ANY && eMins  != XML_DEA_NONE ) ) &&
    1253         568 :             ( eSecs  == rEntry.eSecs  || ( rEntry.eSecs  == XML_DEA_ANY && eSecs  != XML_DEA_NONE ) ) )
    1254             :         {
    1255         568 :             return sal::static_int_cast< sal_uInt16 >(rEntry.eFormat);
    1256             :         }
    1257             :     }
    1258             : 
    1259          68 :     return NF_INDEX_TABLE_ENTRIES;  // invalid
    1260             : }
    1261             : 
    1262             : 
    1263             : //  SvXMLNumFormatContext
    1264             : 
    1265             : 
    1266        3636 : SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
    1267             :                                     sal_uInt16 nPrfx, const OUString& rLName,
    1268             :                                     SvXMLNumImpData* pNewData, sal_uInt16 nNewType,
    1269             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList,
    1270             :                                     SvXMLStylesContext& rStyles ) :
    1271             :     SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList ),
    1272             :     pData( pNewData ),
    1273             :     pStyles( &rStyles ),
    1274             :     aMyConditions(),
    1275             :     nType( nNewType ),
    1276             :     nKey(-1),
    1277             :     nFormatLang( LANGUAGE_SYSTEM ),
    1278             :     bAutoOrder( false ),
    1279             :     bFromSystem( false ),
    1280             :     bTruncate( true ),
    1281             :     bAutoDec( false ),
    1282             :     bAutoInt( false ),
    1283             :     bHasExtraText( false ),
    1284             :     bHasLongDoW( false ),
    1285             :     bHasEra( false ),
    1286             :     bHasDateTime( false ),
    1287             :     bRemoveAfterUse( false ),
    1288             :     eDateDOW( XML_DEA_NONE ),
    1289             :     eDateDay( XML_DEA_NONE ),
    1290             :     eDateMonth( XML_DEA_NONE ),
    1291             :     eDateYear( XML_DEA_NONE ),
    1292             :     eDateHours( XML_DEA_NONE ),
    1293             :     eDateMins( XML_DEA_NONE ),
    1294             :     eDateSecs( XML_DEA_NONE ),
    1295        3636 :     bDateNoDefault( false )
    1296             : {
    1297        3636 :     LanguageTagODF aLanguageTagODF;
    1298        7272 :     OUString sNatNumAttrScript, sNatNumAttrRfcLanguageTag;
    1299        7272 :     ::com::sun::star::i18n::NativeNumberXmlAttributes aNatNumAttr;
    1300        3636 :     bool bAttrBool(false);
    1301             :     sal_uInt16 nAttrEnum;
    1302             : 
    1303        3636 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1304       10256 :     for( sal_Int16 i=0; i < nAttrCount; i++ )
    1305             :     {
    1306        6620 :         OUString sAttrName = xAttrList->getNameByIndex( i );
    1307       13240 :         OUString sValue = xAttrList->getValueByIndex( i );
    1308       13240 :         OUString aLocalName;
    1309        6620 :         sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
    1310             : 
    1311        6620 :         const SvXMLTokenMap& rTokenMap = pData->GetStyleAttrTokenMap();
    1312        6620 :         sal_uInt16 nToken = rTokenMap.Get( nPrefix, aLocalName );
    1313        6620 :         switch (nToken)
    1314             :         {
    1315             :             case XML_TOK_STYLE_ATTR_NAME:
    1316        3636 :                 break;
    1317             :             case XML_TOK_STYLE_ATTR_RFC_LANGUAGE_TAG:
    1318           0 :                 aLanguageTagODF.maRfcLanguageTag = sValue;
    1319           0 :                 break;
    1320             :             case XML_TOK_STYLE_ATTR_LANGUAGE:
    1321         770 :                 aLanguageTagODF.maLanguage = sValue;
    1322         770 :                 break;
    1323             :             case XML_TOK_STYLE_ATTR_SCRIPT:
    1324           0 :                 aLanguageTagODF.maScript = sValue;
    1325           0 :                 break;
    1326             :             case XML_TOK_STYLE_ATTR_COUNTRY:
    1327         770 :                 aLanguageTagODF.maCountry = sValue;
    1328         770 :                 break;
    1329             :             case XML_TOK_STYLE_ATTR_TITLE:
    1330           0 :                 sFormatTitle = sValue;
    1331           0 :                 break;
    1332             :             case XML_TOK_STYLE_ATTR_AUTOMATIC_ORDER:
    1333         260 :                 if (::sax::Converter::convertBool( bAttrBool, sValue ))
    1334         260 :                     bAutoOrder = bAttrBool;
    1335         260 :                 break;
    1336             :             case XML_TOK_STYLE_ATTR_FORMAT_SOURCE:
    1337           4 :                 if ( SvXMLUnitConverter::convertEnum( nAttrEnum, sValue, aFormatSourceMap ) )
    1338           4 :                     bFromSystem = (bool) nAttrEnum;
    1339           4 :                 break;
    1340             :             case XML_TOK_STYLE_ATTR_TRUNCATE_ON_OVERFLOW:
    1341          20 :                 if (::sax::Converter::convertBool( bAttrBool, sValue ))
    1342          20 :                     bTruncate = bAttrBool;
    1343          20 :                 break;
    1344             :             case XML_TOK_STYLE_ATTR_VOLATILE:
    1345             :                 //  volatile formats can be removed after importing
    1346             :                 //  if not used in other styles
    1347        1116 :                 if (::sax::Converter::convertBool( bAttrBool, sValue ))
    1348        1116 :                     bRemoveAfterUse = bAttrBool;
    1349        1116 :                 break;
    1350             :             case XML_TOK_STYLE_ATTR_TRANSL_FORMAT:
    1351           2 :                 aNatNumAttr.Format = sValue;
    1352           2 :                 break;
    1353             :             case XML_TOK_STYLE_ATTR_TRANSL_RFC_LANGUAGE_TAG:
    1354           0 :                 sNatNumAttrRfcLanguageTag = sValue;
    1355           0 :                 break;
    1356             :             case XML_TOK_STYLE_ATTR_TRANSL_LANGUAGE:
    1357           2 :                 aNatNumAttr.Locale.Language = sValue;
    1358           2 :                 break;
    1359             :             case XML_TOK_STYLE_ATTR_TRANSL_SCRIPT:
    1360           0 :                 sNatNumAttrScript = sValue;
    1361           0 :                 break;
    1362             :             case XML_TOK_STYLE_ATTR_TRANSL_COUNTRY:
    1363           2 :                 aNatNumAttr.Locale.Country = sValue;
    1364           2 :                 break;
    1365             :             case XML_TOK_STYLE_ATTR_TRANSL_STYLE:
    1366           2 :                 aNatNumAttr.Style = sValue;
    1367           2 :                 break;
    1368             :         }
    1369        6620 :     }
    1370             : 
    1371        3636 :     if (!aLanguageTagODF.isEmpty())
    1372             :     {
    1373         770 :         nFormatLang = aLanguageTagODF.getLanguageTag().getLanguageType( false);
    1374         770 :         if ( nFormatLang == LANGUAGE_DONTKNOW )
    1375           0 :             nFormatLang = LANGUAGE_SYSTEM;          //! error handling for unknown locales?
    1376             :     }
    1377             : 
    1378        3636 :     if ( !aNatNumAttr.Format.isEmpty() )
    1379             :     {
    1380           2 :         SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    1381           2 :         if ( pFormatter )
    1382             :         {
    1383             :             LanguageTag aLanguageTag( sNatNumAttrRfcLanguageTag, aNatNumAttr.Locale.Language,
    1384           2 :                     sNatNumAttrScript, aNatNumAttr.Locale.Country);
    1385           2 :             aNatNumAttr.Locale = aLanguageTag.getLocale( false);
    1386             : 
    1387           2 :             sal_Int32 nNatNum = pFormatter->GetNatNum()->convertFromXmlAttributes( aNatNumAttr );
    1388           2 :             aFormatCode.append( "[NatNum" );
    1389           2 :             aFormatCode.append( nNatNum, 10 );
    1390             : 
    1391           2 :             LanguageType eLang = aLanguageTag.getLanguageType( false);
    1392           2 :             if ( eLang == LANGUAGE_DONTKNOW )
    1393           0 :                 eLang = LANGUAGE_SYSTEM;            //! error handling for unknown locales?
    1394           2 :             if ( eLang != nFormatLang && eLang != LANGUAGE_SYSTEM )
    1395             :             {
    1396           0 :                 aFormatCode.append( "][$-" );
    1397             :                 // language code in upper hex:
    1398           0 :                 aFormatCode.append(OUString::number(eLang, 16).toAsciiUpperCase());
    1399             :             }
    1400           2 :             aFormatCode.append( ']' );
    1401             :         }
    1402        3636 :     }
    1403        3636 : }
    1404             : 
    1405        1578 : SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
    1406             :                                     sal_uInt16 nPrfx, const OUString& rLName,
    1407             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList,
    1408             :                                     const sal_Int32 nTempKey,
    1409             :                                     SvXMLStylesContext& rStyles ) :
    1410             :     SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_DATA_STYLE ),
    1411             :     pData( NULL ),
    1412             :     pStyles( &rStyles ),
    1413             :     aMyConditions(),
    1414             :     nType( 0 ),
    1415             :     nKey(nTempKey),
    1416             :     nFormatLang( LANGUAGE_SYSTEM ),
    1417             :     bAutoOrder( false ),
    1418             :     bFromSystem( false ),
    1419             :     bTruncate( true ),
    1420             :     bAutoDec( false ),
    1421             :     bAutoInt( false ),
    1422             :     bHasExtraText( false ),
    1423             :     bHasLongDoW( false ),
    1424             :     bHasEra( false ),
    1425             :     bHasDateTime( false ),
    1426             :     bRemoveAfterUse( false ),
    1427             :     eDateDOW( XML_DEA_NONE ),
    1428             :     eDateDay( XML_DEA_NONE ),
    1429             :     eDateMonth( XML_DEA_NONE ),
    1430             :     eDateYear( XML_DEA_NONE ),
    1431             :     eDateHours( XML_DEA_NONE ),
    1432             :     eDateMins( XML_DEA_NONE ),
    1433             :     eDateSecs( XML_DEA_NONE ),
    1434        1578 :     bDateNoDefault( false )
    1435             : {
    1436        1578 :     SetAttribute(XML_NAMESPACE_STYLE, GetXMLToken(XML_NAME), rLName);
    1437        1578 : }
    1438             : 
    1439       10426 : SvXMLNumFormatContext::~SvXMLNumFormatContext()
    1440             : {
    1441       10426 : }
    1442             : 
    1443       11154 : SvXMLImportContext* SvXMLNumFormatContext::CreateChildContext(
    1444             :                                     sal_uInt16 nPrfx, const OUString& rLName,
    1445             :                                     const uno::Reference<xml::sax::XAttributeList>& xAttrList )
    1446             : {
    1447       11154 :     SvXMLImportContext* pContext = NULL;
    1448             : 
    1449       11154 :     const SvXMLTokenMap& rTokenMap = pData->GetStyleElemTokenMap();
    1450       11154 :     sal_uInt16 nToken = rTokenMap.Get( nPrfx, rLName );
    1451       11154 :     switch (nToken)
    1452             :     {
    1453             :         case XML_TOK_STYLE_TEXT:
    1454             :         case XML_TOK_STYLE_FILL_CHARACTER:
    1455             :         case XML_TOK_STYLE_NUMBER:
    1456             :         case XML_TOK_STYLE_SCIENTIFIC_NUMBER:
    1457             :         case XML_TOK_STYLE_FRACTION:
    1458             :         case XML_TOK_STYLE_CURRENCY_SYMBOL:
    1459             :         case XML_TOK_STYLE_DAY:
    1460             :         case XML_TOK_STYLE_MONTH:
    1461             :         case XML_TOK_STYLE_YEAR:
    1462             :         case XML_TOK_STYLE_ERA:
    1463             :         case XML_TOK_STYLE_DAY_OF_WEEK:
    1464             :         case XML_TOK_STYLE_WEEK_OF_YEAR:
    1465             :         case XML_TOK_STYLE_QUARTER:
    1466             :         case XML_TOK_STYLE_HOURS:
    1467             :         case XML_TOK_STYLE_AM_PM:
    1468             :         case XML_TOK_STYLE_MINUTES:
    1469             :         case XML_TOK_STYLE_SECONDS:
    1470             :         case XML_TOK_STYLE_BOOLEAN:
    1471             :         case XML_TOK_STYLE_TEXT_CONTENT:
    1472        9524 :             pContext = new SvXMLNumFmtElementContext( GetImport(), nPrfx, rLName,
    1473        9524 :                                                         *this, nToken, xAttrList );
    1474        9524 :             break;
    1475             : 
    1476             :         case XML_TOK_STYLE_PROPERTIES:
    1477         514 :             pContext = new SvXMLNumFmtPropContext( GetImport(), nPrfx, rLName,
    1478         514 :                                                         *this, xAttrList );
    1479         514 :             break;
    1480             :         case XML_TOK_STYLE_MAP:
    1481             :             {
    1482             :                 //  SvXMLNumFmtMapContext::EndElement adds to aMyConditions,
    1483             :                 //  so there's no need for an extra flag
    1484        1116 :                 pContext = new SvXMLNumFmtMapContext( GetImport(), nPrfx, rLName,
    1485        1116 :                                                             *this, xAttrList );
    1486             :             }
    1487        1116 :             break;
    1488             :     }
    1489             : 
    1490       11154 :     if( !pContext )
    1491           0 :         pContext = new SvXMLImportContext( GetImport(), nPrfx, rLName );
    1492       11154 :     return pContext;
    1493             : }
    1494             : 
    1495        2124 : sal_Int32 SvXMLNumFormatContext::GetKey()
    1496             : {
    1497        2124 :     if (nKey > -1)
    1498             :     {
    1499        1188 :         if (bRemoveAfterUse)
    1500             :         {
    1501             :             //  format is used -> don't remove
    1502           0 :             bRemoveAfterUse = false;
    1503           0 :             if (pData)
    1504           0 :                 pData->SetUsed(nKey);
    1505             : 
    1506             :             //  Add to import's list of keys now - CreateAndInsert didn't add
    1507             :             //  the style if bRemoveAfterUse was set.
    1508           0 :             GetImport().AddNumberStyle( nKey, GetName() );
    1509             :         }
    1510        1188 :         return nKey;
    1511             :     }
    1512             :     else
    1513             :     {
    1514             :         // reset bRemoveAfterUse before CreateAndInsert, so AddKey is called without bRemoveAfterUse set
    1515         936 :         bRemoveAfterUse = false;
    1516         936 :         CreateAndInsert(true);
    1517         936 :         return nKey;
    1518             :     }
    1519             : }
    1520             : 
    1521        1116 : sal_Int32 SvXMLNumFormatContext::PrivateGetKey()
    1522             : {
    1523             :     //  used for map elements in CreateAndInsert - don't reset bRemoveAfterUse flag
    1524             : 
    1525        1116 :     if (nKey > -1)
    1526        1090 :         return nKey;
    1527             :     else
    1528             :     {
    1529          26 :         CreateAndInsert(true);
    1530          26 :         return nKey;
    1531             :     }
    1532             : }
    1533             : 
    1534           0 : sal_Int32 SvXMLNumFormatContext::CreateAndInsert( com::sun::star::uno::Reference< com::sun::star::util::XNumberFormatsSupplier >& xFormatsSupplier )
    1535             : {
    1536           0 :     if (nKey <= -1)
    1537             :     {
    1538           0 :         SvNumberFormatter* pFormatter = NULL;
    1539             :         SvNumberFormatsSupplierObj* pObj =
    1540           0 :                         SvNumberFormatsSupplierObj::getImplementation( xFormatsSupplier );
    1541           0 :         if (pObj)
    1542           0 :             pFormatter = pObj->GetNumberFormatter();
    1543             : 
    1544           0 :         if ( pFormatter )
    1545           0 :             return CreateAndInsert( pFormatter );
    1546             :         else
    1547           0 :             return -1;
    1548             :     }
    1549             :     else
    1550           0 :         return nKey;
    1551             : }
    1552             : 
    1553        3630 : void SvXMLNumFormatContext::CreateAndInsert(bool /*bOverwrite*/)
    1554             : {
    1555        3630 :     if (!(nKey > -1))
    1556        3630 :         CreateAndInsert(pData->GetNumberFormatter());
    1557        3630 : }
    1558             : 
    1559        3630 : sal_Int32 SvXMLNumFormatContext::CreateAndInsert(SvNumberFormatter* pFormatter)
    1560             : {
    1561        3630 :     if (!pFormatter)
    1562             :     {
    1563             :         OSL_FAIL("no number formatter");
    1564           0 :         return -1;
    1565             :     }
    1566             : 
    1567        3630 :     sal_uInt32 nIndex = NUMBERFORMAT_ENTRY_NOT_FOUND;
    1568             : 
    1569        4746 :     for (sal_uInt32 i = 0; i < aMyConditions.size(); i++)
    1570             :     {
    1571             :         SvXMLNumFormatContext* pStyle = const_cast<SvXMLNumFormatContext*>( static_cast<const SvXMLNumFormatContext *>(pStyles->FindStyleChildContext(
    1572        1116 :             XML_STYLE_FAMILY_DATA_STYLE, aMyConditions[i].sMapName, false)));
    1573        1116 :         if (pStyle)
    1574             :         {
    1575        1116 :             if ((pStyle->PrivateGetKey() > -1))     // don't reset pStyle's bRemoveAfterUse flag
    1576        1116 :                 AddCondition(i);
    1577             :         }
    1578             :     }
    1579             : 
    1580        3630 :     if ( aFormatCode.isEmpty() )
    1581             :     {
    1582             :         //  insert empty format as empty string (with quotes)
    1583             :         //  #93901# this check has to be done before inserting the conditions
    1584          26 :         aFormatCode.appendAscii("\"\"");    // ""
    1585             :     }
    1586             : 
    1587        3630 :     aFormatCode.insert( 0, aConditions.makeStringAndClear() );
    1588        3630 :     OUString sFormat = aFormatCode.makeStringAndClear();
    1589             : 
    1590             :     //  test special cases
    1591             : 
    1592        3630 :     if ( bAutoDec )         // automatic decimal places
    1593             :     {
    1594             :         //  #99391# adjust only if the format contains no text elements, no conditions
    1595             :         //  and no color definition (detected by the '[' at the start)
    1596             : 
    1597        2190 :         if ( nType == XML_TOK_STYLES_NUMBER_STYLE && !bHasExtraText &&
    1598        1632 :                 aMyConditions.empty() && sFormat.toChar() != '[' )
    1599         540 :             nIndex = pFormatter->GetStandardIndex( nFormatLang );
    1600             :     }
    1601        3630 :     if ( bAutoInt )         // automatic integer digits
    1602             :     {
    1603             :         //! only if two decimal places was set?
    1604             : 
    1605           0 :         if ( nType == XML_TOK_STYLES_NUMBER_STYLE && !bHasExtraText &&
    1606           0 :                 aMyConditions.empty() && sFormat.toChar() != '[' )
    1607           0 :             nIndex = pFormatter->GetFormatIndex( NF_NUMBER_SYSTEM, nFormatLang );
    1608             :     }
    1609             : 
    1610             :     //  boolean is always the builtin boolean format
    1611             :     //  (no other boolean formats are implemented)
    1612        3630 :     if ( nType == XML_TOK_STYLES_BOOLEAN_STYLE )
    1613          26 :         nIndex = pFormatter->GetFormatIndex( NF_BOOLEAN, nFormatLang );
    1614             : 
    1615             :     //  check for default date formats
    1616        3630 :     if ( nType == XML_TOK_STYLES_DATE_STYLE && bAutoOrder && !bDateNoDefault )
    1617             :     {
    1618             :         NfIndexTableOffset eFormat = (NfIndexTableOffset) SvXMLNumFmtDefaults::GetDefaultDateFormat(
    1619             :             eDateDOW, eDateDay, eDateMonth, eDateYear,
    1620         258 :             eDateHours, eDateMins, eDateSecs, bFromSystem );
    1621         258 :         if ( eFormat < NF_INDEX_TABLE_LOCALE_DATA_DEFAULTS )
    1622             :         {
    1623             :             //  #109651# if a date format has the automatic-order attribute and
    1624             :             //  contains exactly the elements of one of the default date formats,
    1625             :             //  use that default format, with the element order and separators
    1626             :             //  from the current locale settings
    1627             : 
    1628         190 :             nIndex = pFormatter->GetFormatIndex( eFormat, nFormatLang );
    1629             :         }
    1630             :     }
    1631             : 
    1632        3630 :     if ( nIndex == NUMBERFORMAT_ENTRY_NOT_FOUND && !sFormat.isEmpty() )
    1633             :     {
    1634             :         //  insert by format string
    1635             : 
    1636        2874 :         OUString aFormatStr( sFormat );
    1637        2874 :         nIndex = pFormatter->GetEntryKey( aFormatStr, nFormatLang );
    1638        2874 :         if ( nIndex == NUMBERFORMAT_ENTRY_NOT_FOUND )
    1639             :         {
    1640        2074 :             sal_Int32  nErrPos = 0;
    1641        2074 :             short       l_nType = 0;
    1642        2074 :             bool bOk = pFormatter->PutEntry( aFormatStr, nErrPos, l_nType, nIndex, nFormatLang );
    1643        2074 :             if ( !bOk && nErrPos == 0 && aFormatStr != sFormat )
    1644             :             {
    1645             :                 //  if the string was modified by PutEntry, look for an existing format
    1646             :                 //  with the modified string
    1647           2 :                 nIndex = pFormatter->GetEntryKey( aFormatStr, nFormatLang );
    1648           2 :                 if ( nIndex != NUMBERFORMAT_ENTRY_NOT_FOUND )
    1649           2 :                     bOk = true;
    1650             :             }
    1651        2074 :             if (!bOk)
    1652           4 :                 nIndex = NUMBERFORMAT_ENTRY_NOT_FOUND;
    1653        2874 :         }
    1654             :     }
    1655             : 
    1656             : //! I18N doesn't provide SYSTEM or extended date information yet
    1657        3630 :     if ( nIndex != NUMBERFORMAT_ENTRY_NOT_FOUND && !bAutoOrder )
    1658             :     {
    1659             :         //  use fixed-order formats instead of SYS... if bAutoOrder is false
    1660             :         //  (only if the format strings are equal for the locale)
    1661             : 
    1662        3368 :         NfIndexTableOffset eOffset = pFormatter->GetIndexTableOffset( nIndex );
    1663        3368 :         if ( eOffset == NF_DATE_SYS_DMMMYYYY )
    1664             :         {
    1665           0 :             sal_uInt32 nNewIndex = pFormatter->GetFormatIndex( NF_DATE_DIN_DMMMYYYY, nFormatLang );
    1666           0 :             const SvNumberformat* pOldEntry = pFormatter->GetEntry( nIndex );
    1667           0 :             const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewIndex );
    1668           0 :             if ( pOldEntry && pNewEntry && pOldEntry->GetFormatstring() == pNewEntry->GetFormatstring() )
    1669           0 :                 nIndex = nNewIndex;
    1670             :         }
    1671        3368 :         else if ( eOffset == NF_DATE_SYS_DMMMMYYYY )
    1672             :         {
    1673           0 :             sal_uInt32 nNewIndex = pFormatter->GetFormatIndex( NF_DATE_DIN_DMMMMYYYY, nFormatLang );
    1674           0 :             const SvNumberformat* pOldEntry = pFormatter->GetEntry( nIndex );
    1675           0 :             const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewIndex );
    1676           0 :             if ( pOldEntry && pNewEntry && pOldEntry->GetFormatstring() == pNewEntry->GetFormatstring() )
    1677           0 :                 nIndex = nNewIndex;
    1678             :         }
    1679             :     }
    1680             : 
    1681        3630 :     if ((nIndex != NUMBERFORMAT_ENTRY_NOT_FOUND) && !sFormatTitle.isEmpty())
    1682             :     {
    1683           0 :         SvNumberformat* pFormat = const_cast<SvNumberformat*>(pFormatter->GetEntry( nIndex ));
    1684           0 :         if (pFormat)
    1685             :         {
    1686           0 :             pFormat->SetComment(sFormatTitle);
    1687             :         }
    1688             :     }
    1689             : 
    1690        3630 :     if ( nIndex == NUMBERFORMAT_ENTRY_NOT_FOUND )
    1691             :     {
    1692             :         OSL_FAIL("invalid number format");
    1693           4 :         nIndex = pFormatter->GetStandardIndex( nFormatLang );
    1694             :     }
    1695             : 
    1696        3630 :     pData->AddKey( nIndex, GetName(), bRemoveAfterUse );
    1697        3630 :     nKey = nIndex;
    1698             : 
    1699             :     //  Add to import's list of keys (shared between styles and content import)
    1700             :     //  only if not volatile - formats are removed from NumberFormatter at the
    1701             :     //  end of each import (in SvXMLNumFmtHelper dtor).
    1702             :     //  If bRemoveAfterUse is reset later in GetKey, AddNumberStyle is called there.
    1703             : 
    1704        3630 :     if (!bRemoveAfterUse)
    1705        2514 :         GetImport().AddNumberStyle( nKey, GetName() );
    1706             : 
    1707        3630 :     return nKey;
    1708             : }
    1709             : 
    1710        2670 : void SvXMLNumFormatContext::Finish( bool bOverwrite )
    1711             : {
    1712        2670 :     SvXMLStyleContext::Finish( bOverwrite );
    1713        2670 : }
    1714             : 
    1715        2022 : const LocaleDataWrapper& SvXMLNumFormatContext::GetLocaleData() const
    1716             : {
    1717        2022 :     return pData->GetLocaleData( nFormatLang );
    1718             : }
    1719             : 
    1720         692 : void SvXMLNumFormatContext::AddToCode( sal_Unicode c )
    1721             : {
    1722         692 :     aFormatCode.append( c );
    1723         692 :     bHasExtraText = true;
    1724         692 : }
    1725             : 
    1726        3828 : void SvXMLNumFormatContext::AddToCode( const OUString& rString )
    1727             : {
    1728        3828 :     aFormatCode.append( rString );
    1729        3828 :     bHasExtraText = true;
    1730        3828 : }
    1731             : 
    1732        2740 : void SvXMLNumFormatContext::AddNumber( const SvXMLNumberInfo& rInfo )
    1733             : {
    1734        2740 :     SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    1735        2740 :     if (!pFormatter)
    1736         552 :         return;
    1737             : 
    1738             :     //  store special conditions
    1739        2740 :     bAutoDec = ( rInfo.nDecimals < 0 );
    1740        2740 :     bAutoInt = ( rInfo.nInteger < 0 );
    1741             : 
    1742        2740 :     sal_uInt16 nPrec = 0;
    1743        2740 :     sal_uInt16 nLeading = 0;
    1744        2740 :     if ( rInfo.nDecimals >= 0 )                     //  < 0 : Default
    1745        2188 :         nPrec = (sal_uInt16) rInfo.nDecimals;
    1746        2740 :     if ( rInfo.nInteger >= 0 )                      //  < 0 : Default
    1747        2740 :         nLeading = (sal_uInt16) rInfo.nInteger;
    1748             : 
    1749        2740 :     if ( bAutoDec )
    1750             :     {
    1751         552 :         if ( nType == XML_TOK_STYLES_CURRENCY_STYLE )
    1752             :         {
    1753             :             //  for currency formats, "automatic decimals" is used for the automatic
    1754             :             //  currency format with (fixed) decimals from the locale settings
    1755             : 
    1756           0 :             const LocaleDataWrapper& rLoc = pData->GetLocaleData( nFormatLang );
    1757           0 :             nPrec = rLoc.getCurrDigits();
    1758             :         }
    1759             :         else
    1760             :         {
    1761             :             //  for other types, "automatic decimals" means dynamic determination of
    1762             :             //  decimals, as achieved with the "general" keyword
    1763             : 
    1764         552 :             aFormatCode.append( pFormatter->GetStandardName( nFormatLang ) );
    1765         552 :             return;
    1766             :         }
    1767             :     }
    1768        2188 :     if ( bAutoInt )
    1769             :     {
    1770             :         //!...
    1771             :     }
    1772             : 
    1773        2188 :     sal_uInt16 nGenPrec = nPrec;
    1774        2188 :     if ( rInfo.bDecReplace || rInfo.bVarDecimals )
    1775           6 :         nGenPrec = 0;               // generate format without decimals...
    1776             : 
    1777        2188 :     bool bGrouping = rInfo.bGrouping;
    1778        2188 :     sal_uInt16 nEmbeddedCount = rInfo.aEmbeddedElements.size();
    1779        2188 :     if ( nEmbeddedCount )
    1780           0 :         bGrouping = false;      // grouping and embedded characters can't be used together
    1781             : 
    1782        2188 :     sal_uInt32 nStdIndex = pFormatter->GetStandardIndex( nFormatLang );
    1783             :     OUStringBuffer aNumStr = pFormatter->GenerateFormat( nStdIndex, nFormatLang,
    1784        2188 :                                                          bGrouping, false, nGenPrec, nLeading );
    1785             : 
    1786        2188 :     if ( rInfo.nExpDigits >= 0 && nLeading == 0 && !bGrouping && nEmbeddedCount == 0 )
    1787             :     {
    1788             :         // #i43959# For scientific numbers, "#" in the integer part forces a digit,
    1789             :         // so it has to be removed if nLeading is 0 (".00E+0", not "#.00E+0").
    1790             : 
    1791           0 :         aNumStr.stripStart('#');
    1792             :     }
    1793             : 
    1794        2188 :     if ( nEmbeddedCount )
    1795             :     {
    1796             :         //  insert embedded strings into number string
    1797             :         //  only the integer part is supported
    1798             :         //  nZeroPos is the string position where format position 0 is inserted
    1799             : 
    1800           0 :         sal_Int32 nZeroPos = aNumStr.indexOf( pData->GetLocaleData( nFormatLang ).getNumDecimalSep() );
    1801           0 :         if ( nZeroPos < 0 )
    1802             :         {
    1803           0 :             nZeroPos = aNumStr.getLength();
    1804             :         }
    1805             : 
    1806             :         //  aEmbeddedElements is sorted - last entry has the largest position (leftmost)
    1807           0 :         const SvXMLEmbeddedElement* pLastObj = &*rInfo.aEmbeddedElements.rbegin();
    1808           0 :         sal_Int32 nLastFormatPos = pLastObj->nFormatPos;
    1809           0 :         if ( nLastFormatPos >= nZeroPos )
    1810             :         {
    1811             :             //  add '#' characters so all embedded texts are really embedded in digits
    1812             :             //  (there always has to be a digit before the leftmost embedded text)
    1813             : 
    1814           0 :             sal_Int32 nAddCount = nLastFormatPos + 1 - nZeroPos;
    1815           0 :             for(sal_Int32 index = 0; index < nAddCount; ++index)
    1816             :             {
    1817           0 :                 aNumStr.insert(0, '#');
    1818             :             }
    1819           0 :             nZeroPos = nZeroPos + nAddCount;
    1820             :         }
    1821             : 
    1822             :         //  aEmbeddedElements is sorted with ascending positions - loop is from right to left
    1823           0 :         for (SvXMLEmbeddedElementArr::const_iterator it = rInfo.aEmbeddedElements.begin();
    1824           0 :              it != rInfo.aEmbeddedElements.end(); ++it)
    1825             :         {
    1826           0 :             const SvXMLEmbeddedElement* pObj = &*it;
    1827           0 :             sal_Int32 nFormatPos = pObj->nFormatPos;
    1828           0 :             sal_Int32 nInsertPos = nZeroPos - nFormatPos;
    1829           0 :             if ( nFormatPos >= 0 && nInsertPos >= 0 )
    1830             :             {
    1831             :                 //  #107805# always quote embedded strings - even space would otherwise
    1832             :                 //  be recognized as thousands separator in French.
    1833             : 
    1834           0 :                 aNumStr.insert(nInsertPos, '"');
    1835           0 :                 aNumStr.insert(nInsertPos, pObj->aText);
    1836           0 :                 aNumStr.insert(nInsertPos, '"');
    1837             :             }
    1838             :         }
    1839             :     }
    1840             : 
    1841        2188 :     aFormatCode.append( aNumStr.makeStringAndClear() );
    1842             : 
    1843        2188 :     if ( ( rInfo.bDecReplace || rInfo.bVarDecimals ) && nPrec )     // add decimal replacement (dashes)
    1844             :     {
    1845             :         //  add dashes for explicit decimal replacement, # for variable decimals
    1846           6 :         sal_Unicode cAdd = rInfo.bDecReplace ? '-' : '#';
    1847             : 
    1848           6 :         aFormatCode.append( pData->GetLocaleData( nFormatLang ).getNumDecimalSep() );
    1849          18 :         for ( sal_uInt16 i=0; i<nPrec; i++)
    1850          12 :             aFormatCode.append( cAdd );
    1851             :     }
    1852             : 
    1853             :     //  add extra thousands separators for display factor
    1854             : 
    1855        2188 :     if ( rInfo.fDisplayFactor != 1.0 && rInfo.fDisplayFactor > 0.0 )
    1856             :     {
    1857             :         //  test for 1.0 is just for optimization - nSepCount would be 0
    1858             : 
    1859             :         //  one separator for each factor of 1000
    1860          32 :         sal_Int32 nSepCount = (sal_Int32) ::rtl::math::round( log10(rInfo.fDisplayFactor) / 3.0 );
    1861          32 :         if ( nSepCount > 0 )
    1862             :         {
    1863          32 :             OUString aSep = pData->GetLocaleData( nFormatLang ).getNumThousandSep();
    1864          64 :             for ( sal_Int32 i=0; i<nSepCount; i++ )
    1865          64 :                 aFormatCode.append( aSep );
    1866             :         }
    1867        2188 :     }
    1868             : }
    1869             : 
    1870         922 : void SvXMLNumFormatContext::AddCurrency( const OUString& rContent, LanguageType nLang )
    1871             : {
    1872         922 :     bool bAutomatic = false;
    1873         922 :     OUString aSymbol = rContent;
    1874         922 :     if ( aSymbol.isEmpty())
    1875             :     {
    1876         148 :         SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    1877         148 :         if ( pFormatter )
    1878             :         {
    1879         148 :             pFormatter->ChangeIntl( nFormatLang );
    1880         296 :             OUString sCurString, sDummy;
    1881         148 :             pFormatter->GetCompatibilityCurrency( sCurString, sDummy );
    1882         148 :             aSymbol = sCurString;
    1883             : 
    1884         296 :             bAutomatic = true;
    1885             :         }
    1886             :     }
    1887         774 :     else if ( nLang == LANGUAGE_SYSTEM && aSymbol.equalsAscii("CCC") )
    1888             :     {
    1889             :         //  "CCC" is used for automatic long symbol
    1890           0 :         bAutomatic = true;
    1891             :     }
    1892             : 
    1893         922 :     if ( bAutomatic )
    1894             :     {
    1895             :         //  remove unnecessary quotes before automatic symbol (formats like "-(0DM)")
    1896             :         //  otherwise the currency symbol isn't recognized (#94048#)
    1897             : 
    1898         148 :         sal_Int32 nLength = aFormatCode.getLength();
    1899         148 :         if ( nLength > 1 && aFormatCode[nLength - 1] == '"' )
    1900             :         {
    1901             :             //  find start of quoted string
    1902             :             //  When SvXMLNumFmtElementContext::EndElement creates escaped quotes,
    1903             :             //  they must be handled here, too.
    1904             : 
    1905           0 :             sal_Int32 nFirst = nLength - 2;
    1906           0 :             while ( nFirst >= 0 && aFormatCode[nFirst] != '"' )
    1907           0 :                 --nFirst;
    1908           0 :             if ( nFirst >= 0 )
    1909             :             {
    1910             :                 //  remove both quotes from aFormatCode
    1911           0 :                 OUString aOld = aFormatCode.makeStringAndClear();
    1912           0 :                 if ( nFirst > 0 )
    1913           0 :                     aFormatCode.append( aOld.copy( 0, nFirst ) );
    1914           0 :                 if ( nLength > nFirst + 2 )
    1915           0 :                     aFormatCode.append( aOld.copy( nFirst + 1, nLength - nFirst - 2 ) );
    1916             :             }
    1917             :         }
    1918             :     }
    1919             : 
    1920         922 :     if (!bAutomatic)
    1921         774 :         aFormatCode.appendAscii( "[$" );            // intro for "new" currency symbols
    1922             : 
    1923         922 :     aFormatCode.append( aSymbol );
    1924             : 
    1925         922 :     if (!bAutomatic)
    1926             :     {
    1927         774 :         if ( nLang != LANGUAGE_SYSTEM )
    1928             :         {
    1929             :             //  '-' sign and language code in hex:
    1930         742 :             aFormatCode.append("-" + OUString::number(sal_Int32(nLang), 16).toAsciiUpperCase());
    1931             :         }
    1932             : 
    1933         774 :         aFormatCode.append( ']' );    // end of "new" currency symbol
    1934         922 :     }
    1935         922 : }
    1936             : 
    1937        1774 : void SvXMLNumFormatContext::AddNfKeyword( sal_uInt16 nIndex )
    1938             : {
    1939        1774 :     SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    1940        1774 :     if (!pFormatter)
    1941        1774 :         return;
    1942             : 
    1943        1774 :     if ( nIndex == NF_KEY_G || nIndex == NF_KEY_GG || nIndex == NF_KEY_GGG )
    1944           4 :         bHasEra = true;
    1945             : 
    1946        1774 :     if ( nIndex == NF_KEY_NNNN )
    1947             :     {
    1948          10 :         nIndex = NF_KEY_NNN;
    1949          10 :         bHasLongDoW = true;         // to remove string constant with separator
    1950             :     }
    1951             : 
    1952        1774 :     OUString sKeyword = pFormatter->GetKeyword( nFormatLang, nIndex );
    1953             : 
    1954        1774 :     if ( nIndex == NF_KEY_H  || nIndex == NF_KEY_HH  ||
    1955        1580 :          nIndex == NF_KEY_MI || nIndex == NF_KEY_MMI ||
    1956        1346 :          nIndex == NF_KEY_S  || nIndex == NF_KEY_SS )
    1957             :     {
    1958         568 :         if ( !bTruncate && !bHasDateTime )
    1959             :         {
    1960             :             //  with truncate-on-overflow = false, add "[]" to first time part
    1961          20 :             aFormatCode.append("[" + sKeyword + "]");
    1962             :         }
    1963             :         else
    1964             :         {
    1965         548 :             aFormatCode.append( sKeyword );
    1966             :         }
    1967         568 :         bHasDateTime = true;
    1968             :     }
    1969             :     else
    1970             :     {
    1971        1206 :         aFormatCode.append( sKeyword );
    1972             :     }
    1973             :     //  collect the date elements that the format contains, to recognize default date formats
    1974        1774 :     switch ( nIndex )
    1975             :     {
    1976          14 :         case NF_KEY_NN:     eDateDOW = XML_DEA_SHORT;       break;
    1977             :         case NF_KEY_NNN:
    1978          10 :         case NF_KEY_NNNN:   eDateDOW = XML_DEA_LONG;        break;
    1979         176 :         case NF_KEY_D:      eDateDay = XML_DEA_SHORT;       break;
    1980         188 :         case NF_KEY_DD:     eDateDay = XML_DEA_LONG;        break;
    1981         100 :         case NF_KEY_M:      eDateMonth = XML_DEA_SHORT;     break;
    1982         172 :         case NF_KEY_MM:     eDateMonth = XML_DEA_LONG;      break;
    1983         104 :         case NF_KEY_MMM:    eDateMonth = XML_DEA_TEXTSHORT; break;
    1984          24 :         case NF_KEY_MMMM:   eDateMonth = XML_DEA_TEXTLONG;  break;
    1985         114 :         case NF_KEY_YY:     eDateYear = XML_DEA_SHORT;      break;
    1986         230 :         case NF_KEY_YYYY:   eDateYear = XML_DEA_LONG;       break;
    1987         130 :         case NF_KEY_H:      eDateHours = XML_DEA_SHORT;     break;
    1988          64 :         case NF_KEY_HH:     eDateHours = XML_DEA_LONG;      break;
    1989           0 :         case NF_KEY_MI:     eDateMins = XML_DEA_SHORT;      break;
    1990         234 :         case NF_KEY_MMI:    eDateMins = XML_DEA_LONG;       break;
    1991           0 :         case NF_KEY_S:      eDateSecs = XML_DEA_SHORT;      break;
    1992         140 :         case NF_KEY_SS:     eDateSecs = XML_DEA_LONG;       break;
    1993             :         case NF_KEY_AP:
    1994          66 :         case NF_KEY_AMPM:   break;          // AM/PM may or may not be in date/time formats -> ignore by itself
    1995             :         default:
    1996           8 :             bDateNoDefault = true;      // any other element -> no default format
    1997        1774 :     }
    1998             : }
    1999             : 
    2000          10 : static bool lcl_IsAtEnd( OUStringBuffer& rBuffer, const OUString& rToken )
    2001             : {
    2002          10 :     sal_Int32 nBufLen = rBuffer.getLength();
    2003          10 :     sal_Int32 nTokLen = rToken.getLength();
    2004             : 
    2005          10 :     if ( nTokLen > nBufLen )
    2006           0 :         return false;
    2007             : 
    2008          10 :     sal_Int32 nStartPos = nBufLen - nTokLen;
    2009          40 :     for ( sal_Int32 nTokPos = 0; nTokPos < nTokLen; nTokPos++ )
    2010          30 :         if ( rToken[ nTokPos ] != rBuffer[nStartPos + nTokPos] )
    2011           0 :             return false;
    2012             : 
    2013          10 :     return true;
    2014             : }
    2015             : 
    2016          10 : bool SvXMLNumFormatContext::ReplaceNfKeyword( sal_uInt16 nOld, sal_uInt16 nNew )
    2017             : {
    2018             :     //  replaces one keyword with another if it is found at the end of the code
    2019             : 
    2020          10 :     SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    2021          10 :     if (!pFormatter)
    2022           0 :         return false;
    2023             : 
    2024          10 :     OUString sOldStr = pFormatter->GetKeyword( nFormatLang, nOld );
    2025          10 :     if ( lcl_IsAtEnd( aFormatCode, sOldStr ) )
    2026             :     {
    2027             :         // remove old keyword
    2028          10 :         aFormatCode.setLength( aFormatCode.getLength() - sOldStr.getLength() );
    2029             : 
    2030             :         // add new keyword
    2031          10 :         OUString sNewStr = pFormatter->GetKeyword( nFormatLang, nNew );
    2032          10 :         aFormatCode.append( sNewStr );
    2033             : 
    2034          10 :         return true;    // changed
    2035             :     }
    2036           0 :     return false;       // not found
    2037             : }
    2038             : 
    2039        1116 : void SvXMLNumFormatContext::AddCondition( const sal_Int32 nIndex )
    2040             : {
    2041        1116 :     OUString rApplyName = aMyConditions[nIndex].sMapName;
    2042        2232 :     OUString rCondition = aMyConditions[nIndex].sCondition;
    2043        1116 :     SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    2044        1116 :     sal_uInt32 l_nKey = pData->GetKeyForName( rApplyName );
    2045        2232 :     OUString sValue("value()");        //! define constant
    2046        1116 :     sal_Int32 nValLen = sValue.getLength();
    2047             : 
    2048        4464 :     if ( pFormatter && l_nKey != NUMBERFORMAT_ENTRY_NOT_FOUND &&
    2049        4464 :             rCondition.copy( 0, nValLen ) == sValue )
    2050             :     {
    2051             :         //! test for valid conditions
    2052             :         //! test for default conditions
    2053             : 
    2054        1116 :         OUString sRealCond = rCondition.copy( nValLen, rCondition.getLength() - nValLen );
    2055        1116 :         bool bDefaultCond = false;
    2056             : 
    2057             :         //! collect all conditions first and adjust default to >=0, >0 or <0 depending on count
    2058             :         //! allow blanks in conditions
    2059        1116 :         if ( aConditions.isEmpty() && aMyConditions.size() == 1 && sRealCond.equalsAscii( ">=0" ) )
    2060         654 :             bDefaultCond = true;
    2061             : 
    2062        1116 :         if ( nType == XML_TOK_STYLES_TEXT_STYLE && nIndex == 2 )
    2063             :         {
    2064             :             //  The third condition in a number format with a text part can only be
    2065             :             //  "all other numbers", the condition string must be empty.
    2066         118 :             bDefaultCond = true;
    2067             :         }
    2068             : 
    2069        1116 :         if (!bDefaultCond)
    2070             :         {
    2071             :             // Convert != to <>
    2072         344 :             sal_Int32 nPos = sRealCond.indexOf( "!=" );
    2073         344 :             if ( nPos >= 0 )
    2074             :             {
    2075           4 :                 sRealCond = sRealCond.replaceAt( nPos, 2, "<>" );
    2076             :             }
    2077             : 
    2078         344 :             nPos = sRealCond.indexOf( '.' );
    2079         344 :             if ( nPos >= 0 )
    2080             :             {
    2081             :                 // #i8026# #103991# localize decimal separator
    2082           0 :                 const OUString& rDecSep = GetLocaleData().getNumDecimalSep();
    2083           0 :                 if ( rDecSep.getLength() > 1 || rDecSep[0] != '.' )
    2084             :                 {
    2085           0 :                     sRealCond = sRealCond.replaceAt( nPos, 1, rDecSep );
    2086             :                 }
    2087             :             }
    2088         344 :             aConditions.append("[" + sRealCond + "]");
    2089             :         }
    2090             : 
    2091        1116 :         const SvNumberformat* pFormat = pFormatter->GetEntry(l_nKey);
    2092        1116 :         if ( pFormat )
    2093        1116 :             aConditions.append( OUString( pFormat->GetFormatstring() ) );
    2094             : 
    2095        1116 :         aConditions.append( ';' );
    2096        1116 :     }
    2097        1116 : }
    2098             : 
    2099        1116 : void SvXMLNumFormatContext::AddCondition( const OUString& rCondition, const OUString& rApplyName )
    2100             : {
    2101        1116 :     MyCondition aCondition;
    2102        1116 :     aCondition.sCondition = rCondition;
    2103        1116 :     aCondition.sMapName = rApplyName;
    2104        1116 :     aMyConditions.push_back(aCondition);
    2105        1116 : }
    2106             : 
    2107         514 : void SvXMLNumFormatContext::AddColor( sal_uInt32 const nColor )
    2108             : {
    2109         514 :     SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
    2110         514 :     if (!pFormatter)
    2111         514 :         return;
    2112             : 
    2113         514 :     OUStringBuffer aColName;
    2114        2458 :     for ( sal_uInt16 i=0; i<XML_NUMF_COLORCOUNT; i++ )
    2115        2458 :         if (nColor == aNumFmtStdColors[i])
    2116             :         {
    2117         514 :             aColName = OUString( pFormatter->GetKeyword( nFormatLang, sal::static_int_cast< sal_uInt16 >(NF_KEY_FIRSTCOLOR + i) ) );
    2118         514 :             break;
    2119             :         }
    2120             : 
    2121         514 :     if ( !aColName.isEmpty() )
    2122             :     {
    2123         514 :         aColName.insert( 0, '[' );
    2124         514 :         aColName.append( ']' );
    2125         514 :         aFormatCode.insert( 0, aColName.makeStringAndClear() );
    2126         514 :     }
    2127             : }
    2128             : 
    2129        1140 : void SvXMLNumFormatContext::UpdateCalendar( const OUString& rNewCalendar )
    2130             : {
    2131        1140 :     if ( rNewCalendar != sCalendar )
    2132             :     {
    2133           4 :         sCalendar = rNewCalendar;
    2134           4 :         if ( !sCalendar.isEmpty() )
    2135             :         {
    2136           4 :             aFormatCode.appendAscii( "[~" );            // intro for calendar code
    2137           4 :             aFormatCode.append( sCalendar );
    2138           4 :             aFormatCode.append( ']' );    // end of "new" currency symbolcalendar code
    2139             :         }
    2140             :     }
    2141        1140 : }
    2142             : 
    2143          16 : bool SvXMLNumFormatContext::IsSystemLanguage()
    2144             : {
    2145          16 :     return nFormatLang == LANGUAGE_SYSTEM;
    2146             : }
    2147             : 
    2148             : 
    2149             : //  SvXMLNumFmtHelper
    2150             : 
    2151             : 
    2152        1558 : SvXMLNumFmtHelper::SvXMLNumFmtHelper(
    2153             :     const uno::Reference<util::XNumberFormatsSupplier>& rSupp,
    2154             :     const uno::Reference<uno::XComponentContext>& rxContext )
    2155             : {
    2156             :     DBG_ASSERT( rxContext.is(), "got no service manager" );
    2157             : 
    2158        1558 :     SvNumberFormatter* pFormatter = NULL;
    2159             :     SvNumberFormatsSupplierObj* pObj =
    2160        1558 :                     SvNumberFormatsSupplierObj::getImplementation( rSupp );
    2161        1558 :     if (pObj)
    2162        1558 :         pFormatter = pObj->GetNumberFormatter();
    2163             : 
    2164        1558 :     pData = new SvXMLNumImpData( pFormatter, rxContext );
    2165        1558 : }
    2166             : 
    2167         264 : SvXMLNumFmtHelper::SvXMLNumFmtHelper(
    2168             :     SvNumberFormatter* pNumberFormatter,
    2169             :     const uno::Reference<uno::XComponentContext>& rxContext )
    2170             : {
    2171             :     DBG_ASSERT( rxContext.is(), "got no service manager" );
    2172             : 
    2173         264 :     pData = new SvXMLNumImpData( pNumberFormatter, rxContext );
    2174         264 : }
    2175             : 
    2176        1822 : SvXMLNumFmtHelper::~SvXMLNumFmtHelper()
    2177             : {
    2178             :     //  remove temporary (volatile) formats from NumberFormatter
    2179        1822 :     pData->RemoveVolatileFormats();
    2180             : 
    2181        1822 :     delete pData;
    2182        1822 : }
    2183             : 
    2184       29406 : SvXMLStyleContext*  SvXMLNumFmtHelper::CreateChildContext( SvXMLImport& rImport,
    2185             :                 sal_uInt16 nPrefix, const OUString& rLocalName,
    2186             :                 const uno::Reference<xml::sax::XAttributeList>& xAttrList,
    2187             :                 SvXMLStylesContext& rStyles )
    2188             : {
    2189       29406 :     SvXMLStyleContext* pContext = NULL;
    2190             : 
    2191       29406 :     const SvXMLTokenMap& rTokenMap = pData->GetStylesElemTokenMap();
    2192       29406 :     sal_uInt16 nToken = rTokenMap.Get( nPrefix, rLocalName );
    2193       29406 :     switch (nToken)
    2194             :     {
    2195             :         case XML_TOK_STYLES_NUMBER_STYLE:
    2196             :         case XML_TOK_STYLES_CURRENCY_STYLE:
    2197             :         case XML_TOK_STYLES_PERCENTAGE_STYLE:
    2198             :         case XML_TOK_STYLES_DATE_STYLE:
    2199             :         case XML_TOK_STYLES_TIME_STYLE:
    2200             :         case XML_TOK_STYLES_BOOLEAN_STYLE:
    2201             :         case XML_TOK_STYLES_TEXT_STYLE:
    2202             :             pContext = new SvXMLNumFormatContext( rImport, nPrefix, rLocalName,
    2203        3634 :                                                     pData, nToken, xAttrList, rStyles );
    2204        3634 :             break;
    2205             :     }
    2206             : 
    2207             :     // return NULL if not a data style, caller must handle other elements
    2208       29406 :     return pContext;
    2209             : }
    2210             : 
    2211        2948 : const SvXMLTokenMap& SvXMLNumFmtHelper::GetStylesElemTokenMap()
    2212             : {
    2213        2948 :     return pData->GetStylesElemTokenMap();
    2214             : }
    2215             : 
    2216             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10