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