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