LCOV - code coverage report
Current view: top level - xmloff/source/style - xmlnumfe.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 443 770 57.5 %
Date: 2012-08-25 Functions: 41 60 68.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 379 1260 30.1 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <comphelper/string.hxx>
      30                 :            : #include <svl/zforlist.hxx>
      31                 :            : #include <svl/zformat.hxx>
      32                 :            : #include <svl/numuno.hxx>
      33                 :            : #include <i18npool/mslangid.hxx>
      34                 :            : #include <tools/debug.hxx>
      35                 :            : #include <rtl/math.hxx>
      36                 :            : #include <unotools/calendarwrapper.hxx>
      37                 :            : #include <unotools/charclass.hxx>
      38                 :            : #include <com/sun/star/lang/Locale.hpp>
      39                 :            : #include <rtl/ustrbuf.hxx>
      40                 :            : #include <tools/color.hxx>
      41                 :            : #include <sax/tools/converter.hxx>
      42                 :            : 
      43                 :            : #include <com/sun/star/i18n/NativeNumberXmlAttributes.hpp>
      44                 :            : 
      45                 :            : #include <xmloff/xmlnumfe.hxx>
      46                 :            : #include "xmloff/xmlnmspe.hxx"
      47                 :            : #include <xmloff/attrlist.hxx>
      48                 :            : #include <xmloff/nmspmap.hxx>
      49                 :            : #include <xmloff/families.hxx>
      50                 :            : #include <xmloff/xmlnumfi.hxx>      // SvXMLNumFmtDefaults
      51                 :            : 
      52                 :            : #include <svl/nfsymbol.hxx>
      53                 :            : #include <xmloff/xmltoken.hxx>
      54                 :            : #include <xmloff/xmlexp.hxx>
      55                 :            : 
      56                 :            : #include <set>
      57                 :            : #include <boost/ptr_container/ptr_vector.hpp>
      58                 :            : 
      59                 :            : using ::rtl::OUString;
      60                 :            : using ::rtl::OUStringBuffer;
      61                 :            : 
      62                 :            : using namespace ::com::sun::star;
      63                 :            : using namespace ::xmloff::token;
      64                 :            : using namespace ::svt;
      65                 :            : 
      66                 :            : //-------------------------------------------------------------------------
      67                 :            : 
      68                 :            : #define XMLNUM_MAX_PARTS    3
      69                 :            : 
      70                 :            : //-------------------------------------------------------------------------
      71                 :            : 
      72                 :            : struct LessuInt32
      73                 :            : {
      74                 :        498 :     sal_Bool operator() (const sal_uInt32 rValue1, const sal_uInt32 rValue2) const
      75                 :            :     {
      76                 :        498 :         return rValue1 < rValue2;
      77                 :            :     }
      78                 :            : };
      79                 :            : 
      80                 :            : typedef std::set< sal_uInt32, LessuInt32 >  SvXMLuInt32Set;
      81                 :            : 
      82                 :            : class SvXMLNumUsedList_Impl
      83                 :            : {
      84                 :            :     SvXMLuInt32Set              aUsed;
      85                 :            :     SvXMLuInt32Set              aWasUsed;
      86                 :            :     SvXMLuInt32Set::iterator    aCurrentUsedPos;
      87                 :            :     sal_uInt32                  nUsedCount;
      88                 :            :     sal_uInt32                  nWasUsedCount;
      89                 :            : 
      90                 :            : public:
      91                 :            :             SvXMLNumUsedList_Impl();
      92                 :            :             ~SvXMLNumUsedList_Impl();
      93                 :            : 
      94                 :            :     void        SetUsed( sal_uInt32 nKey );
      95                 :            :     sal_Bool    IsUsed( sal_uInt32 nKey ) const;
      96                 :            :     sal_Bool    IsWasUsed( sal_uInt32 nKey ) const;
      97                 :            :     void        Export();
      98                 :            : 
      99                 :            :     sal_Bool    GetFirstUsed(sal_uInt32& nKey);
     100                 :            :     sal_Bool    GetNextUsed(sal_uInt32& nKey);
     101                 :            : 
     102                 :            :     void GetWasUsed(uno::Sequence<sal_Int32>& rWasUsed);
     103                 :            :     void SetWasUsed(const uno::Sequence<sal_Int32>& rWasUsed);
     104                 :            : };
     105                 :            : 
     106                 :            : //-------------------------------------------------------------------------
     107                 :            : 
     108                 :          0 : struct SvXMLEmbeddedTextEntry
     109                 :            : {
     110                 :            :     sal_uInt16      nSourcePos;     // position in NumberFormat (to skip later)
     111                 :            :     sal_Int32       nFormatPos;     // resulting position in embedded-text element
     112                 :            :     rtl::OUString   aText;
     113                 :            : 
     114                 :          0 :     SvXMLEmbeddedTextEntry( sal_uInt16 nSP, sal_Int32 nFP, const rtl::OUString& rT ) :
     115                 :          0 :         nSourcePos(nSP), nFormatPos(nFP), aText(rT) {}
     116                 :            : };
     117                 :            : 
     118                 :         66 : class SvXMLEmbeddedTextEntryArr : public boost::ptr_vector<SvXMLEmbeddedTextEntry> {};
     119                 :            : 
     120                 :            : //-------------------------------------------------------------------------
     121                 :            : 
     122                 :            : //
     123                 :            : //! SvXMLNumUsedList_Impl should be optimized!
     124                 :            : //
     125                 :            : 
     126                 :        489 : SvXMLNumUsedList_Impl::SvXMLNumUsedList_Impl() :
     127                 :            :     nUsedCount(0),
     128 [ +  - ][ +  - ]:        489 :     nWasUsedCount(0)
     129                 :            : {
     130                 :        489 : }
     131                 :            : 
     132                 :        489 : SvXMLNumUsedList_Impl::~SvXMLNumUsedList_Impl()
     133                 :            : {
     134                 :        489 : }
     135                 :            : 
     136                 :        138 : void SvXMLNumUsedList_Impl::SetUsed( sal_uInt32 nKey )
     137                 :            : {
     138         [ +  + ]:        138 :     if ( !IsWasUsed(nKey) )
     139                 :            :     {
     140         [ +  - ]:         83 :         std::pair<SvXMLuInt32Set::iterator, bool> aPair = aUsed.insert( nKey );
     141         [ +  + ]:         83 :         if (aPair.second)
     142                 :         83 :             nUsedCount++;
     143                 :            :     }
     144                 :        138 : }
     145                 :            : 
     146                 :         67 : sal_Bool SvXMLNumUsedList_Impl::IsUsed( sal_uInt32 nKey ) const
     147                 :            : {
     148         [ +  - ]:         67 :     SvXMLuInt32Set::const_iterator aItr = aUsed.find(nKey);
     149         [ +  - ]:         67 :     return (aItr != aUsed.end());
     150                 :            : }
     151                 :            : 
     152                 :        201 : sal_Bool SvXMLNumUsedList_Impl::IsWasUsed( sal_uInt32 nKey ) const
     153                 :            : {
     154         [ +  - ]:        201 :     SvXMLuInt32Set::const_iterator aItr = aWasUsed.find(nKey);
     155         [ +  - ]:        201 :     return (aItr != aWasUsed.end());
     156                 :            : }
     157                 :            : 
     158                 :        233 : void SvXMLNumUsedList_Impl::Export()
     159                 :            : {
     160                 :        233 :     SvXMLuInt32Set::const_iterator aItr = aUsed.begin();
     161 [ +  - ][ +  + ]:        262 :     while (aItr != aUsed.end())
     162                 :            :     {
     163 [ +  - ][ +  - ]:         29 :         std::pair<SvXMLuInt32Set::const_iterator, bool> aPair = aWasUsed.insert( *aItr );
     164         [ +  - ]:         29 :         if (aPair.second)
     165                 :         29 :             nWasUsedCount++;
     166         [ +  - ]:         29 :         ++aItr;
     167                 :            :     }
     168                 :        233 :     aUsed.clear();
     169                 :        233 :     nUsedCount = 0;
     170                 :        233 : }
     171                 :            : 
     172                 :        233 : sal_Bool SvXMLNumUsedList_Impl::GetFirstUsed(sal_uInt32& nKey)
     173                 :            : {
     174                 :        233 :     sal_Bool bRet(sal_False);
     175                 :        233 :     aCurrentUsedPos = aUsed.begin();
     176         [ +  + ]:        233 :     if(nUsedCount)
     177                 :            :     {
     178                 :            :         DBG_ASSERT(aCurrentUsedPos != aUsed.end(), "something went wrong");
     179                 :         15 :         nKey = *aCurrentUsedPos;
     180                 :         15 :         bRet = sal_True;
     181                 :            :     }
     182                 :        233 :     return bRet;
     183                 :            : }
     184                 :            : 
     185                 :         29 : sal_Bool SvXMLNumUsedList_Impl::GetNextUsed(sal_uInt32& nKey)
     186                 :            : {
     187                 :         29 :     sal_Bool bRet(sal_False);
     188 [ +  - ][ +  - ]:         29 :     if (aCurrentUsedPos != aUsed.end())
     189                 :            :     {
     190                 :         29 :         ++aCurrentUsedPos;
     191 [ +  + ][ +  - ]:         29 :         if (aCurrentUsedPos != aUsed.end())
     192                 :            :         {
     193                 :         14 :             nKey = *aCurrentUsedPos;
     194                 :         14 :             bRet = sal_True;
     195                 :            :         }
     196                 :            :     }
     197                 :         29 :     return bRet;
     198                 :            : }
     199                 :            : 
     200                 :         50 : void SvXMLNumUsedList_Impl::GetWasUsed(uno::Sequence<sal_Int32>& rWasUsed)
     201                 :            : {
     202                 :         50 :     rWasUsed.realloc(nWasUsedCount);
     203                 :         50 :     sal_Int32* pWasUsed = rWasUsed.getArray();
     204         [ +  - ]:         50 :     if (pWasUsed)
     205                 :            :     {
     206                 :         50 :         SvXMLuInt32Set::const_iterator aItr = aWasUsed.begin();
     207 [ +  - ][ +  + ]:         70 :         while (aItr != aWasUsed.end())
     208                 :            :         {
     209         [ +  - ]:         20 :             *pWasUsed = *aItr;
     210         [ +  - ]:         20 :             ++aItr;
     211                 :         20 :             ++pWasUsed;
     212                 :            :         }
     213                 :            :     }
     214                 :         50 : }
     215                 :            : 
     216                 :         25 : void SvXMLNumUsedList_Impl::SetWasUsed(const uno::Sequence<sal_Int32>& rWasUsed)
     217                 :            : {
     218                 :            :     DBG_ASSERT(nWasUsedCount == 0, "WasUsed should be empty");
     219                 :         25 :     sal_Int32 nCount(rWasUsed.getLength());
     220                 :         25 :     const sal_Int32* pWasUsed = rWasUsed.getConstArray();
     221         [ +  + ]:         33 :     for (sal_uInt16 i = 0; i < nCount; i++, pWasUsed++)
     222                 :            :     {
     223         [ +  - ]:          8 :         std::pair<SvXMLuInt32Set::const_iterator, bool> aPair = aWasUsed.insert( *pWasUsed );
     224         [ +  - ]:          8 :         if (aPair.second)
     225                 :          8 :             nWasUsedCount++;
     226                 :            :     }
     227                 :         25 : }
     228                 :            : 
     229                 :            : //-------------------------------------------------------------------------
     230                 :            : 
     231                 :        489 : SvXMLNumFmtExport::SvXMLNumFmtExport(
     232                 :            :             SvXMLExport& rExp,
     233                 :            :             const uno::Reference< util::XNumberFormatsSupplier >& rSupp ) :
     234                 :            :     rExport( rExp ),
     235                 :            :     sPrefix( OUString("N") ),
     236                 :            :     pFormatter( NULL ),
     237                 :            :     pCharClass( NULL ),
     238                 :        489 :     pLocaleData( NULL )
     239                 :            : {
     240                 :            :     //  supplier must be SvNumberFormatsSupplierObj
     241                 :            :     SvNumberFormatsSupplierObj* pObj =
     242         [ +  - ]:        489 :                     SvNumberFormatsSupplierObj::getImplementation( rSupp );
     243         [ +  - ]:        489 :     if (pObj)
     244         [ +  - ]:        489 :         pFormatter = pObj->GetNumberFormatter();
     245                 :            : 
     246         [ +  - ]:        489 :     if ( pFormatter )
     247                 :            :     {
     248                 :            :         pCharClass = new CharClass( pFormatter->GetServiceManager(),
     249 [ +  - ][ +  - ]:        489 :             pFormatter->GetLocale() );
                 [ +  - ]
     250                 :            :         pLocaleData = new LocaleDataWrapper( pFormatter->GetServiceManager(),
     251 [ +  - ][ +  - ]:        489 :             pFormatter->GetLocale() );
                 [ +  - ]
     252                 :            :     }
     253                 :            :     else
     254                 :            :     {
     255 [ #  # ][ #  # ]:          0 :         lang::Locale aLocale( MsLangId::convertLanguageToLocale( MsLangId::getSystemLanguage() ) );
     256                 :            : 
     257 [ #  # ][ #  # ]:          0 :         pCharClass = new CharClass( rExport.getServiceFactory(), aLocale );
                 [ #  # ]
     258 [ #  # ][ #  # ]:          0 :         pLocaleData = new LocaleDataWrapper( rExport.getServiceFactory(), aLocale );
                 [ #  # ]
     259                 :            :     }
     260                 :            : 
     261 [ +  - ][ +  - ]:        489 :     pUsedList = new SvXMLNumUsedList_Impl;
     262                 :        489 : }
     263                 :            : 
     264                 :          0 : SvXMLNumFmtExport::SvXMLNumFmtExport(
     265                 :            :                        SvXMLExport& rExp,
     266                 :            :                        const ::com::sun::star::uno::Reference<
     267                 :            :                         ::com::sun::star::util::XNumberFormatsSupplier >& rSupp,
     268                 :            :                        const rtl::OUString& rPrefix ) :
     269                 :            :     rExport( rExp ),
     270                 :            :     sPrefix( rPrefix ),
     271                 :            :     pFormatter( NULL ),
     272                 :            :     pCharClass( NULL ),
     273                 :          0 :     pLocaleData( NULL )
     274                 :            : {
     275                 :            :     //  supplier must be SvNumberFormatsSupplierObj
     276                 :            :     SvNumberFormatsSupplierObj* pObj =
     277         [ #  # ]:          0 :                     SvNumberFormatsSupplierObj::getImplementation( rSupp );
     278         [ #  # ]:          0 :     if (pObj)
     279         [ #  # ]:          0 :         pFormatter = pObj->GetNumberFormatter();
     280                 :            : 
     281         [ #  # ]:          0 :     if ( pFormatter )
     282                 :            :     {
     283                 :            :         pCharClass = new CharClass( pFormatter->GetServiceManager(),
     284 [ #  # ][ #  # ]:          0 :             pFormatter->GetLocale() );
                 [ #  # ]
     285                 :            :         pLocaleData = new LocaleDataWrapper( pFormatter->GetServiceManager(),
     286 [ #  # ][ #  # ]:          0 :             pFormatter->GetLocale() );
                 [ #  # ]
     287                 :            :     }
     288                 :            :     else
     289                 :            :     {
     290 [ #  # ][ #  # ]:          0 :         lang::Locale aLocale( MsLangId::convertLanguageToLocale( MsLangId::getSystemLanguage() ) );
     291                 :            : 
     292 [ #  # ][ #  # ]:          0 :         pCharClass = new CharClass( rExport.getServiceFactory(), aLocale );
                 [ #  # ]
     293 [ #  # ][ #  # ]:          0 :         pLocaleData = new LocaleDataWrapper( rExport.getServiceFactory(), aLocale );
                 [ #  # ]
     294                 :            :     }
     295                 :            : 
     296 [ #  # ][ #  # ]:          0 :     pUsedList = new SvXMLNumUsedList_Impl;
     297                 :          0 : }
     298                 :            : 
     299                 :        489 : SvXMLNumFmtExport::~SvXMLNumFmtExport()
     300                 :            : {
     301         [ +  - ]:        489 :     delete pUsedList;
     302 [ +  - ][ +  - ]:        489 :     delete pLocaleData;
     303 [ +  - ][ +  - ]:        489 :     delete pCharClass;
     304         [ -  + ]:        978 : }
     305                 :            : 
     306                 :            : //-------------------------------------------------------------------------
     307                 :            : 
     308                 :            : //
     309                 :            : //  helper methods
     310                 :            : //
     311                 :            : 
     312                 :        104 : OUString lcl_CreateStyleName( sal_Int32 nKey, sal_Int32 nPart, sal_Bool bDefPart, const rtl::OUString& rPrefix )
     313                 :            : {
     314                 :        104 :     OUStringBuffer aFmtName( 10L );
     315         [ +  - ]:        104 :     aFmtName.append( rPrefix );
     316         [ +  - ]:        104 :     aFmtName.append( nKey );
     317         [ +  + ]:        104 :     if (!bDefPart)
     318                 :            :     {
     319         [ +  - ]:          8 :         aFmtName.append( (sal_Unicode)'P' );
     320         [ +  - ]:          8 :         aFmtName.append( nPart );
     321                 :            :     }
     322         [ +  - ]:        104 :     return aFmtName.makeStringAndClear();
     323                 :            : }
     324                 :            : 
     325                 :         26 : void SvXMLNumFmtExport::AddCalendarAttr_Impl( const OUString& rCalendar )
     326                 :            : {
     327         [ -  + ]:         26 :     if ( !rCalendar.isEmpty() )
     328                 :            :     {
     329                 :          0 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_CALENDAR, rCalendar );
     330                 :            :     }
     331                 :         26 : }
     332                 :            : 
     333                 :         10 : void SvXMLNumFmtExport::AddTextualAttr_Impl( sal_Bool bText )
     334                 :            : {
     335         [ +  + ]:         10 :     if ( bText )            // non-textual
     336                 :            :     {
     337                 :          2 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TEXTUAL, XML_TRUE );
     338                 :            :     }
     339                 :         10 : }
     340                 :            : 
     341                 :         26 : void SvXMLNumFmtExport::AddStyleAttr_Impl( sal_Bool bLong )
     342                 :            : {
     343         [ +  - ]:         26 :     if ( bLong )            // short is default
     344                 :            :     {
     345                 :         26 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_STYLE, XML_LONG );
     346                 :            :     }
     347                 :         26 : }
     348                 :            : 
     349                 :         41 : void SvXMLNumFmtExport::AddLanguageAttr_Impl( sal_Int32 nLang )
     350                 :            : {
     351         [ +  + ]:         41 :     if ( nLang != LANGUAGE_SYSTEM )
     352                 :            :     {
     353                 :         18 :         OUString aLangStr, aCountryStr;
     354         [ +  - ]:         18 :         MsLangId::convertLanguageToIsoNames( (LanguageType)nLang, aLangStr, aCountryStr );
     355                 :            : 
     356         [ +  - ]:         18 :         if (!aLangStr.isEmpty())
     357         [ +  - ]:         18 :             rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_LANGUAGE, aLangStr );
     358         [ +  - ]:         18 :         if (!aCountryStr.isEmpty())
     359         [ +  - ]:         18 :             rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_COUNTRY, aCountryStr );
     360                 :            :     }
     361                 :         41 : }
     362                 :            : 
     363                 :            : //-------------------------------------------------------------------------
     364                 :            : 
     365                 :            : //
     366                 :            : //  methods to write individual elements within a format
     367                 :            : //
     368                 :            : 
     369                 :         20 : void SvXMLNumFmtExport::AddToTextElement_Impl( const OUString& rString )
     370                 :            : {
     371                 :            :     //  append to sTextContent, write element in FinishTextElement_Impl
     372                 :            :     //  to avoid several text elements following each other
     373                 :            : 
     374                 :         20 :     sTextContent.append( rString );
     375                 :         20 : }
     376                 :            : 
     377                 :        152 : void SvXMLNumFmtExport::FinishTextElement_Impl()
     378                 :            : {
     379         [ +  + ]:        152 :     if ( sTextContent.getLength() )
     380                 :            :     {
     381                 :            :         SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_TEXT,
     382         [ +  - ]:         20 :                                   sal_True, sal_False );
     383 [ +  - ][ +  - ]:         20 :         rExport.Characters( sTextContent.makeStringAndClear() );
                 [ +  - ]
     384                 :            :     }
     385                 :        152 : }
     386                 :            : 
     387                 :          4 : void SvXMLNumFmtExport::WriteColorElement_Impl( const Color& rColor )
     388                 :            : {
     389         [ +  - ]:          4 :     FinishTextElement_Impl();
     390                 :            : 
     391                 :          4 :     OUStringBuffer aColStr( 7 );
     392         [ +  - ]:          4 :     ::sax::Converter::convertColor( aColStr, rColor.GetColor() );
     393                 :            :     rExport.AddAttribute( XML_NAMESPACE_FO, XML_COLOR,
     394 [ +  - ][ +  - ]:          4 :                           aColStr.makeStringAndClear() );
     395                 :            : 
     396                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, XML_TEXT_PROPERTIES,
     397 [ +  - ][ +  - ]:          4 :                               sal_True, sal_False );
     398                 :          4 : }
     399                 :            : 
     400                 :          8 : void SvXMLNumFmtExport::WriteCurrencyElement_Impl( const OUString& rString,
     401                 :            :                                                     const OUString& rExt )
     402                 :            : {
     403         [ +  - ]:          8 :     FinishTextElement_Impl();
     404                 :            : 
     405         [ +  - ]:          8 :     if ( !rExt.isEmpty() )
     406                 :            :     {
     407                 :          8 :         sal_Int32 nLang = rExt.toInt32(16);     // hex
     408         [ +  - ]:          8 :         if ( nLang < 0 )                        // extension string may contain "-" separator
     409                 :          8 :             nLang = -nLang;
     410         [ +  - ]:          8 :         AddLanguageAttr_Impl( nLang );          // adds to pAttrList
     411                 :            :     }
     412                 :            : 
     413                 :            :     SvXMLElementExport aElem( rExport,
     414                 :            :                               XML_NAMESPACE_NUMBER, XML_CURRENCY_SYMBOL,
     415         [ +  - ]:          8 :                               sal_True, sal_False );
     416 [ +  - ][ +  - ]:          8 :     rExport.Characters( rString );
     417                 :          8 : }
     418                 :            : 
     419                 :          0 : void SvXMLNumFmtExport::WriteBooleanElement_Impl()
     420                 :            : {
     421         [ #  # ]:          0 :     FinishTextElement_Impl();
     422                 :            : 
     423                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_BOOLEAN,
     424 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     425                 :          0 : }
     426                 :            : 
     427                 :          0 : void SvXMLNumFmtExport::WriteTextContentElement_Impl()
     428                 :            : {
     429         [ #  # ]:          0 :     FinishTextElement_Impl();
     430                 :            : 
     431                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_TEXT_CONTENT,
     432 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     433                 :          0 : }
     434                 :            : 
     435                 :            : //  date elements
     436                 :            : 
     437                 :          8 : void SvXMLNumFmtExport::WriteDayElement_Impl( const OUString& rCalendar, sal_Bool bLong )
     438                 :            : {
     439         [ +  - ]:          8 :     FinishTextElement_Impl();
     440                 :            : 
     441         [ +  - ]:          8 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     442         [ +  - ]:          8 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     443                 :            : 
     444                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_DAY,
     445 [ +  - ][ +  - ]:          8 :                               sal_True, sal_False );
     446                 :          8 : }
     447                 :            : 
     448                 :         10 : void SvXMLNumFmtExport::WriteMonthElement_Impl( const OUString& rCalendar, sal_Bool bLong, sal_Bool bText )
     449                 :            : {
     450         [ +  - ]:         10 :     FinishTextElement_Impl();
     451                 :            : 
     452         [ +  - ]:         10 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     453         [ +  - ]:         10 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     454         [ +  - ]:         10 :     AddTextualAttr_Impl( bText );   // adds to pAttrList
     455                 :            : 
     456                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_MONTH,
     457 [ +  - ][ +  - ]:         10 :                               sal_True, sal_False );
     458                 :         10 : }
     459                 :            : 
     460                 :          8 : void SvXMLNumFmtExport::WriteYearElement_Impl( const OUString& rCalendar, sal_Bool bLong )
     461                 :            : {
     462         [ +  - ]:          8 :     FinishTextElement_Impl();
     463                 :            : 
     464         [ +  - ]:          8 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     465         [ +  - ]:          8 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     466                 :            : 
     467                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_YEAR,
     468 [ +  - ][ +  - ]:          8 :                               sal_True, sal_False );
     469                 :          8 : }
     470                 :            : 
     471                 :          0 : void SvXMLNumFmtExport::WriteEraElement_Impl( const OUString& rCalendar, sal_Bool bLong )
     472                 :            : {
     473         [ #  # ]:          0 :     FinishTextElement_Impl();
     474                 :            : 
     475         [ #  # ]:          0 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     476         [ #  # ]:          0 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     477                 :            : 
     478                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_ERA,
     479 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     480                 :          0 : }
     481                 :            : 
     482                 :          0 : void SvXMLNumFmtExport::WriteDayOfWeekElement_Impl( const OUString& rCalendar, sal_Bool bLong )
     483                 :            : {
     484         [ #  # ]:          0 :     FinishTextElement_Impl();
     485                 :            : 
     486         [ #  # ]:          0 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     487         [ #  # ]:          0 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     488                 :            : 
     489                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_DAY_OF_WEEK,
     490 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     491                 :          0 : }
     492                 :            : 
     493                 :          0 : void SvXMLNumFmtExport::WriteWeekElement_Impl( const OUString& rCalendar )
     494                 :            : {
     495         [ #  # ]:          0 :     FinishTextElement_Impl();
     496                 :            : 
     497         [ #  # ]:          0 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     498                 :            : 
     499                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_WEEK_OF_YEAR,
     500 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     501                 :          0 : }
     502                 :            : 
     503                 :          0 : void SvXMLNumFmtExport::WriteQuarterElement_Impl( const OUString& rCalendar, sal_Bool bLong )
     504                 :            : {
     505         [ #  # ]:          0 :     FinishTextElement_Impl();
     506                 :            : 
     507         [ #  # ]:          0 :     AddCalendarAttr_Impl( rCalendar ); // adds to pAttrList
     508         [ #  # ]:          0 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     509                 :            : 
     510                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_QUARTER,
     511 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     512                 :          0 : }
     513                 :            : 
     514                 :            : //  time elements
     515                 :            : 
     516                 :          0 : void SvXMLNumFmtExport::WriteHoursElement_Impl( sal_Bool bLong )
     517                 :            : {
     518         [ #  # ]:          0 :     FinishTextElement_Impl();
     519                 :            : 
     520         [ #  # ]:          0 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     521                 :            : 
     522                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_HOURS,
     523 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     524                 :          0 : }
     525                 :            : 
     526                 :          0 : void SvXMLNumFmtExport::WriteMinutesElement_Impl( sal_Bool bLong )
     527                 :            : {
     528         [ #  # ]:          0 :     FinishTextElement_Impl();
     529                 :            : 
     530         [ #  # ]:          0 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     531                 :            : 
     532                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_MINUTES,
     533 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     534                 :          0 : }
     535                 :            : 
     536                 :          0 : void SvXMLNumFmtExport::WriteRepeatedElement_Impl( sal_Unicode nChar )
     537                 :            : {
     538         [ #  # ]:          0 :     FinishTextElement_Impl();
     539                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_FILL_CHARACTER,
     540         [ #  # ]:          0 :                                   sal_True, sal_False );
     541 [ #  # ][ #  # ]:          0 :     rExport.Characters( OUString::valueOf( nChar ) );
     542                 :          0 : }
     543                 :            : 
     544                 :          0 : void SvXMLNumFmtExport::WriteSecondsElement_Impl( sal_Bool bLong, sal_uInt16 nDecimals )
     545                 :            : {
     546         [ #  # ]:          0 :     FinishTextElement_Impl();
     547                 :            : 
     548         [ #  # ]:          0 :     AddStyleAttr_Impl( bLong );     // adds to pAttrList
     549         [ #  # ]:          0 :     if ( nDecimals > 0 )
     550                 :            :     {
     551                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,
     552         [ #  # ]:          0 :                               OUString::valueOf( (sal_Int32) nDecimals ) );
     553                 :            :     }
     554                 :            : 
     555                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_SECONDS,
     556 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     557                 :          0 : }
     558                 :            : 
     559                 :          0 : void SvXMLNumFmtExport::WriteAMPMElement_Impl()
     560                 :            : {
     561         [ #  # ]:          0 :     FinishTextElement_Impl();
     562                 :            : 
     563                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_AM_PM,
     564 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     565                 :          0 : }
     566                 :            : 
     567                 :            : //  numbers
     568                 :            : 
     569                 :         23 : void SvXMLNumFmtExport::WriteNumberElement_Impl(
     570                 :            :                             sal_Int32 nDecimals, sal_Int32 nInteger,
     571                 :            :                             const OUString& rDashStr, sal_Bool bVarDecimals,
     572                 :            :                             sal_Bool bGrouping, sal_Int32 nTrailingThousands,
     573                 :            :                             const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries )
     574                 :            : {
     575         [ +  - ]:         23 :     FinishTextElement_Impl();
     576                 :            : 
     577                 :            :     //  decimals
     578         [ +  + ]:         23 :     if ( nDecimals >= 0 )   // negative = automatic
     579                 :            :     {
     580                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,
     581         [ +  - ]:         10 :                               OUString::valueOf( nDecimals ) );
     582                 :            :     }
     583                 :            : 
     584                 :            :     //  integer digits
     585         [ +  - ]:         23 :     if ( nInteger >= 0 )    // negative = automatic
     586                 :            :     {
     587                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
     588         [ +  - ]:         23 :                               OUString::valueOf( nInteger ) );
     589                 :            :     }
     590                 :            : 
     591                 :            :     //  decimal replacement (dashes) or variable decimals (#)
     592 [ +  - ][ -  + ]:         23 :     if ( !rDashStr.isEmpty() || bVarDecimals )
                 [ -  + ]
     593                 :            :     {
     594                 :            :         //  variable decimals means an empty replacement string
     595                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_REPLACEMENT,
     596         [ #  # ]:          0 :                               rDashStr );
     597                 :            :     }
     598                 :            : 
     599                 :            :     //  (automatic) grouping separator
     600         [ +  + ]:         23 :     if ( bGrouping )
     601                 :            :     {
     602         [ +  - ]:         10 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
     603                 :            :     }
     604                 :            : 
     605                 :            :     //  display-factor if there are trailing thousands separators
     606         [ -  + ]:         23 :     if ( nTrailingThousands )
     607                 :            :     {
     608                 :            :         //  each separator character removes three digits
     609                 :          0 :         double fFactor = ::rtl::math::pow10Exp( 1.0, 3 * nTrailingThousands );
     610                 :            : 
     611                 :          0 :         OUStringBuffer aFactStr;
     612         [ #  # ]:          0 :         ::sax::Converter::convertDouble( aFactStr, fFactor );
     613 [ #  # ][ #  # ]:          0 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DISPLAY_FACTOR, aFactStr.makeStringAndClear() );
     614                 :            :     }
     615                 :            : 
     616                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_NUMBER,
     617         [ +  - ]:         23 :                               sal_True, sal_True );
     618                 :            : 
     619                 :            :     //  number:embedded-text as child elements
     620                 :            : 
     621                 :         23 :     sal_uInt16 nEntryCount = rEmbeddedEntries.size();
     622         [ -  + ]:         23 :     for (sal_uInt16 nEntry=0; nEntry<nEntryCount; nEntry++)
     623                 :            :     {
     624         [ #  # ]:          0 :         const SvXMLEmbeddedTextEntry* pObj = &rEmbeddedEntries[nEntry];
     625                 :            : 
     626                 :            :         //  position attribute
     627                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_POSITION,
     628         [ #  # ]:          0 :                                 OUString::valueOf( pObj->nFormatPos ) );
     629                 :            :         SvXMLElementExport aChildElem( rExport, XML_NAMESPACE_NUMBER, XML_EMBEDDED_TEXT,
     630         [ #  # ]:          0 :                                           sal_True, sal_False );
     631                 :            : 
     632                 :            :         //  text as element content
     633                 :          0 :         rtl::OUString aContent( pObj->aText );
     634 [ #  # ][ #  # ]:          0 :         while ( nEntry+1 < nEntryCount && rEmbeddedEntries[nEntry+1].nFormatPos == pObj->nFormatPos )
         [ #  # ][ #  # ]
     635                 :            :         {
     636                 :            :             // The array can contain several elements for the same position in the number
     637                 :            :             // (for example, literal text and space from underscores). They must be merged
     638                 :            :             // into a single embedded-text element.
     639         [ #  # ]:          0 :             aContent += rEmbeddedEntries[nEntry+1].aText;
     640                 :          0 :             ++nEntry;
     641                 :            :         }
     642         [ #  # ]:          0 :         rExport.Characters( aContent );
     643 [ #  # ][ +  - ]:         23 :     }
     644                 :         23 : }
     645                 :            : 
     646                 :          0 : void SvXMLNumFmtExport::WriteScientificElement_Impl(
     647                 :            :                             sal_Int32 nDecimals, sal_Int32 nInteger,
     648                 :            :                             sal_Bool bGrouping, sal_Int32 nExp )
     649                 :            : {
     650         [ #  # ]:          0 :     FinishTextElement_Impl();
     651                 :            : 
     652                 :            :     //  decimals
     653         [ #  # ]:          0 :     if ( nDecimals >= 0 )   // negative = automatic
     654                 :            :     {
     655                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES,
     656         [ #  # ]:          0 :                               OUString::valueOf( nDecimals ) );
     657                 :            :     }
     658                 :            : 
     659                 :            :     //  integer digits
     660         [ #  # ]:          0 :     if ( nInteger >= 0 )    // negative = automatic
     661                 :            :     {
     662                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
     663         [ #  # ]:          0 :                               OUString::valueOf( nInteger ) );
     664                 :            :     }
     665                 :            : 
     666                 :            :     //  (automatic) grouping separator
     667         [ #  # ]:          0 :     if ( bGrouping )
     668                 :            :     {
     669         [ #  # ]:          0 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
     670                 :            :     }
     671                 :            : 
     672                 :            :     //  exponent digits
     673         [ #  # ]:          0 :     if ( nExp >= 0 )
     674                 :            :     {
     675                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_EXPONENT_DIGITS,
     676         [ #  # ]:          0 :                               OUString::valueOf( nExp ) );
     677                 :            :     }
     678                 :            : 
     679                 :            :     SvXMLElementExport aElem( rExport,
     680                 :            :                               XML_NAMESPACE_NUMBER, XML_SCIENTIFIC_NUMBER,
     681 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     682                 :          0 : }
     683                 :            : 
     684                 :          0 : void SvXMLNumFmtExport::WriteFractionElement_Impl(
     685                 :            :                             sal_Int32 nInteger, sal_Bool bGrouping,
     686                 :            :                             sal_Int32 nNumerator, sal_Int32 nDenominator )
     687                 :            : {
     688         [ #  # ]:          0 :     FinishTextElement_Impl();
     689                 :            : 
     690                 :            :     //  integer digits
     691         [ #  # ]:          0 :     if ( nInteger >= 0 )        // negative = default (no integer part)
     692                 :            :     {
     693                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_INTEGER_DIGITS,
     694         [ #  # ]:          0 :                               OUString::valueOf( nInteger ) );
     695                 :            :     }
     696                 :            : 
     697                 :            :     //  (automatic) grouping separator
     698         [ #  # ]:          0 :     if ( bGrouping )
     699                 :            :     {
     700         [ #  # ]:          0 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_GROUPING, XML_TRUE );
     701                 :            :     }
     702                 :            : 
     703                 :            :     //  numerator digits
     704         [ #  # ]:          0 :     if ( nNumerator >= 0 )
     705                 :            :     {
     706                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS,
     707         [ #  # ]:          0 :                                  OUString::valueOf( nNumerator ) );
     708                 :            :     }
     709                 :            : 
     710                 :            :     //  denominator digits
     711         [ #  # ]:          0 :     if ( nDenominator >= 0 )
     712                 :            :     {
     713                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_MIN_DENOMINATOR_DIGITS,
     714         [ #  # ]:          0 :                               OUString::valueOf( nDenominator ) );
     715                 :            :     }
     716                 :            : 
     717                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, XML_FRACTION,
     718 [ #  # ][ #  # ]:          0 :                               sal_True, sal_False );
     719                 :          0 : }
     720                 :            : 
     721                 :            : //  mapping (condition)
     722                 :            : 
     723                 :         58 : void SvXMLNumFmtExport::WriteMapElement_Impl( sal_Int32 nOp, double fLimit,
     724                 :            :                                                 sal_Int32 nKey, sal_Int32 nPart )
     725                 :            : {
     726                 :         58 :     FinishTextElement_Impl();
     727                 :            : 
     728         [ +  + ]:         58 :     if ( nOp != NUMBERFORMAT_OP_NO )
     729                 :            :     {
     730                 :            :         // style namespace
     731                 :            : 
     732                 :          4 :         OUStringBuffer aCondStr( 20L );
     733         [ +  - ]:          4 :         aCondStr.appendAscii( "value()" );          //! define constant
     734   [ -  -  -  -  :          4 :         switch ( nOp )
                -  +  - ]
     735                 :            :         {
     736         [ #  # ]:          0 :             case NUMBERFORMAT_OP_EQ: aCondStr.append( (sal_Unicode) '=' );  break;
     737         [ #  # ]:          0 :             case NUMBERFORMAT_OP_NE: aCondStr.appendAscii( "<>" );          break;
     738         [ #  # ]:          0 :             case NUMBERFORMAT_OP_LT: aCondStr.append( (sal_Unicode) '<' );  break;
     739         [ #  # ]:          0 :             case NUMBERFORMAT_OP_LE: aCondStr.appendAscii( "<=" );          break;
     740         [ #  # ]:          0 :             case NUMBERFORMAT_OP_GT: aCondStr.append( (sal_Unicode) '>' );  break;
     741         [ +  - ]:          4 :             case NUMBERFORMAT_OP_GE: aCondStr.appendAscii( ">=" );          break;
     742                 :            :             default:
     743                 :            :                 OSL_FAIL("unknown operator");
     744                 :            :         }
     745                 :            :         ::rtl::math::doubleToUStringBuffer( aCondStr, fLimit,
     746                 :            :                 rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
     747                 :          4 :                 '.', true );
     748                 :            : 
     749                 :            :         rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_CONDITION,
     750 [ +  - ][ +  - ]:          4 :                               aCondStr.makeStringAndClear() );
     751                 :            : 
     752                 :            :         rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_APPLY_STYLE_NAME,
     753                 :            :                               rExport.EncodeStyleName( lcl_CreateStyleName( nKey, nPart, sal_False,
     754 [ +  - ][ +  - ]:          4 :                                                    sPrefix ) ) );
                 [ +  - ]
     755                 :            : 
     756                 :            :         SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, XML_MAP,
     757 [ +  - ][ +  - ]:          4 :                                   sal_True, sal_False );
     758                 :            :     }
     759                 :         58 : }
     760                 :            : 
     761                 :            : //-------------------------------------------------------------------------
     762                 :            : //  for old (automatic) currency formats: parse currency symbol from text
     763                 :            : 
     764                 :          0 : xub_StrLen lcl_FindSymbol( const String& sUpperStr, const String& sCurString )
     765                 :            : {
     766                 :            :     //  search for currency symbol
     767                 :            :     //  Quoting as in ImpSvNumberformatScan::Symbol_Division
     768                 :            : 
     769                 :          0 :     xub_StrLen nCPos = 0;
     770         [ #  # ]:          0 :     while (nCPos != STRING_NOTFOUND)
     771                 :            :     {
     772                 :          0 :         nCPos = sUpperStr.Search( sCurString, nCPos );
     773         [ #  # ]:          0 :         if (nCPos != STRING_NOTFOUND)
     774                 :            :         {
     775                 :            :             // in Quotes?
     776                 :          0 :             xub_StrLen nQ = SvNumberformat::GetQuoteEnd( sUpperStr, nCPos );
     777         [ #  # ]:          0 :             if ( nQ == STRING_NOTFOUND )
     778                 :            :             {
     779                 :            :                 //  dm can be escaped as "dm or \d
     780                 :            :                 sal_Unicode c;
     781 [ #  # ][ #  # ]:          0 :                 if ( nCPos == 0 ||
         [ #  # ][ #  # ]
     782                 :          0 :                     ((c = sUpperStr.GetChar(xub_StrLen(nCPos-1))) != '"'
     783                 :            :                             && c != '\\') )
     784                 :            :                 {
     785                 :          0 :                     return nCPos;                   // found
     786                 :            :                 }
     787                 :            :                 else
     788                 :          0 :                     nCPos++;                        // continue
     789                 :            :             }
     790                 :            :             else
     791                 :          0 :                 nCPos = nQ + 1;                     // continue after quote end
     792                 :            :         }
     793                 :            :     }
     794                 :          0 :     return STRING_NOTFOUND;                         // not found
     795                 :            : }
     796                 :            : 
     797                 :          0 : sal_Bool SvXMLNumFmtExport::WriteTextWithCurrency_Impl( const OUString& rString,
     798                 :            :                             const ::com::sun::star::lang::Locale& rLocale )
     799                 :            : {
     800                 :            :     //  returns sal_True if currency element was written
     801                 :            : 
     802                 :          0 :     sal_Bool bRet = sal_False;
     803                 :            : 
     804         [ #  # ]:          0 :     LanguageType nLang = MsLangId::convertLocaleToLanguage( rLocale );
     805         [ #  # ]:          0 :     pFormatter->ChangeIntl( nLang );
     806 [ #  # ][ #  # ]:          0 :     String sCurString, sDummy;
     807         [ #  # ]:          0 :     pFormatter->GetCompatibilityCurrency( sCurString, sDummy );
     808                 :            : 
     809         [ #  # ]:          0 :     pCharClass->setLocale( rLocale );
     810 [ #  # ][ #  # ]:          0 :     String sUpperStr = pCharClass->uppercase(rString);
     811         [ #  # ]:          0 :     xub_StrLen nPos = lcl_FindSymbol( sUpperStr, sCurString );
     812         [ #  # ]:          0 :     if ( nPos != STRING_NOTFOUND )
     813                 :            :     {
     814                 :          0 :         sal_Int32 nLength = rString.getLength();
     815                 :          0 :         sal_Int32 nCurLen = sCurString.Len();
     816                 :          0 :         sal_Int32 nCont = nPos + nCurLen;
     817                 :            : 
     818                 :            :         //  text before currency symbol
     819         [ #  # ]:          0 :         if ( nPos > 0 )
     820         [ #  # ]:          0 :             AddToTextElement_Impl( rString.copy( 0, nPos ) );
     821                 :            : 
     822                 :            :         //  currency symbol (empty string -> default)
     823                 :          0 :         OUString sEmpty;
     824         [ #  # ]:          0 :         WriteCurrencyElement_Impl( sEmpty, sEmpty );
     825                 :          0 :         bRet = sal_True;
     826                 :            : 
     827                 :            :         //  text after currency symbol
     828         [ #  # ]:          0 :         if ( nCont < nLength )
     829         [ #  # ]:          0 :             AddToTextElement_Impl( rString.copy( nCont, nLength-nCont ) );
     830                 :            :     }
     831                 :            :     else
     832         [ #  # ]:          0 :         AddToTextElement_Impl( rString );       // simple text
     833                 :            : 
     834 [ #  # ][ #  # ]:          0 :     return bRet;        // sal_True: currency element written
                 [ #  # ]
     835                 :            : }
     836                 :            : 
     837                 :            : //-------------------------------------------------------------------------
     838                 :            : 
     839                 :          0 : OUString lcl_GetDefaultCalendar( SvNumberFormatter* pFormatter, LanguageType nLang )
     840                 :            : {
     841                 :            :     //  get name of first non-gregorian calendar for the language
     842                 :            : 
     843                 :          0 :     OUString aCalendar;
     844         [ #  # ]:          0 :     CalendarWrapper* pCalendar = pFormatter->GetCalendar();
     845         [ #  # ]:          0 :     if (pCalendar)
     846                 :            :     {
     847         [ #  # ]:          0 :         lang::Locale aLocale( MsLangId::convertLanguageToLocale( nLang ) );
     848                 :            : 
     849         [ #  # ]:          0 :         uno::Sequence<OUString> aCals = pCalendar->getAllCalendars( aLocale );
     850                 :          0 :         sal_Int32 nCnt = aCals.getLength();
     851                 :          0 :         sal_Bool bFound = sal_False;
     852 [ #  # ][ #  # ]:          0 :         for ( sal_Int32 j=0; j < nCnt && !bFound; j++ )
                 [ #  # ]
     853                 :            :         {
     854 [ #  # ][ #  # ]:          0 :             if ( aCals[j] != "gregorian" )
     855                 :            :             {
     856         [ #  # ]:          0 :                 aCalendar = aCals[j];
     857                 :          0 :                 bFound = sal_True;
     858                 :            :             }
     859         [ #  # ]:          0 :         }
     860                 :            :     }
     861                 :          0 :     return aCalendar;
     862                 :            : }
     863                 :            : 
     864                 :            : //-------------------------------------------------------------------------
     865                 :            : 
     866                 :         20 : sal_Bool lcl_IsInEmbedded( const SvXMLEmbeddedTextEntryArr& rEmbeddedEntries, sal_uInt16 nPos )
     867                 :            : {
     868                 :         20 :     sal_uInt16 nCount = rEmbeddedEntries.size();
     869         [ -  + ]:         20 :     for (sal_uInt16 i=0; i<nCount; i++)
     870         [ #  # ]:          0 :         if ( rEmbeddedEntries[i].nSourcePos == nPos )
     871                 :          0 :             return sal_True;
     872                 :            : 
     873                 :         20 :     return sal_False;       // not found
     874                 :            : }
     875                 :            : 
     876                 :          8 : sal_Bool lcl_IsDefaultDateFormat( const SvNumberformat& rFormat, sal_Bool bSystemDate, NfIndexTableOffset eBuiltIn )
     877                 :            : {
     878                 :            :     //  make an extra loop to collect date elements, to check if it is a default format
     879                 :            :     //  before adding the automatic-order attribute
     880                 :            : 
     881                 :          8 :     SvXMLDateElementAttributes eDateDOW = XML_DEA_NONE;
     882                 :          8 :     SvXMLDateElementAttributes eDateDay = XML_DEA_NONE;
     883                 :          8 :     SvXMLDateElementAttributes eDateMonth = XML_DEA_NONE;
     884                 :          8 :     SvXMLDateElementAttributes eDateYear = XML_DEA_NONE;
     885                 :          8 :     SvXMLDateElementAttributes eDateHours = XML_DEA_NONE;
     886                 :          8 :     SvXMLDateElementAttributes eDateMins = XML_DEA_NONE;
     887                 :          8 :     SvXMLDateElementAttributes eDateSecs = XML_DEA_NONE;
     888                 :          8 :     sal_Bool bDateNoDefault = sal_False;
     889                 :            : 
     890                 :          8 :     sal_uInt16 nPos = 0;
     891                 :          8 :     sal_Bool bEnd = sal_False;
     892                 :          8 :     short nLastType = 0;
     893         [ +  + ]:         56 :     while (!bEnd)
     894                 :            :     {
     895                 :         48 :         short nElemType = rFormat.GetNumForType( 0, nPos, sal_False );
     896   [ +  +  -  -  :         48 :         switch ( nElemType )
          -  +  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
                      - ]
     897                 :            :         {
     898                 :            :             case 0:
     899         [ -  + ]:          8 :                 if ( nLastType == NF_SYMBOLTYPE_STRING )
     900                 :          0 :                     bDateNoDefault = sal_True;  // text at the end -> no default date format
     901                 :          8 :                 bEnd = sal_True;                // end of format reached
     902                 :          8 :                 break;
     903                 :            :             case NF_SYMBOLTYPE_STRING:
     904                 :            :             case NF_SYMBOLTYPE_DATESEP:
     905                 :            :             case NF_SYMBOLTYPE_TIMESEP:
     906                 :            :             case NF_SYMBOLTYPE_TIME100SECSEP:
     907                 :            :                 // text is ignored, except at the end
     908                 :         16 :                 break;
     909                 :            :             // same mapping as in SvXMLNumFormatContext::AddNfKeyword:
     910                 :          0 :             case NF_KEY_NN:     eDateDOW = XML_DEA_SHORT;       break;
     911                 :            :             case NF_KEY_NNN:
     912                 :          0 :             case NF_KEY_NNNN:   eDateDOW = XML_DEA_LONG;        break;
     913                 :          0 :             case NF_KEY_D:      eDateDay = XML_DEA_SHORT;       break;
     914                 :          8 :             case NF_KEY_DD:     eDateDay = XML_DEA_LONG;        break;
     915                 :          0 :             case NF_KEY_M:      eDateMonth = XML_DEA_SHORT;     break;
     916                 :          8 :             case NF_KEY_MM:     eDateMonth = XML_DEA_LONG;      break;
     917                 :          0 :             case NF_KEY_MMM:    eDateMonth = XML_DEA_TEXTSHORT; break;
     918                 :          0 :             case NF_KEY_MMMM:   eDateMonth = XML_DEA_TEXTLONG;  break;
     919                 :          0 :             case NF_KEY_YY:     eDateYear = XML_DEA_SHORT;      break;
     920                 :          8 :             case NF_KEY_YYYY:   eDateYear = XML_DEA_LONG;       break;
     921                 :          0 :             case NF_KEY_H:      eDateHours = XML_DEA_SHORT;     break;
     922                 :          0 :             case NF_KEY_HH:     eDateHours = XML_DEA_LONG;      break;
     923                 :          0 :             case NF_KEY_MI:     eDateMins = XML_DEA_SHORT;      break;
     924                 :          0 :             case NF_KEY_MMI:    eDateMins = XML_DEA_LONG;       break;
     925                 :          0 :             case NF_KEY_S:      eDateSecs = XML_DEA_SHORT;      break;
     926                 :          0 :             case NF_KEY_SS:     eDateSecs = XML_DEA_LONG;       break;
     927                 :            :             case NF_KEY_AP:
     928                 :          0 :             case NF_KEY_AMPM:   break;          // AM/PM may or may not be in date/time formats -> ignore by itself
     929                 :            :             default:
     930                 :          0 :                 bDateNoDefault = sal_True;      // any other element -> no default format
     931                 :            :         }
     932                 :         48 :         nLastType = nElemType;
     933                 :         48 :         ++nPos;
     934                 :            :     }
     935                 :            : 
     936         [ -  + ]:          8 :     if ( bDateNoDefault )
     937                 :          0 :         return sal_False;                       // additional elements
     938                 :            :     else
     939                 :            :     {
     940                 :            :         NfIndexTableOffset eFound = (NfIndexTableOffset) SvXMLNumFmtDefaults::GetDefaultDateFormat(
     941                 :          8 :                 eDateDOW, eDateDay, eDateMonth, eDateYear, eDateHours, eDateMins, eDateSecs, bSystemDate );
     942                 :            : 
     943                 :          8 :         return ( eFound == eBuiltIn );
     944                 :            :     }
     945                 :            : }
     946                 :            : 
     947                 :            : //
     948                 :            : //  export one part (condition)
     949                 :            : //
     950                 :            : 
     951                 :         33 : void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt32 nKey,
     952                 :            :                                             sal_uInt16 nPart, sal_Bool bDefPart )
     953                 :            : {
     954                 :            :     //! for the default part, pass the coditions from the other parts!
     955                 :            : 
     956                 :            :     //
     957                 :            :     //  element name
     958                 :            :     //
     959                 :            : 
     960         [ +  - ]:         33 :     NfIndexTableOffset eBuiltIn = pFormatter->GetIndexTableOffset( nKey );
     961                 :            : 
     962                 :         33 :     short nFmtType = 0;
     963                 :         33 :     bool bThousand = false;
     964                 :         33 :     sal_uInt16 nPrecision = 0;
     965                 :         33 :     sal_uInt16 nLeading = 0;
     966         [ +  - ]:         33 :     rFormat.GetNumForInfo( nPart, nFmtType, bThousand, nPrecision, nLeading);
     967                 :         33 :     nFmtType &= ~NUMBERFORMAT_DEFINED;
     968                 :            : 
     969                 :            :     //  special treatment of builtin formats that aren't detected by normal parsing
     970                 :            :     //  (the same formats that get the type set in SvNumberFormatter::ImpGenerateFormats)
     971         [ +  + ]:         33 :     if ( eBuiltIn == NF_NUMBER_STANDARD )
     972                 :         13 :         nFmtType = NUMBERFORMAT_NUMBER;
     973         [ -  + ]:         20 :     else if ( eBuiltIn == NF_BOOLEAN )
     974                 :          0 :         nFmtType = NUMBERFORMAT_LOGICAL;
     975         [ -  + ]:         20 :     else if ( eBuiltIn == NF_TEXT )
     976                 :          0 :         nFmtType = NUMBERFORMAT_TEXT;
     977                 :            : 
     978                 :            :     // #101606# An empty subformat is a valid number-style resulting in an
     979                 :            :     // empty display string for the condition of the subformat.
     980 [ -  + ][ #  # ]:         33 :     if ( nFmtType == NUMBERFORMAT_UNDEFINED && rFormat.GetNumForType( nPart,
                 [ -  + ]
     981         [ #  # ]:          0 :                 0, sal_False ) == 0 )
     982                 :          0 :         nFmtType = 0;
     983                 :            : 
     984                 :         33 :     XMLTokenEnum eType = XML_TOKEN_INVALID;
     985   [ +  -  +  +  :         33 :     switch ( nFmtType )
             -  -  -  - ]
     986                 :            :     {
     987                 :            :         // type is 0 if a format contains no recognized elements
     988                 :            :         // (like text only) - this is handled as a number-style.
     989                 :            :         case 0:
     990                 :            :         case NUMBERFORMAT_NUMBER:
     991                 :            :         case NUMBERFORMAT_SCIENTIFIC:
     992                 :            :         case NUMBERFORMAT_FRACTION:
     993                 :         15 :             eType = XML_NUMBER_STYLE;
     994                 :         15 :             break;
     995                 :            :         case NUMBERFORMAT_PERCENT:
     996                 :          0 :             eType = XML_PERCENTAGE_STYLE;
     997                 :          0 :             break;
     998                 :            :         case NUMBERFORMAT_CURRENCY:
     999                 :          8 :             eType = XML_CURRENCY_STYLE;
    1000                 :          8 :             break;
    1001                 :            :         case NUMBERFORMAT_DATE:
    1002                 :            :         case NUMBERFORMAT_DATETIME:
    1003                 :         10 :             eType = XML_DATE_STYLE;
    1004                 :         10 :             break;
    1005                 :            :         case NUMBERFORMAT_TIME:
    1006                 :          0 :             eType = XML_TIME_STYLE;
    1007                 :          0 :             break;
    1008                 :            :         case NUMBERFORMAT_TEXT:
    1009                 :          0 :             eType = XML_TEXT_STYLE;
    1010                 :          0 :             break;
    1011                 :            :         case NUMBERFORMAT_LOGICAL:
    1012                 :          0 :             eType = XML_BOOLEAN_STYLE;
    1013                 :          0 :             break;
    1014                 :            :     }
    1015                 :            :     DBG_ASSERT( eType != XML_TOKEN_INVALID, "unknown format type" );
    1016                 :            : 
    1017                 :         33 :     OUString sAttrValue;
    1018                 :         33 :     sal_Bool bUserDef = ( ( rFormat.GetType() & NUMBERFORMAT_DEFINED ) != 0 );
    1019                 :            : 
    1020                 :            :     //
    1021                 :            :     //  common attributes for format
    1022                 :            :     //
    1023                 :            : 
    1024                 :            :     //  format name (generated from key) - style namespace
    1025                 :            :     rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
    1026 [ +  - ][ +  - ]:         33 :                         lcl_CreateStyleName( nKey, nPart, bDefPart, sPrefix ) );
    1027                 :            : 
    1028                 :            :     //  "volatile" attribute for styles used only in maps
    1029         [ +  + ]:         33 :     if ( !bDefPart )
    1030         [ +  - ]:          4 :         rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_VOLATILE, XML_TRUE );
    1031                 :            : 
    1032                 :            :     //  language / country
    1033                 :         33 :     LanguageType nLang = rFormat.GetLanguage();
    1034         [ +  - ]:         33 :     AddLanguageAttr_Impl( nLang );                  // adds to pAttrList
    1035                 :            : 
    1036                 :            :     //  title (comment)
    1037                 :            :     //  titles for builtin formats are not written
    1038         [ +  - ]:         33 :     sAttrValue = rFormat.GetComment();
    1039 [ #  # ][ #  # ]:         33 :     if ( !sAttrValue.isEmpty() && bUserDef && bDefPart )
         [ -  + ][ -  + ]
    1040                 :            :     {
    1041         [ #  # ]:          0 :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TITLE, sAttrValue );
    1042                 :            :     }
    1043                 :            : 
    1044                 :            :     //  automatic ordering for currency and date formats
    1045                 :            :     //  only used for some built-in formats
    1046                 :            :     sal_Bool bAutoOrder = ( eBuiltIn == NF_CURRENCY_1000INT     || eBuiltIn == NF_CURRENCY_1000DEC2 ||
    1047                 :            :                         eBuiltIn == NF_CURRENCY_1000INT_RED || eBuiltIn == NF_CURRENCY_1000DEC2_RED ||
    1048                 :            :                         eBuiltIn == NF_CURRENCY_1000DEC2_DASHED ||
    1049                 :            :                         eBuiltIn == NF_DATE_SYSTEM_SHORT    || eBuiltIn == NF_DATE_SYSTEM_LONG ||
    1050                 :            :                         eBuiltIn == NF_DATE_SYS_MMYY        || eBuiltIn == NF_DATE_SYS_DDMMM ||
    1051                 :            :                         eBuiltIn == NF_DATE_SYS_DDMMYYYY    || eBuiltIn == NF_DATE_SYS_DDMMYY ||
    1052                 :            :                         eBuiltIn == NF_DATE_SYS_DMMMYY      || eBuiltIn == NF_DATE_SYS_DMMMYYYY ||
    1053                 :            :                         eBuiltIn == NF_DATE_SYS_DMMMMYYYY   || eBuiltIn == NF_DATE_SYS_NNDMMMYY ||
    1054                 :            :                         eBuiltIn == NF_DATE_SYS_NNDMMMMYYYY || eBuiltIn == NF_DATE_SYS_NNNNDMMMMYYYY ||
    1055 [ +  - ][ +  - ]:         33 :                         eBuiltIn == NF_DATETIME_SYSTEM_SHORT_HHMM || eBuiltIn == NF_DATETIME_SYS_DDMMYYYY_HHMMSS );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ -  + ]
    1056                 :            : 
    1057                 :            :     //  format source (for date and time formats)
    1058                 :            :     //  only used for some built-in formats
    1059                 :            :     sal_Bool bSystemDate = ( eBuiltIn == NF_DATE_SYSTEM_SHORT ||
    1060                 :            :                          eBuiltIn == NF_DATE_SYSTEM_LONG  ||
    1061 [ +  - ][ +  - ]:         33 :                          eBuiltIn == NF_DATETIME_SYSTEM_SHORT_HHMM );
                 [ -  + ]
    1062                 :         33 :     sal_Bool bLongSysDate = ( eBuiltIn == NF_DATE_SYSTEM_LONG );
    1063                 :            : 
    1064                 :            :     // check if the format definition matches the key
    1065 [ +  + ][ -  + ]:         41 :     if ( bAutoOrder && ( nFmtType == NUMBERFORMAT_DATE || nFmtType == NUMBERFORMAT_DATETIME ) &&
         [ #  # ][ -  + ]
                 [ -  + ]
    1066         [ +  - ]:          8 :             !lcl_IsDefaultDateFormat( rFormat, bSystemDate, eBuiltIn ) )
    1067                 :            :     {
    1068                 :          0 :         bAutoOrder = bSystemDate = bLongSysDate = sal_False;        // don't write automatic-order attribute then
    1069                 :            :     }
    1070                 :            : 
    1071 [ +  + ][ +  - ]:         33 :     if ( bAutoOrder &&
         [ -  + ][ #  # ]
    1072                 :            :         ( nFmtType == NUMBERFORMAT_CURRENCY || nFmtType == NUMBERFORMAT_DATE || nFmtType == NUMBERFORMAT_DATETIME ) )
    1073                 :            :     {
    1074                 :            :         //  #85109# format type must be checked to avoid dtd errors if
    1075                 :            :         //  locale data contains other format types at the built-in positions
    1076                 :            : 
    1077                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_AUTOMATIC_ORDER,
    1078         [ +  - ]:          8 :                               XML_TRUE );
    1079                 :            :     }
    1080                 :            : 
    1081 [ -  + ][ #  # ]:         33 :     if ( bSystemDate && bAutoOrder &&
         [ #  # ][ #  # ]
    1082                 :            :         ( nFmtType == NUMBERFORMAT_DATE || nFmtType == NUMBERFORMAT_DATETIME ) )
    1083                 :            :     {
    1084                 :            :         //  #85109# format type must be checked to avoid dtd errors if
    1085                 :            :         //  locale data contains other format types at the built-in positions
    1086                 :            : 
    1087                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_FORMAT_SOURCE,
    1088         [ #  # ]:          0 :                               XML_LANGUAGE );
    1089                 :            :     }
    1090                 :            : 
    1091                 :            :     //  overflow for time formats as in [hh]:mm
    1092                 :            :     //  controlled by bThousand from number format info
    1093                 :            :     //  default for truncate-on-overflow is true
    1094 [ -  + ][ #  # ]:         33 :     if ( nFmtType == NUMBERFORMAT_TIME && bThousand )
    1095                 :            :     {
    1096                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRUNCATE_ON_OVERFLOW,
    1097         [ #  # ]:          0 :                               XML_FALSE );
    1098                 :            :     }
    1099                 :            : 
    1100                 :            :     //
    1101                 :            :     // Native number transliteration
    1102                 :            :     //
    1103                 :         33 :     ::com::sun::star::i18n::NativeNumberXmlAttributes aAttr;
    1104         [ +  - ]:         33 :     rFormat.GetNatNumXml( aAttr, nPart );
    1105         [ -  + ]:         33 :     if ( !aAttr.Format.isEmpty() )
    1106                 :            :     {
    1107                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_FORMAT,
    1108         [ #  # ]:          0 :                               aAttr.Format );
    1109                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_LANGUAGE,
    1110         [ #  # ]:          0 :                               aAttr.Locale.Language );
    1111                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_COUNTRY,
    1112         [ #  # ]:          0 :                               aAttr.Locale.Country );
    1113                 :            :         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_STYLE,
    1114         [ #  # ]:          0 :                               aAttr.Style );
    1115                 :            :     }
    1116                 :            : 
    1117                 :            :     //
    1118                 :            :     // The element
    1119                 :            :     //
    1120                 :            :     SvXMLElementExport aElem( rExport, XML_NAMESPACE_NUMBER, eType,
    1121         [ +  - ]:         33 :                               sal_True, sal_True );
    1122                 :            : 
    1123                 :            :     //
    1124                 :            :     //  color (properties element)
    1125                 :            :     //
    1126                 :            : 
    1127         [ +  - ]:         33 :     const Color* pCol = rFormat.GetColor( nPart );
    1128         [ +  + ]:         33 :     if (pCol)
    1129         [ +  - ]:          4 :         WriteColorElement_Impl(*pCol);
    1130                 :            : 
    1131                 :            : 
    1132                 :            :     //  detect if there is "real" content, excluding color and maps
    1133                 :            :     //! move to implementation of Write... methods?
    1134                 :         33 :     sal_Bool bAnyContent = sal_False;
    1135                 :            : 
    1136                 :            :     //
    1137                 :            :     //  format elements
    1138                 :            :     //
    1139                 :            : 
    1140         [ +  - ]:         33 :     SvXMLEmbeddedTextEntryArr aEmbeddedEntries;
    1141         [ +  + ]:         33 :     if ( eBuiltIn == NF_NUMBER_STANDARD )
    1142                 :            :     {
    1143                 :            :         //  default number format contains just one number element
    1144         [ +  - ]:         13 :         WriteNumberElement_Impl( -1, 1, OUString(), sal_False, sal_False, 0, aEmbeddedEntries );
    1145                 :         13 :         bAnyContent = sal_True;
    1146                 :            :     }
    1147         [ -  + ]:         20 :     else if ( eBuiltIn == NF_BOOLEAN )
    1148                 :            :     {
    1149                 :            :         //  boolean format contains just one boolean element
    1150         [ #  # ]:          0 :         WriteBooleanElement_Impl();
    1151                 :          0 :         bAnyContent = sal_True;
    1152                 :            :     }
    1153                 :            :     else
    1154                 :            :     {
    1155                 :            :         //  first loop to collect attributes
    1156                 :            : 
    1157                 :         20 :         sal_Bool bDecDashes  = sal_False;
    1158                 :         20 :         sal_Bool bVarDecimals = sal_False;
    1159                 :         20 :         sal_Bool bExpFound   = sal_False;
    1160                 :         20 :         sal_Bool bCurrFound  = sal_False;
    1161                 :         20 :         sal_Bool bInInteger  = sal_True;
    1162                 :         20 :         sal_Int32 nExpDigits = 0;
    1163                 :         20 :         sal_Int32 nIntegerSymbols = 0;          // for embedded-text, including "#"
    1164                 :         20 :         sal_Int32 nTrailingThousands = 0;       // thousands-separators after all digits
    1165                 :         20 :         OUString sCurrExt;
    1166                 :         20 :         OUString aCalendar;
    1167                 :         20 :         sal_uInt16 nPos = 0;
    1168                 :         20 :         sal_Bool bEnd = sal_False;
    1169         [ +  + ]:        168 :         while (!bEnd)
    1170                 :            :         {
    1171         [ +  - ]:        148 :             short nElemType = rFormat.GetNumForType( nPart, nPos, sal_False );
    1172         [ +  - ]:        148 :             const XubString* pElemStr = rFormat.GetNumForString( nPart, nPos, sal_False );
    1173                 :            : 
    1174   [ +  +  +  +  :        148 :             switch ( nElemType )
             -  +  +  -  
                      + ]
    1175                 :            :             {
    1176                 :            :                 case 0:
    1177                 :         20 :                     bEnd = sal_True;                // end of format reached
    1178                 :         20 :                     break;
    1179                 :            :                 case NF_SYMBOLTYPE_DIGIT:
    1180 [ -  + ][ #  # ]:         30 :                     if ( bExpFound && pElemStr )
    1181                 :          0 :                         nExpDigits += pElemStr->Len();
    1182 [ +  - ][ +  - ]:         30 :                     else if ( !bDecDashes && pElemStr && pElemStr->GetChar(0) == '-' )
         [ -  + ][ -  + ]
    1183                 :          0 :                         bDecDashes = sal_True;
    1184 [ +  - ][ +  + ]:         30 :                     else if ( !bVarDecimals && !bInInteger && pElemStr && pElemStr->GetChar(0) == '#' )
         [ +  - ][ -  + ]
                 [ -  + ]
    1185                 :            :                     {
    1186                 :            :                         //  If the decimal digits string starts with a '#', variable
    1187                 :            :                         //  decimals is assumed (for 0.###, but not 0.0##).
    1188                 :          0 :                         bVarDecimals = sal_True;
    1189                 :            :                     }
    1190 [ +  + ][ +  - ]:         30 :                     if ( bInInteger && pElemStr )
    1191                 :         20 :                         nIntegerSymbols += pElemStr->Len();
    1192                 :         30 :                     nTrailingThousands = 0;
    1193                 :         30 :                     break;
    1194                 :            :                 case NF_SYMBOLTYPE_DECSEP:
    1195                 :         10 :                     bInInteger = sal_False;
    1196                 :         10 :                     break;
    1197                 :            :                 case NF_SYMBOLTYPE_THSEP:
    1198         [ +  - ]:         10 :                     if (pElemStr)
    1199                 :         10 :                         nTrailingThousands += pElemStr->Len();      // is reset to 0 if digits follow
    1200                 :         10 :                     break;
    1201                 :            :                 case NF_SYMBOLTYPE_EXP:
    1202                 :          0 :                     bExpFound = sal_True;           // following digits are exponent digits
    1203                 :          0 :                     bInInteger = sal_False;
    1204                 :          0 :                     break;
    1205                 :            :                 case NF_SYMBOLTYPE_CURRENCY:
    1206                 :          8 :                     bCurrFound = sal_True;
    1207                 :          8 :                     break;
    1208                 :            :                 case NF_SYMBOLTYPE_CURREXT:
    1209         [ +  - ]:          8 :                     if (pElemStr)
    1210         [ +  - ]:          8 :                         sCurrExt = *pElemStr;
    1211                 :          8 :                     break;
    1212                 :            : 
    1213                 :            :                 // E, EE, R, RR: select non-gregorian calendar
    1214                 :            :                 // AAA, AAAA: calendar is switched at the position of the element
    1215                 :            :                 case NF_KEY_EC:
    1216                 :            :                 case NF_KEY_EEC:
    1217                 :            :                 case NF_KEY_R:
    1218                 :            :                 case NF_KEY_RR:
    1219         [ #  # ]:          0 :                     if (aCalendar.isEmpty())
    1220         [ #  # ]:          0 :                         aCalendar = lcl_GetDefaultCalendar( pFormatter, nLang );
    1221                 :          0 :                     break;
    1222                 :            :             }
    1223                 :        148 :             ++nPos;
    1224                 :            :         }
    1225                 :            : 
    1226                 :            :         //  collect strings for embedded-text (must be known before number element is written)
    1227                 :            : 
    1228                 :            :         sal_Bool bAllowEmbedded = ( nFmtType == 0 || nFmtType == NUMBERFORMAT_NUMBER ||
    1229                 :            :                                         nFmtType == NUMBERFORMAT_CURRENCY ||
    1230 [ +  - ][ +  + ]:         20 :                                         nFmtType == NUMBERFORMAT_PERCENT );
         [ +  + ][ -  + ]
    1231         [ +  + ]:         20 :         if ( bAllowEmbedded )
    1232                 :            :         {
    1233                 :         10 :             sal_Int32 nDigitsPassed = 0;
    1234                 :         10 :             nPos = 0;
    1235                 :         10 :             bEnd = sal_False;
    1236         [ +  + ]:        106 :             while (!bEnd)
    1237                 :            :             {
    1238         [ +  - ]:         96 :                 short nElemType = rFormat.GetNumForType( nPart, nPos, sal_False );
    1239         [ +  - ]:         96 :                 const XubString* pElemStr = rFormat.GetNumForString( nPart, nPos, sal_False );
    1240                 :            : 
    1241   [ +  +  +  + ]:         96 :                 switch ( nElemType )
    1242                 :            :                 {
    1243                 :            :                     case 0:
    1244                 :         10 :                         bEnd = sal_True;                // end of format reached
    1245                 :         10 :                         break;
    1246                 :            :                     case NF_SYMBOLTYPE_DIGIT:
    1247         [ +  - ]:         30 :                         if ( pElemStr )
    1248                 :         30 :                             nDigitsPassed += pElemStr->Len();
    1249                 :         30 :                         break;
    1250                 :            :                     case NF_SYMBOLTYPE_STRING:
    1251                 :            :                     case NF_SYMBOLTYPE_BLANK:
    1252                 :            :                     case NF_SYMBOLTYPE_PERCENT:
    1253 [ -  + ][ #  # ]:          4 :                         if ( nDigitsPassed > 0 && nDigitsPassed < nIntegerSymbols && pElemStr )
                 [ #  # ]
    1254                 :            :                         {
    1255                 :            :                             //  text (literal or underscore) within the integer part of a number:number element
    1256                 :            : 
    1257         [ #  # ]:          0 :                             String aEmbeddedStr;
    1258 [ #  # ][ #  # ]:          0 :                             if ( nElemType == NF_SYMBOLTYPE_STRING || nElemType == NF_SYMBOLTYPE_PERCENT )
    1259         [ #  # ]:          0 :                                 aEmbeddedStr = *pElemStr;
    1260                 :            :                             else
    1261         [ #  # ]:          0 :                                 SvNumberformat::InsertBlanks( aEmbeddedStr, 0, pElemStr->GetChar(1) );
    1262                 :            : 
    1263                 :          0 :                             sal_Int32 nEmbedPos = nIntegerSymbols - nDigitsPassed;
    1264                 :            : 
    1265 [ #  # ][ #  # ]:          0 :                             SvXMLEmbeddedTextEntry* pObj = new SvXMLEmbeddedTextEntry( nPos, nEmbedPos, aEmbeddedStr );
    1266 [ #  # ][ #  # ]:          0 :                             aEmbeddedEntries.push_back( pObj );
    1267                 :            :                         }
    1268                 :          4 :                         break;
    1269                 :            :                 }
    1270                 :         96 :                 ++nPos;
    1271                 :            :             }
    1272                 :            :         }
    1273                 :            : 
    1274                 :            :         //  final loop to write elements
    1275                 :            : 
    1276                 :         20 :         sal_Bool bNumWritten = sal_False;
    1277                 :         20 :         sal_Bool bCurrencyWritten = sal_False;
    1278                 :         20 :         short nPrevType = 0;
    1279                 :         20 :         nPos = 0;
    1280                 :         20 :         bEnd = sal_False;
    1281         [ +  + ]:        168 :         while (!bEnd)
    1282                 :            :         {
    1283         [ +  - ]:        148 :             short nElemType = rFormat.GetNumForType( nPart, nPos, sal_False );
    1284         [ +  - ]:        148 :             const XubString* pElemStr = rFormat.GetNumForString( nPart, nPos, sal_False );
    1285                 :            : 
    1286   [ +  +  -  -  :        148 :             switch ( nElemType )
          -  +  +  +  -  
          -  +  -  +  +  
          -  -  -  -  -  
             -  -  -  + ]
    1287                 :            :             {
    1288                 :            :                 case 0:
    1289                 :         20 :                     bEnd = sal_True;                // end of format reached
    1290                 :         20 :                     break;
    1291                 :            :                 case NF_SYMBOLTYPE_STRING:
    1292                 :            :                 case NF_SYMBOLTYPE_DATESEP:
    1293                 :            :                 case NF_SYMBOLTYPE_TIMESEP:
    1294                 :            :                 case NF_SYMBOLTYPE_TIME100SECSEP:
    1295                 :            :                 case NF_SYMBOLTYPE_PERCENT:
    1296         [ +  - ]:         20 :                     if (pElemStr)
    1297                 :            :                     {
    1298 [ +  - ][ -  + ]:         20 :                         if ( ( nPrevType == NF_KEY_S || nPrevType == NF_KEY_SS ) &&
         [ #  # ][ #  # ]
    1299                 :            :                              ( nElemType == NF_SYMBOLTYPE_TIME100SECSEP ) &&
    1300                 :            :                              nPrecision > 0 )
    1301                 :            :                         {
    1302                 :            :                             //  decimal separator after seconds is implied by
    1303                 :            :                             //  "decimal-places" attribute and must not be written
    1304                 :            :                             //  as text element
    1305                 :            :                             //! difference between '.' and ',' is lost here
    1306                 :            :                         }
    1307 [ +  - ][ +  - ]:         20 :                         else if ( lcl_IsInEmbedded( aEmbeddedEntries, nPos ) )
    1308                 :            :                         {
    1309                 :            :                             //  text is written as embedded-text child of the number,
    1310                 :            :                             //  don't create a text element
    1311                 :            :                         }
    1312 [ +  + ][ -  + ]:         20 :                         else if ( nFmtType == NUMBERFORMAT_CURRENCY && !bCurrFound && !bCurrencyWritten )
                 [ #  # ]
    1313                 :            :                         {
    1314                 :            :                             //  automatic currency symbol is implemented as part of
    1315                 :            :                             //  normal text -> search for the symbol
    1316                 :            :                             bCurrencyWritten = WriteTextWithCurrency_Impl( *pElemStr,
    1317 [ #  # ][ #  # ]:          0 :                                 MsLangId::convertLanguageToLocale( nLang ) );
                 [ #  # ]
    1318                 :          0 :                             bAnyContent = sal_True;
    1319                 :            :                         }
    1320                 :            :                         else
    1321 [ +  - ][ +  - ]:         20 :                             AddToTextElement_Impl( *pElemStr );
    1322                 :            :                     }
    1323                 :         20 :                     break;
    1324                 :            :                 case NF_SYMBOLTYPE_BLANK:
    1325 [ #  # ][ #  # ]:          0 :                     if ( pElemStr && !lcl_IsInEmbedded( aEmbeddedEntries, nPos ) )
         [ #  # ][ #  # ]
    1326                 :            :                     {
    1327                 :            :                         //  turn "_x" into the number of spaces used for x in InsertBlanks in the NumberFormat
    1328                 :            :                         //  (#i20396# the spaces may also be in embedded-text elements)
    1329                 :            : 
    1330         [ #  # ]:          0 :                         String aBlanks;
    1331         [ #  # ]:          0 :                         SvNumberformat::InsertBlanks( aBlanks, 0, pElemStr->GetChar(1) );
    1332 [ #  # ][ #  # ]:          0 :                         AddToTextElement_Impl( aBlanks );
                 [ #  # ]
    1333                 :            :                     }
    1334                 :          0 :                     break;
    1335                 :            :                 case NF_KEY_GENERAL :
    1336         [ #  # ]:          0 :                         WriteNumberElement_Impl( -1, 1, OUString(), sal_False, sal_False, 0, aEmbeddedEntries );
    1337                 :          0 :                     break;
    1338                 :            :                 case NF_KEY_CCC:
    1339         [ #  # ]:          0 :                     if (pElemStr)
    1340                 :            :                     {
    1341         [ #  # ]:          0 :                         if ( bCurrencyWritten )
    1342 [ #  # ][ #  # ]:          0 :                             AddToTextElement_Impl( *pElemStr );     // never more than one currency element
    1343                 :            :                         else
    1344                 :            :                         {
    1345                 :            :                             //! must be different from short automatic format
    1346                 :            :                             //! but should still be empty (meaning automatic)
    1347                 :            :                             //  pElemStr is "CCC"
    1348                 :            : 
    1349 [ #  # ][ #  # ]:          0 :                             WriteCurrencyElement_Impl( *pElemStr, OUString() );
    1350                 :          0 :                             bAnyContent = sal_True;
    1351                 :          0 :                             bCurrencyWritten = sal_True;
    1352                 :            :                         }
    1353                 :            :                     }
    1354                 :          0 :                     break;
    1355                 :            :                 case NF_SYMBOLTYPE_CURRENCY:
    1356         [ +  - ]:          8 :                     if (pElemStr)
    1357                 :            :                     {
    1358         [ -  + ]:          8 :                         if ( bCurrencyWritten )
    1359 [ #  # ][ #  # ]:          0 :                             AddToTextElement_Impl( *pElemStr );     // never more than one currency element
    1360                 :            :                         else
    1361                 :            :                         {
    1362 [ +  - ][ +  - ]:          8 :                             WriteCurrencyElement_Impl( *pElemStr, sCurrExt );
    1363                 :          8 :                             bAnyContent = sal_True;
    1364                 :          8 :                             bCurrencyWritten = sal_True;
    1365                 :            :                         }
    1366                 :            :                     }
    1367                 :          8 :                     break;
    1368                 :            :                 case NF_SYMBOLTYPE_DIGIT:
    1369         [ +  + ]:         30 :                     if (!bNumWritten)           // write number part
    1370                 :            :                     {
    1371   [ +  -  -  - ]:         10 :                         switch ( nFmtType )
    1372                 :            :                         {
    1373                 :            :                             // for type 0 (not recognized as a special type),
    1374                 :            :                             // write a "normal" number
    1375                 :            :                             case 0:
    1376                 :            :                             case NUMBERFORMAT_NUMBER:
    1377                 :            :                             case NUMBERFORMAT_CURRENCY:
    1378                 :            :                             case NUMBERFORMAT_PERCENT:
    1379                 :            :                                 {
    1380                 :            :                                     //  decimals
    1381                 :            :                                     //  only some built-in formats have automatic decimals
    1382                 :         10 :                                     sal_Int32 nDecimals = nPrecision;   // from GetFormatSpecialInfo
    1383 [ +  - ][ +  - ]:         10 :                                     if ( eBuiltIn == NF_NUMBER_STANDARD ||
         [ +  - ][ +  - ]
                 [ -  + ]
    1384                 :            :                                          eBuiltIn == NF_CURRENCY_1000DEC2 ||
    1385                 :            :                                          eBuiltIn == NF_CURRENCY_1000DEC2_RED ||
    1386                 :            :                                          eBuiltIn == NF_CURRENCY_1000DEC2_CCC ||
    1387                 :            :                                          eBuiltIn == NF_CURRENCY_1000DEC2_DASHED )
    1388                 :          0 :                                         nDecimals = -1;
    1389                 :            : 
    1390                 :            :                                     //  integer digits
    1391                 :            :                                     //  only one built-in format has automatic integer digits
    1392                 :         10 :                                     sal_Int32 nInteger = nLeading;
    1393         [ -  + ]:         10 :                                     if ( eBuiltIn == NF_NUMBER_SYSTEM )
    1394                 :          0 :                                         nInteger = -1;
    1395                 :            : 
    1396                 :            :                                     //  string for decimal replacement
    1397                 :            :                                     //  has to be taken from nPrecision
    1398                 :            :                                     //  (positive number even for automatic decimals)
    1399         [ +  - ]:         10 :                                     String sDashStr;
    1400 [ -  + ][ #  # ]:         10 :                                     if ( bDecDashes && nPrecision > 0 )
    1401         [ #  # ]:          0 :                                         sDashStr.Fill( nPrecision, '-' );
    1402                 :            : 
    1403                 :            :                                     WriteNumberElement_Impl( nDecimals, nInteger, sDashStr, bVarDecimals,
    1404 [ +  - ][ +  - ]:         10 :                                                         bThousand, nTrailingThousands, aEmbeddedEntries );
    1405         [ +  - ]:         10 :                                     bAnyContent = sal_True;
    1406                 :            :                                 }
    1407                 :         10 :                                 break;
    1408                 :            :                             case NUMBERFORMAT_SCIENTIFIC:
    1409                 :            :                                 // #i43959# for scientific numbers, count all integer symbols ("0" and "#")
    1410                 :            :                                 // as integer digits: use nIntegerSymbols instead of nLeading
    1411                 :            :                                 // (use of '#' to select multiples in exponent might be added later)
    1412         [ #  # ]:          0 :                                 WriteScientificElement_Impl( nPrecision, nIntegerSymbols, bThousand, nExpDigits );
    1413                 :          0 :                                 bAnyContent = sal_True;
    1414                 :          0 :                                 break;
    1415                 :            :                             case NUMBERFORMAT_FRACTION:
    1416                 :            :                                 {
    1417                 :          0 :                                     sal_Int32 nInteger = nLeading;
    1418 [ #  # ][ #  # ]:          0 :                                     if ( pElemStr && pElemStr->GetChar(0) == '?' )
                 [ #  # ]
    1419                 :            :                                     {
    1420                 :            :                                         //  If the first digit character is a question mark,
    1421                 :            :                                         //  the fraction doesn't have an integer part, and no
    1422                 :            :                                         //  min-integer-digits attribute must be written.
    1423                 :          0 :                                         nInteger = -1;
    1424                 :            :                                     }
    1425         [ #  # ]:          0 :                                     WriteFractionElement_Impl( nInteger, bThousand, nPrecision, nPrecision );
    1426                 :          0 :                                     bAnyContent = sal_True;
    1427                 :            :                                 }
    1428                 :          0 :                                 break;
    1429                 :            :                         }
    1430                 :            : 
    1431                 :         10 :                         bNumWritten = sal_True;
    1432                 :            :                     }
    1433                 :         30 :                     break;
    1434                 :            :                 case NF_SYMBOLTYPE_DECSEP:
    1435 [ +  - ][ -  + ]:         10 :                     if ( pElemStr && nPrecision == 0 )
    1436                 :            :                     {
    1437                 :            :                         //  A decimal separator after the number, without following decimal digits,
    1438                 :            :                         //  isn't modelled as part of the number element, so it's written as text
    1439                 :            :                         //  (the distinction between a quoted and non-quoted, locale-dependent
    1440                 :            :                         //  character is lost here).
    1441                 :            : 
    1442 [ #  # ][ #  # ]:          0 :                         AddToTextElement_Impl( *pElemStr );
    1443                 :            :                     }
    1444                 :         10 :                     break;
    1445                 :            :                 case NF_SYMBOLTYPE_DEL:
    1446 [ #  # ][ #  # ]:          0 :                     if ( pElemStr && comphelper::string::equals(*pElemStr, '@') )
         [ #  # ][ #  # ]
           [ #  #  #  # ]
    1447                 :            :                     {
    1448         [ #  # ]:          0 :                         WriteTextContentElement_Impl();
    1449                 :          0 :                         bAnyContent = sal_True;
    1450                 :            :                     }
    1451                 :          0 :                     break;
    1452                 :            : 
    1453                 :            :                 case NF_SYMBOLTYPE_CALENDAR:
    1454         [ #  # ]:          0 :                     if ( pElemStr )
    1455         [ #  # ]:          0 :                         aCalendar = *pElemStr;
    1456                 :          0 :                     break;
    1457                 :            : 
    1458                 :            :                 // date elements:
    1459                 :            : 
    1460                 :            :                 case NF_KEY_D:
    1461                 :            :                 case NF_KEY_DD:
    1462                 :            :                     {
    1463                 :          8 :                         sal_Bool bLong = ( nElemType == NF_KEY_DD );
    1464 [ -  + ][ +  - ]:          8 :                         WriteDayElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
    1465                 :          8 :                         bAnyContent = sal_True;
    1466                 :            :                     }
    1467                 :          8 :                     break;
    1468                 :            :                 case NF_KEY_DDD:
    1469                 :            :                 case NF_KEY_DDDD:
    1470                 :            :                 case NF_KEY_NN:
    1471                 :            :                 case NF_KEY_NNN:
    1472                 :            :                 case NF_KEY_NNNN:
    1473                 :            :                 case NF_KEY_AAA:
    1474                 :            :                 case NF_KEY_AAAA:
    1475                 :            :                     {
    1476                 :          0 :                         OUString aCalAttr = aCalendar;
    1477 [ #  # ][ #  # ]:          0 :                         if ( nElemType == NF_KEY_AAA || nElemType == NF_KEY_AAAA )
    1478                 :            :                         {
    1479                 :            :                             //  calendar attribute for AAA and AAAA is switched only for this element
    1480         [ #  # ]:          0 :                             if (aCalAttr.isEmpty())
    1481         [ #  # ]:          0 :                                 aCalAttr = lcl_GetDefaultCalendar( pFormatter, nLang );
    1482                 :            :                         }
    1483                 :            : 
    1484                 :            :                         sal_Bool bLong = ( nElemType == NF_KEY_NNN || nElemType == NF_KEY_NNNN ||
    1485 [ #  # ][ #  # ]:          0 :                                            nElemType == NF_KEY_DDDD || nElemType == NF_KEY_AAAA );
         [ #  # ][ #  # ]
    1486 [ #  # ][ #  # ]:          0 :                         WriteDayOfWeekElement_Impl( aCalAttr, ( bSystemDate ? bLongSysDate : bLong ) );
    1487                 :          0 :                         bAnyContent = sal_True;
    1488         [ #  # ]:          0 :                         if ( nElemType == NF_KEY_NNNN )
    1489                 :            :                         {
    1490                 :            :                             //  write additional text element for separator
    1491 [ #  # ][ #  # ]:          0 :                             pLocaleData->setLocale( MsLangId::convertLanguageToLocale( nLang ) );
    1492 [ #  # ][ #  # ]:          0 :                             AddToTextElement_Impl( pLocaleData->getLongDateDayOfWeekSep() );
    1493                 :          0 :                         }
    1494                 :            :                     }
    1495                 :          0 :                     break;
    1496                 :            :                 case NF_KEY_M:
    1497                 :            :                 case NF_KEY_MM:
    1498                 :            :                 case NF_KEY_MMM:
    1499                 :            :                 case NF_KEY_MMMM:
    1500                 :            :                 case NF_KEY_MMMMM:      //! first letter of month name, no attribute available
    1501                 :            :                     {
    1502 [ +  + ][ +  - ]:         10 :                         sal_Bool bLong = ( nElemType == NF_KEY_MM  || nElemType == NF_KEY_MMMM );
    1503                 :            :                         sal_Bool bText = ( nElemType == NF_KEY_MMM || nElemType == NF_KEY_MMMM ||
    1504 [ +  - ][ +  + ]:         10 :                                             nElemType == NF_KEY_MMMMM );
                 [ -  + ]
    1505 [ -  + ][ +  - ]:         10 :                         WriteMonthElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ), bText );
    1506                 :         10 :                         bAnyContent = sal_True;
    1507                 :            :                     }
    1508                 :         10 :                     break;
    1509                 :            :                 case NF_KEY_YY:
    1510                 :            :                 case NF_KEY_YYYY:
    1511                 :            :                 case NF_KEY_EC:
    1512                 :            :                 case NF_KEY_EEC:
    1513                 :            :                 case NF_KEY_R:      //! R acts as EE, no attribute available
    1514                 :            :                     {
    1515                 :            :                         //! distinguish EE and R
    1516                 :            :                         //  calendar attribute for E and EE and R is set in first loop
    1517                 :            :                         sal_Bool bLong = ( nElemType == NF_KEY_YYYY || nElemType == NF_KEY_EEC ||
    1518 [ -  + ][ #  # ]:          8 :                                             nElemType == NF_KEY_R );
                 [ #  # ]
    1519 [ -  + ][ +  - ]:          8 :                         WriteYearElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
    1520                 :          8 :                         bAnyContent = sal_True;
    1521                 :            :                     }
    1522                 :          8 :                     break;
    1523                 :            :                 case NF_KEY_G:
    1524                 :            :                 case NF_KEY_GG:
    1525                 :            :                 case NF_KEY_GGG:
    1526                 :            :                 case NF_KEY_RR:     //! RR acts as GGGEE, no attribute available
    1527                 :            :                     {
    1528                 :            :                         //! distinguish GG and GGG and RR
    1529 [ #  # ][ #  # ]:          0 :                         sal_Bool bLong = ( nElemType == NF_KEY_GGG || nElemType == NF_KEY_RR );
    1530 [ #  # ][ #  # ]:          0 :                         WriteEraElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
    1531                 :          0 :                         bAnyContent = sal_True;
    1532         [ #  # ]:          0 :                         if ( nElemType == NF_KEY_RR )
    1533                 :            :                         {
    1534                 :            :                             //  calendar attribute for RR is set in first loop
    1535 [ #  # ][ #  # ]:          0 :                             WriteYearElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : sal_True ) );
    1536                 :            :                         }
    1537                 :            :                     }
    1538                 :          0 :                     break;
    1539                 :            :                 case NF_KEY_Q:
    1540                 :            :                 case NF_KEY_QQ:
    1541                 :            :                     {
    1542                 :          0 :                         sal_Bool bLong = ( nElemType == NF_KEY_QQ );
    1543 [ #  # ][ #  # ]:          0 :                         WriteQuarterElement_Impl( aCalendar, ( bSystemDate ? bLongSysDate : bLong ) );
    1544                 :          0 :                         bAnyContent = sal_True;
    1545                 :            :                     }
    1546                 :          0 :                     break;
    1547                 :            :                 case NF_KEY_WW:
    1548         [ #  # ]:          0 :                     WriteWeekElement_Impl( aCalendar );
    1549                 :          0 :                     bAnyContent = sal_True;
    1550                 :          0 :                     break;
    1551                 :            : 
    1552                 :            :                 // time elements (bSystemDate is not used):
    1553                 :            : 
    1554                 :            :                 case NF_KEY_H:
    1555                 :            :                 case NF_KEY_HH:
    1556         [ #  # ]:          0 :                     WriteHoursElement_Impl( nElemType == NF_KEY_HH );
    1557                 :          0 :                     bAnyContent = sal_True;
    1558                 :          0 :                     break;
    1559                 :            :                 case NF_KEY_MI:
    1560                 :            :                 case NF_KEY_MMI:
    1561         [ #  # ]:          0 :                     WriteMinutesElement_Impl( nElemType == NF_KEY_MMI );
    1562                 :          0 :                     bAnyContent = sal_True;
    1563                 :          0 :                     break;
    1564                 :            :                 case NF_KEY_S:
    1565                 :            :                 case NF_KEY_SS:
    1566         [ #  # ]:          0 :                     WriteSecondsElement_Impl( ( nElemType == NF_KEY_SS ), nPrecision );
    1567                 :          0 :                     bAnyContent = sal_True;
    1568                 :          0 :                     break;
    1569                 :            :                 case NF_KEY_AMPM:
    1570                 :            :                 case NF_KEY_AP:
    1571         [ #  # ]:          0 :                     WriteAMPMElement_Impl();        // short/long?
    1572                 :          0 :                     bAnyContent = sal_True;
    1573                 :          0 :                     break;
    1574                 :            :                 case NF_SYMBOLTYPE_STAR :
    1575                 :            :                     // export only if ODF 1.2 extensions are enabled
    1576 [ #  # ][ #  # ]:          0 :                     if( SvtSaveOptions().GetODFDefaultVersion() > SvtSaveOptions::ODFVER_012 )
         [ #  # ][ #  # ]
    1577                 :            :                     {
    1578 [ #  # ][ #  # ]:          0 :                         if ( pElemStr && pElemStr->Len() > 1 )
                 [ #  # ]
    1579         [ #  # ]:          0 :                             WriteRepeatedElement_Impl( pElemStr->GetChar( 1 ) );
    1580                 :            :                     }
    1581                 :          0 :                     break;
    1582                 :            :             }
    1583                 :        148 :             nPrevType = nElemType;
    1584                 :        148 :             ++nPos;
    1585                 :         20 :         }
    1586                 :            :     }
    1587                 :            : 
    1588         [ -  + ]:         33 :     if ( sTextContent.getLength() )
    1589                 :          0 :         bAnyContent = sal_True;     // element written in FinishTextElement_Impl
    1590                 :            : 
    1591         [ +  - ]:         33 :     FinishTextElement_Impl();       // final text element - before maps
    1592                 :            : 
    1593         [ -  + ]:         33 :     if ( !bAnyContent )
    1594                 :            :     {
    1595                 :            :         //  for an empty format, write an empty text element
    1596                 :            :         SvXMLElementExport aTElem( rExport, XML_NAMESPACE_NUMBER, XML_TEXT,
    1597 [ #  # ][ #  # ]:          0 :                                    sal_True, sal_False );
    1598                 :            :     }
    1599                 :            : 
    1600                 :            :     //
    1601                 :            :     //  mapping (conditions) must be last elements
    1602                 :            :     //
    1603                 :            : 
    1604         [ +  + ]:         33 :     if (bDefPart)
    1605                 :            :     {
    1606                 :            :         SvNumberformatLimitOps eOp1, eOp2;
    1607                 :            :         double fLimit1, fLimit2;
    1608         [ +  - ]:         29 :         rFormat.GetConditions( eOp1, fLimit1, eOp2, fLimit2 );
    1609                 :            : 
    1610         [ +  - ]:         29 :         WriteMapElement_Impl( eOp1, fLimit1, nKey, 0 );
    1611         [ +  - ]:         29 :         WriteMapElement_Impl( eOp2, fLimit2, nKey, 1 );
    1612                 :            : 
    1613         [ -  + ]:         29 :         if ( rFormat.HasTextFormat() )
    1614                 :            :         {
    1615                 :            :             //  4th part is for text -> make an "all other numbers" condition for the 3rd part
    1616                 :            :             //  by reversing the 2nd condition
    1617                 :            : 
    1618                 :          0 :             SvNumberformatLimitOps eOp3 = NUMBERFORMAT_OP_NO;
    1619                 :          0 :             double fLimit3 = fLimit2;
    1620   [ #  #  #  #  :          0 :             switch ( eOp2 )
                #  #  # ]
    1621                 :            :             {
    1622                 :          0 :                 case NUMBERFORMAT_OP_EQ: eOp3 = NUMBERFORMAT_OP_NE; break;
    1623                 :          0 :                 case NUMBERFORMAT_OP_NE: eOp3 = NUMBERFORMAT_OP_EQ; break;
    1624                 :          0 :                 case NUMBERFORMAT_OP_LT: eOp3 = NUMBERFORMAT_OP_GE; break;
    1625                 :          0 :                 case NUMBERFORMAT_OP_LE: eOp3 = NUMBERFORMAT_OP_GT; break;
    1626                 :          0 :                 case NUMBERFORMAT_OP_GT: eOp3 = NUMBERFORMAT_OP_LE; break;
    1627                 :          0 :                 case NUMBERFORMAT_OP_GE: eOp3 = NUMBERFORMAT_OP_LT; break;
    1628                 :            :                 default:
    1629                 :          0 :                     break;
    1630                 :            :             }
    1631                 :            : 
    1632 [ #  # ][ #  # ]:          0 :             if ( fLimit1 == fLimit2 &&
         [ #  # ][ #  # ]
                 [ #  # ]
    1633                 :            :                     ( ( eOp1 == NUMBERFORMAT_OP_LT && eOp2 == NUMBERFORMAT_OP_GT ) ||
    1634                 :            :                       ( eOp1 == NUMBERFORMAT_OP_GT && eOp2 == NUMBERFORMAT_OP_LT ) ) )
    1635                 :            :             {
    1636                 :            :                 //  For <x and >x, add =x as last condition
    1637                 :            :                 //  (just for readability, <=x would be valid, too)
    1638                 :            : 
    1639                 :          0 :                 eOp3 = NUMBERFORMAT_OP_EQ;
    1640                 :            :             }
    1641                 :            : 
    1642         [ #  # ]:         29 :             WriteMapElement_Impl( eOp3, fLimit3, nKey, 2 );
    1643                 :            :         }
    1644 [ +  - ][ +  - ]:         33 :     }
    1645                 :         33 : }
    1646                 :            : 
    1647                 :            : //-------------------------------------------------------------------------
    1648                 :            : 
    1649                 :            : //
    1650                 :            : //  export one format
    1651                 :            : //
    1652                 :            : 
    1653                 :         29 : void SvXMLNumFmtExport::ExportFormat_Impl( const SvNumberformat& rFormat, sal_uInt32 nKey )
    1654                 :            : {
    1655                 :         29 :     sal_uInt16 nUsedParts = 0;
    1656                 :            :     sal_uInt16 nPart;
    1657         [ +  + ]:        116 :     for (nPart=0; nPart<XMLNUM_MAX_PARTS; nPart++)
    1658 [ +  - ][ +  + ]:         87 :         if (rFormat.GetNumForType( nPart, 0, sal_False ) != 0)
    1659                 :         33 :             nUsedParts = nPart+1;
    1660                 :            : 
    1661                 :            :     SvNumberformatLimitOps eOp1, eOp2;
    1662                 :            :     double fLimit1, fLimit2;
    1663         [ +  - ]:         29 :     rFormat.GetConditions( eOp1, fLimit1, eOp2, fLimit2 );
    1664                 :            : 
    1665                 :            :     //  if conditions are set, even empty formats must be written
    1666                 :            : 
    1667 [ +  + ][ -  + ]:         29 :     if ( eOp1 != NUMBERFORMAT_OP_NO && nUsedParts < 2 )
    1668                 :          0 :         nUsedParts = 2;
    1669 [ -  + ][ #  # ]:         29 :     if ( eOp2 != NUMBERFORMAT_OP_NO && nUsedParts < 3 )
    1670                 :          0 :         nUsedParts = 3;
    1671 [ -  + ][ #  # ]:         29 :     if ( rFormat.HasTextFormat() && nUsedParts < 4 )
                 [ -  + ]
    1672                 :          0 :         nUsedParts = 4;
    1673                 :            : 
    1674         [ +  + ]:         62 :     for (nPart=0; nPart<nUsedParts; nPart++)
    1675                 :            :     {
    1676                 :         33 :         sal_Bool bDefault = ( nPart+1 == nUsedParts );          // last = default
    1677         [ +  - ]:         33 :         ExportPart_Impl( rFormat, nKey, nPart, bDefault );
    1678                 :            :     }
    1679                 :         29 : }
    1680                 :            : 
    1681                 :            : //-------------------------------------------------------------------------
    1682                 :            : 
    1683                 :            : //
    1684                 :            : //  export method called by application
    1685                 :            : //
    1686                 :            : 
    1687                 :        233 : void SvXMLNumFmtExport::Export( sal_Bool bIsAutoStyle )
    1688                 :            : {
    1689         [ +  - ]:        233 :     if ( !pFormatter )
    1690                 :        233 :         return;                         // no formatter -> no entries
    1691                 :            : 
    1692                 :            :     sal_uInt32 nKey;
    1693                 :        233 :     const SvNumberformat* pFormat = NULL;
    1694         [ +  - ]:        233 :     sal_Bool bNext(pUsedList->GetFirstUsed(nKey));
    1695         [ +  + ]:        262 :     while(bNext)
    1696                 :            :     {
    1697         [ +  - ]:         29 :         pFormat = pFormatter->GetEntry(nKey);
    1698         [ +  - ]:         29 :         if(pFormat)
    1699         [ +  - ]:         29 :             ExportFormat_Impl( *pFormat, nKey );
    1700         [ +  - ]:         29 :         bNext = pUsedList->GetNextUsed(nKey);
    1701                 :            :     }
    1702         [ +  + ]:        233 :     if (!bIsAutoStyle)
    1703                 :            :     {
    1704         [ +  - ]:        178 :         std::vector<sal_uInt16> aLanguages;
    1705         [ +  - ]:        178 :         pFormatter->GetUsedLanguages( aLanguages );
    1706 [ +  - ][ +  - ]:        356 :         for (std::vector<sal_uInt16>::const_iterator it(aLanguages.begin()); it != aLanguages.end(); ++it)
         [ +  - ][ +  + ]
    1707                 :            :         {
    1708         [ +  - ]:        178 :             LanguageType nLang = *it;
    1709                 :            : 
    1710                 :        178 :             sal_uInt32 nDefaultIndex = 0;
    1711                 :            :             SvNumberFormatTable& rTable = pFormatter->GetEntryTable(
    1712         [ +  - ]:        178 :                                             NUMBERFORMAT_DEFINED, nDefaultIndex, nLang );
    1713                 :        178 :             SvNumberFormatTable::iterator it2 = rTable.begin();
    1714 [ +  - ][ -  + ]:        178 :             while (it2 != rTable.end())
    1715                 :            :             {
    1716         [ #  # ]:          0 :                 nKey = it2->first;
    1717         [ #  # ]:          0 :                 pFormat = it2->second;
    1718 [ #  # ][ #  # ]:          0 :                 if (!pUsedList->IsUsed(nKey))
    1719                 :            :                 {
    1720                 :            :                     DBG_ASSERT((pFormat->GetType() & NUMBERFORMAT_DEFINED) != 0, "a not user defined numberformat found");
    1721                 :            :                     //  user-defined and used formats are exported
    1722         [ #  # ]:          0 :                     ExportFormat_Impl( *pFormat, nKey );
    1723                 :            :                     // if it is a user-defined Format it will be added else nothing will hapen
    1724         [ #  # ]:          0 :                     pUsedList->SetUsed(nKey);
    1725                 :            :                 }
    1726                 :            : 
    1727         [ #  # ]:          0 :                 ++it2;
    1728                 :            :             }
    1729                 :        178 :         }
    1730                 :            :     }
    1731         [ +  - ]:        233 :     pUsedList->Export();
    1732                 :            : }
    1733                 :            : 
    1734                 :         67 : OUString SvXMLNumFmtExport::GetStyleName( sal_uInt32 nKey )
    1735                 :            : {
    1736 [ +  + ][ +  - ]:         67 :     if(pUsedList->IsUsed(nKey) || pUsedList->IsWasUsed(nKey))
                 [ +  - ]
    1737                 :         67 :         return lcl_CreateStyleName( nKey, 0, sal_True, sPrefix );
    1738                 :            :     else
    1739                 :            :     {
    1740                 :            :         OSL_FAIL("There is no written Data-Style");
    1741                 :         67 :         return rtl::OUString();
    1742                 :            :     }
    1743                 :            : }
    1744                 :            : 
    1745                 :        138 : void SvXMLNumFmtExport::SetUsed( sal_uInt32 nKey )
    1746                 :            : {
    1747                 :            :     DBG_ASSERT( pFormatter != NULL, "missing formatter" );
    1748         [ -  + ]:        138 :     if( !pFormatter )
    1749                 :        138 :         return;
    1750                 :            : 
    1751         [ +  - ]:        138 :     if (pFormatter->GetEntry(nKey))
    1752                 :        138 :         pUsedList->SetUsed( nKey );
    1753                 :            :     else {
    1754                 :            :         OSL_FAIL("no existing Numberformat found with this key");
    1755                 :            :     }
    1756                 :            : }
    1757                 :            : 
    1758                 :         50 : void SvXMLNumFmtExport::GetWasUsed(uno::Sequence<sal_Int32>& rWasUsed)
    1759                 :            : {
    1760         [ +  - ]:         50 :     if (pUsedList)
    1761                 :         50 :         pUsedList->GetWasUsed(rWasUsed);
    1762                 :         50 : }
    1763                 :            : 
    1764                 :         25 : void SvXMLNumFmtExport::SetWasUsed(const uno::Sequence<sal_Int32>& rWasUsed)
    1765                 :            : {
    1766         [ +  - ]:         25 :     if (pUsedList)
    1767                 :         25 :         pUsedList->SetWasUsed(rWasUsed);
    1768                 :         25 : }
    1769                 :            : 
    1770                 :            : 
    1771                 :            : 
    1772                 :         10 : const SvNumberformat* lcl_GetFormat( SvNumberFormatter* pFormatter,
    1773                 :            :                            sal_uInt32 nKey )
    1774                 :            : {
    1775         [ +  - ]:         10 :     return ( pFormatter != NULL ) ? pFormatter->GetEntry( nKey ) : NULL;
    1776                 :            : }
    1777                 :            : 
    1778                 :         10 : sal_uInt32 SvXMLNumFmtExport::ForceSystemLanguage( sal_uInt32 nKey )
    1779                 :            : {
    1780                 :         10 :     sal_uInt32 nRet = nKey;
    1781                 :            : 
    1782                 :         10 :     const SvNumberformat* pFormat = lcl_GetFormat( pFormatter, nKey );
    1783         [ +  - ]:         10 :     if( pFormat != NULL )
    1784                 :            :     {
    1785                 :            :         DBG_ASSERT( pFormatter != NULL, "format without formatter?" );
    1786                 :            : 
    1787                 :            :         xub_StrLen nErrorPos;
    1788                 :         10 :         short nType = pFormat->GetType();
    1789                 :            : 
    1790                 :            :         sal_uInt32 nNewKey = pFormatter->GetFormatForLanguageIfBuiltIn(
    1791         [ +  - ]:         10 :                        nKey, LANGUAGE_SYSTEM );
    1792                 :            : 
    1793         [ -  + ]:         10 :         if( nNewKey != nKey )
    1794                 :            :         {
    1795                 :          0 :             nRet = nNewKey;
    1796                 :            :         }
    1797                 :            :         else
    1798                 :            :         {
    1799         [ +  - ]:         10 :             String aFormatString( pFormat->GetFormatstring() );
    1800                 :            :             pFormatter->PutandConvertEntry(
    1801                 :            :                             aFormatString,
    1802                 :            :                             nErrorPos, nType, nNewKey,
    1803         [ +  - ]:         10 :                             pFormat->GetLanguage(), LANGUAGE_SYSTEM );
    1804                 :            : 
    1805                 :            :             // success? Then use new key.
    1806         [ +  - ]:         10 :             if( nErrorPos == 0 )
    1807         [ +  - ]:         10 :                 nRet = nNewKey;
    1808                 :            :         }
    1809                 :            :     }
    1810                 :            : 
    1811                 :         10 :     return nRet;
    1812                 :            : }
    1813                 :            : 
    1814                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10