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