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

Generated by: LCOV version 1.10