1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 #include <tools/debug.hxx>
31 #include <XMLNumberStylesExport.hxx>
32 #include <XMLNumberStylesImport.hxx>
33 #include "xmloff/xmlnmspe.hxx"
34 #include <xmloff/xmlimp.hxx>
35 #include <xmloff/nmspmap.hxx>
36 #include <xmloff/xmltoken.hxx>
37 
38 #include "sdxmlexp_impl.hxx"
39 #include "sdxmlimp_impl.hxx"
40 
41 using namespace rtl;
42 using namespace ::xmloff::token;
43 
44 struct SdXMLDataStyleNumber
45 {
46 	enum XMLTokenEnum meNumberStyle;
47 	sal_Bool	mbLong;
48 	sal_Bool	mbTextual;
49 	sal_Bool	mbDecimal02;
50 	const char* mpText;
51 }
52 	aSdXMLDataStyleNumbers[] =
53 {
54 	{ XML_DAY,			sal_False,		sal_False,		sal_False,		NULL },
55 	{ XML_DAY,			sal_True,		sal_False,		sal_False,		NULL },
56 	{ XML_MONTH,		sal_True,		sal_False,		sal_False,		NULL },
57 	{ XML_MONTH,		sal_False,		sal_True,		sal_False,		NULL },
58 	{ XML_MONTH,		sal_True,		sal_True,		sal_False,		NULL },
59 	{ XML_YEAR,		    sal_False,		sal_False,		sal_False,		NULL },
60 	{ XML_YEAR,		    sal_True,		sal_False,		sal_False,		NULL },
61 	{ XML_DAY_OF_WEEK,	sal_False,		sal_False,		sal_False,		NULL },
62 	{ XML_DAY_OF_WEEK,  sal_True,		sal_False,		sal_False,		NULL },
63 	{ XML_TEXT,		    sal_False,		sal_False,		sal_False,		"."	 },
64 	{ XML_TEXT,		    sal_False,		sal_False,		sal_False,		" "  },
65 	{ XML_TEXT,		    sal_False,		sal_False,		sal_False,		", " },
66 	{ XML_TEXT,		    sal_False,		sal_False,		sal_False,		". " },
67 	{ XML_HOURS,		sal_False,		sal_False,		sal_False,		NULL },
68 	{ XML_MINUTES,		sal_False,		sal_False,		sal_False,		NULL },
69 	{ XML_TEXT,		    sal_False,		sal_False,		sal_False,		":"  },
70 	{ XML_AM_PM,		sal_False,		sal_False,		sal_False,		NULL },
71 	{ XML_SECONDS,		sal_False,		sal_False,		sal_False,		NULL },
72 	{ XML_SECONDS,		sal_False,		sal_False,		sal_True,		NULL },
73 	{ XML_TOKEN_INVALID,        0,              0,             0,       NULL  }
74 };
75 
76 // date
77 
78 #define DATA_STYLE_NUMBER_END				0
79 #define DATA_STYLE_NUMBER_DAY				1	// <number:day/>
80 #define DATA_STYLE_NUMBER_DAY_LONG			2	// <number:day number:style="long"/>
81 #define DATA_STYLE_NUMBER_MONTH_LONG		3	// <number:month number:style="long"/>
82 #define DATA_STYLE_NUMBER_MONTH_TEXT		4	// <number:month number:textual="true"/>
83 #define DATA_STYLE_NUMBER_MONTH_LONG_TEXT	5	// <number:month number:style="long" number:textual="true"/>
84 #define DATA_STYLE_NUMBER_YEAR				6	// <number:year/>
85 #define DATA_STYLE_NUMBER_YEAR_LONG			7	// <number:year number:style="long"/>
86 #define DATA_STYLE_NUMBER_DAYOFWEEK			8	// <number:day-of-week/>
87 #define DATA_STYLE_NUMBER_DAYOFWEEK_LONG	9	// <number:day-of-week number:style="long"/>
88 #define DATA_STYLE_NUMBER_TEXT_POINT		10	// <number:text>.</number:text>
89 #define DATA_STYLE_NUMBER_TEXT_SPACE		11	// <number:text> </number:text>
90 #define DATA_STYLE_NUMBER_TEXT_COMMASPACE	12	// <number:text>, </number:text>
91 #define DATA_STYLE_NUMBER_TEXT_POINTSPACE	13	// <number:text>. </number:text>
92 #define DATA_STYLE_NUMBER_HOURS				14	// <number:hours/>
93 #define DATA_STYLE_NUMBER_MINUTES			15	// <number:minutes/>
94 #define DATA_STYLE_NUMBER_TEXT_COLON		16	// <number:text>:</number:text>
95 #define DATA_STYLE_NUMBER_AMPM				17	// <number:am-pm/>
96 #define DATA_STYLE_NUMBER_SECONDS			18	// <number:seconds/>
97 #define DATA_STYLE_NUMBER_SECONDS_02		19	// <number:seconds number:/>
98 
99 
100 struct SdXMLFixedDataStyle
101 {
102 	const char*	mpName;
103 	sal_Bool	mbAutomatic;
104 	sal_Bool	mbDateStyle;
105 	sal_uInt8	mpFormat[8];
106 };
107 
108 const SdXMLFixedDataStyle aSdXML_Standard_Short =
109 {
110 	"D1", sal_True, sal_True,
111 	{
112 		DATA_STYLE_NUMBER_DAY_LONG,
113 		DATA_STYLE_NUMBER_TEXT_POINT,
114 		DATA_STYLE_NUMBER_MONTH_LONG,
115 		DATA_STYLE_NUMBER_TEXT_POINT,
116 		DATA_STYLE_NUMBER_YEAR_LONG,
117 		0, 0, 0
118 	}
119 };
120 
121 const SdXMLFixedDataStyle aSdXML_Standard_Long =
122 {
123 	"D2", sal_True, sal_True,
124 	{
125 		DATA_STYLE_NUMBER_DAYOFWEEK_LONG,
126 		DATA_STYLE_NUMBER_TEXT_COMMASPACE,
127 		DATA_STYLE_NUMBER_DAY,
128 		DATA_STYLE_NUMBER_TEXT_POINTSPACE,
129 		DATA_STYLE_NUMBER_MONTH_LONG_TEXT,
130 		DATA_STYLE_NUMBER_TEXT_SPACE,
131 		DATA_STYLE_NUMBER_YEAR_LONG,
132 		0
133 	}
134 };
135 
136 const SdXMLFixedDataStyle aSdXML_DateStyle_1 =
137 {
138 	"D3", sal_False, sal_True,
139 	{
140 		DATA_STYLE_NUMBER_DAY_LONG,
141 		DATA_STYLE_NUMBER_TEXT_POINT,
142 		DATA_STYLE_NUMBER_MONTH_LONG,
143 		DATA_STYLE_NUMBER_TEXT_POINT,
144 		DATA_STYLE_NUMBER_YEAR,
145 		0, 0, 0
146 	}
147 };
148 
149 const SdXMLFixedDataStyle aSdXML_DateStyle_2 =
150 {
151 	"D4", sal_False, sal_True,
152 	{
153 		DATA_STYLE_NUMBER_DAY_LONG,
154 		DATA_STYLE_NUMBER_TEXT_POINT,
155 		DATA_STYLE_NUMBER_MONTH_LONG,
156 		DATA_STYLE_NUMBER_TEXT_POINT,
157 		DATA_STYLE_NUMBER_YEAR_LONG,
158 		0, 0, 0
159 	}
160 };
161 
162 const SdXMLFixedDataStyle aSdXML_DateStyle_3 =
163 {
164 	"D5", sal_False, sal_True,
165 	{
166 		DATA_STYLE_NUMBER_DAY,
167 		DATA_STYLE_NUMBER_TEXT_POINTSPACE,
168 		DATA_STYLE_NUMBER_MONTH_TEXT,
169 		DATA_STYLE_NUMBER_TEXT_SPACE,
170 		DATA_STYLE_NUMBER_YEAR_LONG,
171 		0, 0, 0
172 	}
173 };
174 
175 const SdXMLFixedDataStyle aSdXML_DateStyle_4 =
176 {
177 	"D6", sal_False, sal_True,
178 	{
179 		DATA_STYLE_NUMBER_DAY,
180 		DATA_STYLE_NUMBER_TEXT_POINTSPACE,
181 		DATA_STYLE_NUMBER_MONTH_LONG_TEXT,
182 		DATA_STYLE_NUMBER_TEXT_SPACE,
183 		DATA_STYLE_NUMBER_YEAR_LONG,
184 		0, 0, 0
185 	}
186 };
187 
188 const SdXMLFixedDataStyle aSdXML_DateStyle_5 =
189 {
190 	"D7", sal_False, sal_True,
191 	{
192 		DATA_STYLE_NUMBER_DAYOFWEEK,
193 		DATA_STYLE_NUMBER_TEXT_COMMASPACE,
194 		DATA_STYLE_NUMBER_DAY,
195 		DATA_STYLE_NUMBER_TEXT_POINTSPACE,
196 		DATA_STYLE_NUMBER_MONTH_LONG_TEXT,
197 		DATA_STYLE_NUMBER_TEXT_SPACE,
198 		DATA_STYLE_NUMBER_YEAR_LONG,
199 		0
200 	}
201 };
202 
203 const SdXMLFixedDataStyle aSdXML_DateStyle_6 =
204 {
205 	"D8", sal_False, sal_True,
206 	{
207 		DATA_STYLE_NUMBER_DAYOFWEEK_LONG,
208 		DATA_STYLE_NUMBER_TEXT_COMMASPACE,
209 		DATA_STYLE_NUMBER_DAY,
210 		DATA_STYLE_NUMBER_TEXT_POINTSPACE,
211 		DATA_STYLE_NUMBER_MONTH_LONG_TEXT,
212 		DATA_STYLE_NUMBER_TEXT_SPACE,
213 		DATA_STYLE_NUMBER_YEAR_LONG,
214 		0
215 	}
216 };
217 
218 const SdXMLFixedDataStyle aSdXML_TimeStyle_1 =
219 {	"T1", sal_True, sal_False,
220 	{
221 		DATA_STYLE_NUMBER_HOURS,
222 		DATA_STYLE_NUMBER_TEXT_COLON,
223 		DATA_STYLE_NUMBER_MINUTES,
224 		DATA_STYLE_NUMBER_TEXT_COLON,
225 		DATA_STYLE_NUMBER_SECONDS,
226 		DATA_STYLE_NUMBER_AMPM,
227 		0, 0,
228 	}
229 };
230 
231 const SdXMLFixedDataStyle aSdXML_TimeStyle_2 =
232 {	"T2", sal_False, sal_False,
233 	{
234 		DATA_STYLE_NUMBER_HOURS,
235 		DATA_STYLE_NUMBER_TEXT_COLON,
236 		DATA_STYLE_NUMBER_MINUTES,
237 		0, 0, 0, 0, 0
238 	}
239 };
240 
241 const SdXMLFixedDataStyle aSdXML_TimeStyle_3 =
242 {	"T3", sal_False, sal_False,
243 	{
244 		DATA_STYLE_NUMBER_HOURS,
245 		DATA_STYLE_NUMBER_TEXT_COLON,
246 		DATA_STYLE_NUMBER_MINUTES,
247 		DATA_STYLE_NUMBER_TEXT_COLON,
248 		DATA_STYLE_NUMBER_SECONDS,
249 		0, 0, 0
250 	}
251 };
252 
253 const SdXMLFixedDataStyle aSdXML_TimeStyle_4 =
254 {	"T4", sal_False, sal_False,
255 	{
256 		DATA_STYLE_NUMBER_HOURS,
257 		DATA_STYLE_NUMBER_TEXT_COLON,
258 		DATA_STYLE_NUMBER_MINUTES,
259 		DATA_STYLE_NUMBER_TEXT_COLON,
260 		DATA_STYLE_NUMBER_SECONDS_02,
261 		0, 0, 0
262 	}
263 };
264 
265 const SdXMLFixedDataStyle aSdXML_TimeStyle_5 =
266 {	"T5", sal_False, sal_False,
267 	{
268 		DATA_STYLE_NUMBER_HOURS,
269 		DATA_STYLE_NUMBER_TEXT_COLON,
270 		DATA_STYLE_NUMBER_MINUTES,
271 		DATA_STYLE_NUMBER_AMPM,
272 		0, 0, 0, 0
273 	}
274 };
275 
276 const SdXMLFixedDataStyle aSdXML_TimeStyle_6 =
277 {	"T6", sal_False, sal_False,
278 	{
279 		DATA_STYLE_NUMBER_HOURS,
280 		DATA_STYLE_NUMBER_TEXT_COLON,
281 		DATA_STYLE_NUMBER_MINUTES,
282 		DATA_STYLE_NUMBER_TEXT_COLON,
283 		DATA_STYLE_NUMBER_SECONDS,
284 		DATA_STYLE_NUMBER_AMPM,
285 		0, 0
286 	}
287 };
288 
289 const SdXMLFixedDataStyle aSdXML_TimeStyle_7 =
290 {	"T7", sal_False, sal_False,
291 	{
292 		DATA_STYLE_NUMBER_HOURS,
293 		DATA_STYLE_NUMBER_TEXT_COLON,
294 		DATA_STYLE_NUMBER_MINUTES,
295 		DATA_STYLE_NUMBER_TEXT_COLON,
296 		DATA_STYLE_NUMBER_SECONDS_02,
297 		DATA_STYLE_NUMBER_AMPM,
298 		0, 0
299 	}
300 };
301 
302 const SdXMLFixedDataStyle* aSdXMLFixedDateFormats[SdXMLDateFormatCount] =
303 {
304 	&aSdXML_Standard_Short,
305 	&aSdXML_Standard_Long,
306 	&aSdXML_DateStyle_1,
307 	&aSdXML_DateStyle_2,
308 	&aSdXML_DateStyle_3,
309 	&aSdXML_DateStyle_4,
310 	&aSdXML_DateStyle_5,
311 	&aSdXML_DateStyle_6,
312 };
313 
314 const SdXMLFixedDataStyle* aSdXMLFixedTimeFormats[SdXMLTimeFormatCount] =
315 {
316 	&aSdXML_TimeStyle_1,
317 	&aSdXML_TimeStyle_2,
318 	&aSdXML_TimeStyle_3,
319 	&aSdXML_TimeStyle_4,
320 	&aSdXML_TimeStyle_5,
321 	&aSdXML_TimeStyle_6,
322 	&aSdXML_TimeStyle_7
323 };
324 
325 
326 ///////////////////////////////////////////////////////////////////////
327 // export
328 
329 #ifndef SVX_LIGHT
330 
331 static void SdXMLExportDataStyleNumber( SdXMLExport& rExport, SdXMLDataStyleNumber& rElement )
332 {
333 	if( rElement.mbDecimal02 )
334 	{
335 		rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_DECIMAL_PLACES, XML_2 );
336 	}
337 
338 	if( rElement.mbLong )
339 	{
340 		rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_STYLE, XML_LONG );
341 	}
342 
343 	if( rElement.mbTextual )
344 	{
345 		rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TEXTUAL, XML_TRUE );
346 	}
347 
348 	SvXMLElementExport aNumberStyle( rExport, XML_NAMESPACE_NUMBER, rElement.meNumberStyle, sal_True, sal_False );
349 	if( rElement.mpText )
350 	{
351 		OUString sAttrValue( OUString::createFromAscii( rElement.mpText ) );
352 		rExport.GetDocHandler()->characters( sAttrValue );
353 	}
354 }
355 
356 static void SdXMLExportStyle( SdXMLExport& rExport, const SdXMLFixedDataStyle* pStyle, const SdXMLFixedDataStyle* pStyle2 = NULL )
357 {
358 	OUString sAttrValue;
359 
360 	// name
361 	sAttrValue = OUString::createFromAscii( pStyle->mpName );
362 	if( pStyle2 )
363 		sAttrValue += OUString::createFromAscii( pStyle2->mpName );
364 
365 	rExport.AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, sAttrValue );
366 
367 	if( pStyle->mbAutomatic )
368 	{
369 		rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_AUTOMATIC_ORDER, XML_TRUE );
370 	}
371 
372 	SvXMLElementExport aElement( rExport, XML_NAMESPACE_NUMBER, pStyle->mbDateStyle ? XML_DATE_STYLE : XML_TIME_STYLE, sal_True, sal_True );
373 
374 	do
375 	{
376 
377 		const sal_uInt8* pElements = (const sal_uInt8*)&pStyle->mpFormat[0];
378 
379 		while( *pElements )
380 		{
381 			SdXMLDataStyleNumber& rElement = aSdXMLDataStyleNumbers[ (*pElements++) - 1 ];
382 			SdXMLExportDataStyleNumber( rExport, rElement );
383 		}
384 
385 		if( pStyle2 )
386 		{
387 			SdXMLDataStyleNumber& rElement = aSdXMLDataStyleNumbers[ DATA_STYLE_NUMBER_TEXT_SPACE - 1 ];
388 			SdXMLExportDataStyleNumber( rExport, rElement );
389 		}
390 
391 		pStyle = pStyle2;
392 		pStyle2 = NULL;
393 	}
394 	while( pStyle );
395 }
396 
397 void SdXMLNumberStylesExporter::exportTimeStyle( SdXMLExport& rExport, sal_Int32 nStyle )
398 {
399 	DBG_ASSERT( (nStyle >= 0) && (nStyle < SdXMLTimeFormatCount), "Unknown time style!" );
400 	if( (nStyle >= 0) && (nStyle < SdXMLTimeFormatCount) )
401 		SdXMLExportStyle( rExport, aSdXMLFixedTimeFormats[ nStyle ] );
402 }
403 
404 void SdXMLNumberStylesExporter::exportDateStyle( SdXMLExport& rExport, sal_Int32 nStyle )
405 {
406 	if( nStyle > 0x0f )
407 	{
408 		int nDateStyle = nStyle & 0x0f;
409 		bool bHasDate = nDateStyle != 0;
410 
411 		if( nDateStyle > 1 )
412 			nDateStyle -= 2;
413 
414 		DBG_ASSERT( (nDateStyle >= 0) && (nDateStyle < SdXMLDateFormatCount), "unknown date style!" );
415 
416 		int nTimeStyle = (nStyle >> 4) & 0x0f;
417 		bool bHasTime = nTimeStyle != 0;
418 
419 		if( nTimeStyle > 1 )
420 			nTimeStyle -= 2;
421 
422 		DBG_ASSERT( (nTimeStyle >= 0) && (nTimeStyle < SdXMLTimeFormatCount), "Unknown time style!" );
423 
424 		if( (nDateStyle >= 0) && (nDateStyle < SdXMLDateFormatCount) && (nTimeStyle >= 0) && (nTimeStyle < SdXMLTimeFormatCount) )
425 		{
426 			if( bHasDate )
427 			{
428 				if( bHasTime )
429 				{
430 					SdXMLExportStyle( rExport, aSdXMLFixedDateFormats[ nDateStyle ], aSdXMLFixedTimeFormats[ nTimeStyle ] );
431 				}
432 				else
433 				{
434 					SdXMLExportStyle( rExport, aSdXMLFixedDateFormats[ nDateStyle ] );
435 				}
436 			}
437 			else if( bHasTime )
438 			{
439 				SdXMLExportStyle( rExport, aSdXMLFixedTimeFormats[ nTimeStyle ] );
440 			}
441 		}
442 	}
443 	else
444 	{
445 		DBG_ASSERT( (nStyle >= 0) && (nStyle < SdXMLDateFormatCount), "unknown date style!" );
446 		if( (nStyle >= 0) && (nStyle < SdXMLDateFormatCount) )
447 			SdXMLExportStyle( rExport, aSdXMLFixedDateFormats[ nStyle ] );
448 	}
449 }
450 
451 OUString SdXMLNumberStylesExporter::getTimeStyleName(const sal_Int32 nTimeFormat )
452 {
453 	sal_Int32 nFormat = nTimeFormat;
454 	if( nFormat > 1 )
455 		nFormat -= 2;
456 
457 	if( (nFormat >= 0) && (nFormat < SdXMLTimeFormatCount) )
458 	{
459 		return OUString::createFromAscii(aSdXMLFixedTimeFormats[nFormat]->mpName );
460 	}
461 	else
462 	{
463 		return OUString();
464 	}
465 }
466 
467 OUString SdXMLNumberStylesExporter::getDateStyleName(const sal_Int32 nDateFormat )
468 {
469 	sal_Int32 nFormat = nDateFormat;
470 
471 	if( nFormat > 0x0f )
472 	{
473 		OUString aStr;
474 		if( nFormat & 0x0f )
475 			aStr = getDateStyleName( nFormat & 0x0f );
476 		aStr += getTimeStyleName( (nFormat >> 4) & 0x0f );
477 		return aStr;
478 	}
479 
480 	if( nFormat > 1 )
481 		nFormat -= 2;
482 
483 	if( (nFormat >= 0) && (nFormat < SdXMLDateFormatCount) )
484 	{
485 		return OUString::createFromAscii(aSdXMLFixedDateFormats[nFormat]->mpName );
486 	}
487 	else
488 	{
489 		return OUString();
490 	}
491 }
492 
493 #endif // #ifndef SVX_LIGHT
494 
495 
496 ///////////////////////////////////////////////////////////////////////
497 // import
498 
499 class SdXMLNumberFormatMemberImportContext : public SvXMLImportContext
500 {
501 private:
502 	SdXMLNumberFormatImportContext* mpParent;
503 
504 	OUString maNumberStyle;
505 	sal_Bool mbLong;
506 	sal_Bool mbTextual;
507 	sal_Bool mbDecimal02;
508 	OUString maText;
509 	SvXMLImportContext* mpSlaveContext;
510 
511 public:
512 	TYPEINFO();
513 
514 	SdXMLNumberFormatMemberImportContext( SvXMLImport& rImport,
515 		sal_uInt16 nPrfx,
516 		const rtl::OUString& rLocalName,
517 		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
518 		SdXMLNumberFormatImportContext* pParent,
519 		SvXMLImportContext* pSlaveContext );
520 	virtual ~SdXMLNumberFormatMemberImportContext();
521 
522 	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
523 								   const ::rtl::OUString& rLocalName,
524 								   const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
525 
526 	virtual void StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
527 
528 	virtual void EndElement();
529 
530 	virtual void Characters( const ::rtl::OUString& rChars );
531 };
532 
533 TYPEINIT1( SdXMLNumberFormatMemberImportContext, SvXMLImportContext );
534 
535 SdXMLNumberFormatMemberImportContext::SdXMLNumberFormatMemberImportContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, SdXMLNumberFormatImportContext* pParent, SvXMLImportContext* pSlaveContext )
536 :	SvXMLImportContext(rImport, nPrfx, rLocalName),
537 	mpParent( pParent ),
538 	maNumberStyle( rLocalName ),
539 	mpSlaveContext( pSlaveContext )
540 {
541 	mbLong = sal_False;
542 	mbTextual = sal_False;
543 	mbDecimal02 = sal_False;
544 
545 	const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
546 	for(sal_Int16 i=0; i < nAttrCount; i++)
547 	{
548 		OUString sAttrName = xAttrList->getNameByIndex( i );
549 		OUString aLocalName;
550 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
551 		OUString sValue = xAttrList->getValueByIndex( i );
552 
553 		if( nPrefix == XML_NAMESPACE_NUMBER )
554 		{
555 			if( IsXMLToken( aLocalName, XML_DECIMAL_PLACES ) )
556 			{
557 				mbDecimal02 =  IsXMLToken( sValue, XML_2 );
558 			}
559 			else if( IsXMLToken( aLocalName, XML_STYLE ) )
560 			{
561 				mbLong = IsXMLToken( sValue, XML_LONG );
562 			}
563 			else if( IsXMLToken( aLocalName, XML_TEXTUAL ) )
564 			{
565 				mbTextual = IsXMLToken( sValue, XML_TRUE );
566 			}
567 		}
568 	}
569 
570 }
571 
572 SdXMLNumberFormatMemberImportContext::~SdXMLNumberFormatMemberImportContext()
573 {
574 }
575 
576 SvXMLImportContext *SdXMLNumberFormatMemberImportContext::CreateChildContext( sal_uInt16 nPrefix,
577 						   const ::rtl::OUString& rLocalName,
578 						   const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
579 {
580 	return mpSlaveContext->CreateChildContext( nPrefix, rLocalName, xAttrList );
581 }
582 
583 void SdXMLNumberFormatMemberImportContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
584 {
585 	mpSlaveContext->StartElement( xAttrList );
586 }
587 
588 void SdXMLNumberFormatMemberImportContext::EndElement()
589 {
590 	mpSlaveContext->EndElement();
591 
592 	if( mpParent )
593 		mpParent->add( maNumberStyle, mbLong, mbTextual, mbDecimal02, maText );
594 }
595 
596 void SdXMLNumberFormatMemberImportContext::Characters( const ::rtl::OUString& rChars )
597 {
598 	mpSlaveContext->Characters( rChars );
599 	maText += rChars;
600 }
601 
602 TYPEINIT1( SdXMLNumberFormatImportContext, SvXMLImportContext );
603 
604 
605 SdXMLNumberFormatImportContext::SdXMLNumberFormatImportContext( SdXMLImport& rImport, sal_uInt16 nPrfx,	const rtl::OUString& rLocalName, SvXMLNumImpData* pNewData, sal_uInt16 nNewType, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, SvXMLStylesContext& rStyles)
606 :	SvXMLNumFormatContext(rImport, nPrfx, rLocalName, pNewData, nNewType, xAttrList, rStyles),
607 	mrImport( rImport ),
608 	mbAutomatic( sal_False ),
609 	mnIndex(0),
610 	mnKey( -1 )
611 {
612 	mbTimeStyle = IsXMLToken( rLocalName, XML_TIME_STYLE );
613 
614 	const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
615 	for(sal_Int16 i=0; i < nAttrCount; i++)
616 	{
617 		OUString sAttrName = xAttrList->getNameByIndex( i );
618 		OUString aLocalName;
619 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
620 		OUString sValue = xAttrList->getValueByIndex( i );
621 
622 		if( nPrefix == XML_NAMESPACE_NUMBER )
623 		{
624 			if( IsXMLToken( aLocalName, XML_AUTOMATIC_ORDER ) )
625 			{
626 				mbAutomatic = IsXMLToken( sValue, XML_TRUE );
627 			}
628 		}
629 	}
630 }
631 
632 SdXMLNumberFormatImportContext::~SdXMLNumberFormatImportContext()
633 {
634 }
635 
636 void SdXMLNumberFormatImportContext::add( OUString& rNumberStyle, sal_Bool bLong, sal_Bool bTextual, sal_Bool	bDecimal02, OUString& rText )
637 {
638 	if( mnIndex == -1 || mnIndex == 16 )
639 	{
640 		mnIndex = -1;
641 		return;
642 	}
643 
644 	const SdXMLDataStyleNumber* pStyleMember = aSdXMLDataStyleNumbers;
645 	for( sal_uInt8 nIndex = 0; pStyleMember->meNumberStyle != XML_TOKEN_INVALID; nIndex++, pStyleMember++ )
646 	{
647 		if( (IsXMLToken(rNumberStyle, pStyleMember->meNumberStyle) &&
648 			(pStyleMember->mbLong == bLong) &&
649 			(pStyleMember->mbTextual == bTextual) &&
650 			(pStyleMember->mbDecimal02 == bDecimal02) &&
651 			( ( (pStyleMember->mpText == NULL) && (rText.getLength() == 0) ) ||
652 			  ( pStyleMember->mpText && (rText.compareToAscii( pStyleMember->mpText )  == 0 )) ) ) )
653 		{
654 			mnElements[mnIndex++] = nIndex + 1;
655 			return;
656 		}
657 	}
658 }
659 
660 bool SdXMLNumberFormatImportContext::compareStyle( const SdXMLFixedDataStyle* pStyle, sal_Int16& nIndex ) const
661 {
662 	if( (pStyle->mbAutomatic != mbAutomatic) && (nIndex == 0))
663 		return sal_False;
664 
665 	sal_Int16 nCompareIndex;
666 	for( nCompareIndex = 0; nCompareIndex < 8; nIndex++, nCompareIndex++ )
667 	{
668 		if( pStyle->mpFormat[nCompareIndex] != mnElements[nIndex] )
669 			return sal_False;
670 	}
671 
672 	return sal_True;
673 }
674 
675 void SdXMLNumberFormatImportContext::EndElement()
676 {
677 	SvXMLNumFormatContext::EndElement();
678 
679 	for( ; mnIndex < 16; mnIndex++ )
680 	{
681 		mnElements[mnIndex] = 0;
682 	}
683 
684 	if( mbTimeStyle )
685 	{
686 		// compare import with all time styles
687 		for( sal_Int16 nFormat = 0; nFormat < SdXMLTimeFormatCount; nFormat++ )
688 		{
689 			sal_Int16 nIndex = 0;
690 			if( compareStyle( aSdXMLFixedTimeFormats[nFormat], nIndex ) )
691 			{
692 				mnKey = nFormat + 2;
693 				break;
694 			}
695 		}
696 	}
697 	else
698 	{
699 		// compare import with all date styles
700 		for( sal_Int16 nFormat = 0; nFormat < SdXMLDateFormatCount; nFormat++ )
701 		{
702 			sal_Int16 nIndex = 0;
703 			if( compareStyle( aSdXMLFixedDateFormats[nFormat], nIndex ) )
704 			{
705 				mnKey = nFormat + 2;
706 				break;
707 			}
708 			else if( mnElements[nIndex] == DATA_STYLE_NUMBER_TEXT_SPACE )
709 			{
710 				// if its a valid date ending with a space, see if a time style follows
711 				for( sal_Int16 nTimeFormat = 0; nTimeFormat < SdXMLTimeFormatCount; nTimeFormat++ )
712 				{
713 					sal_Int16 nIndex2 = nIndex + 1;
714 					if( compareStyle( aSdXMLFixedTimeFormats[nTimeFormat], nIndex2 ) )
715 					{
716 						mnKey = (nFormat + 2) | ((nTimeFormat + 2) << 4);
717 						break;
718 					}
719 				}
720 			}
721 		}
722 
723 		// no date style found? maybe its an extended time style
724 		if( mnKey == -1 )
725 		{
726 			// compare import with all time styles
727 			for( sal_Int16 nFormat = 0; nFormat < SdXMLTimeFormatCount; nFormat++ )
728 			{
729 				sal_Int16 nIndex = 0;
730 				if( compareStyle( aSdXMLFixedTimeFormats[nFormat], nIndex ) )
731 				{
732 					mnKey = (nFormat + 2) << 4;
733 					break;
734 				}
735 			}
736 		}
737 	}
738 }
739 
740 SvXMLImportContext * SdXMLNumberFormatImportContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
741 {
742 	return new SdXMLNumberFormatMemberImportContext( GetImport(), nPrefix, rLocalName, xAttrList, this, SvXMLNumFormatContext::CreateChildContext( nPrefix, rLocalName, xAttrList ) );
743 }
744