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