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