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