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 
31 
32 #include <com/sun/star/util/XStringSubstitution.hpp>
33 #include <xmloff/DocumentSettingsContext.hxx>
34 #include <xmloff/xmlimp.hxx>
35 #include <xmloff/xmltoken.hxx>
36 #include "xmloff/xmlnmspe.hxx"
37 #include <xmloff/nmspmap.hxx>
38 #include <xmloff/xmluconv.hxx>
39 #include <tools/debug.hxx>
40 
41 #ifndef __SGI_STL_LIST
42 #include <list>
43 #endif
44 #include <com/sun/star/i18n/XForbiddenCharacters.hpp>
45 #include <com/sun/star/container/XIndexContainer.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/formula/SymbolDescriptor.hpp>
48 #include <comphelper/processfactory.hxx>
49 #include <com/sun/star/util/DateTime.hpp>
50 #include <com/sun/star/document/XViewDataSupplier.hpp>
51 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
52 #include <comphelper/configurationhelper.hxx>
53 #include <rtl/ustrbuf.hxx>
54 #include <xmlenums.hxx>
55 
56 using namespace com::sun::star;
57 using namespace ::xmloff::token;
58 
59 #define C2U(cChar) ::rtl::OUString::createFromAscii(cChar)
60 
61 //------------------------------------------------------------------
62 
63 class XMLMyList
64 {
65 	std::list<beans::PropertyValue>	aProps;
66 	sal_uInt32						nCount;
67 
68 	// #110680#
69 	::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxServiceFactory;
70 
71 public:
72 	// #110680#
73 	XMLMyList(const uno::Reference<lang::XMultiServiceFactory>& xServiceFactory);
74 	~XMLMyList();
75 
76 	void push_back(beans::PropertyValue& aProp) { aProps.push_back(aProp); nCount++; }
77 	uno::Sequence<beans::PropertyValue> GetSequence();
78 	uno::Reference<container::XNameContainer> GetNameContainer();
79 	uno::Reference<container::XIndexContainer> GetIndexContainer();
80 };
81 
82 // #110680#
83 XMLMyList::XMLMyList(const uno::Reference<lang::XMultiServiceFactory>& xServiceFactory)
84 :	nCount(0),
85 	mxServiceFactory(xServiceFactory)
86 {
87 	DBG_ASSERT( mxServiceFactory.is(), "got no service manager" );
88 }
89 
90 // #110680#
91 XMLMyList::~XMLMyList()
92 {
93 }
94 
95 uno::Sequence<beans::PropertyValue> XMLMyList::GetSequence()
96 {
97 	uno::Sequence<beans::PropertyValue> aSeq;
98 	if(nCount)
99 	{
100 		DBG_ASSERT(nCount == aProps.size(), "wrong count of PropertyValue");
101 		aSeq.realloc(nCount);
102 		beans::PropertyValue* pProps = aSeq.getArray();
103 		std::list<beans::PropertyValue>::iterator aItr = aProps.begin();
104 		while (aItr != aProps.end())
105 		{
106 			*pProps = *aItr;
107 			pProps++;
108 			aItr++;
109 		}
110 	}
111 	return aSeq;
112 }
113 
114 uno::Reference<container::XNameContainer> XMLMyList::GetNameContainer()
115 {
116 	uno::Reference<container::XNameContainer> xNameContainer;
117 
118 	// #110680#
119 	// uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory();
120 	// DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
121 
122 	if( mxServiceFactory.is() )
123 	{
124 		rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.NamedPropertyValues"));
125 		xNameContainer = uno::Reference<container::XNameContainer>(mxServiceFactory->createInstance(sName), uno::UNO_QUERY);
126 		if (xNameContainer.is())
127 		{
128 			std::list<beans::PropertyValue>::iterator aItr = aProps.begin();
129 			while (aItr != aProps.end())
130 			{
131 				xNameContainer->insertByName(aItr->Name, aItr->Value);
132 				aItr++;
133 			}
134 		}
135 	}
136 	return xNameContainer;
137 }
138 
139 uno::Reference<container::XIndexContainer> XMLMyList::GetIndexContainer()
140 {
141 	uno::Reference<container::XIndexContainer> xIndexContainer;
142 	// #110680#
143 	// uno::Reference<lang::XMultiServiceFactory> xServiceFactory = comphelper::getProcessServiceFactory();
144 	// DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
145 
146 	if( mxServiceFactory.is() )
147 	{
148 		rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.IndexedPropertyValues"));
149 		xIndexContainer = uno::Reference<container::XIndexContainer>(mxServiceFactory->createInstance(sName), uno::UNO_QUERY);
150 		if (xIndexContainer.is())
151 		{
152 			std::list<beans::PropertyValue>::iterator aItr = aProps.begin();
153 			sal_uInt32 i(0);
154 			while (aItr != aProps.end())
155 			{
156 				xIndexContainer->insertByIndex(i, aItr->Value);
157 				aItr++;
158 				i++;
159 			}
160 		}
161 	}
162 	return xIndexContainer;
163 }
164 
165 //=============================================================================
166 
167 class XMLConfigBaseContext : public SvXMLImportContext
168 {
169 protected:
170 	XMLMyList					maProps;
171 	beans::PropertyValue		maProp;
172 	com::sun::star::uno::Any&	mrAny;
173 	XMLConfigBaseContext*		mpBaseContext;
174 public:
175 	XMLConfigBaseContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
176 									com::sun::star::uno::Any& rAny,
177 									XMLConfigBaseContext* pBaseContext);
178 	virtual ~XMLConfigBaseContext();
179 
180 	void AddPropertyValue() { maProps.push_back(maProp); }
181 };
182 
183 //=============================================================================
184 
185 class XMLConfigItemContext : public SvXMLImportContext
186 {
187 	rtl::OUString				msType;
188 	rtl::OUString				msValue;
189 	uno::Sequence<sal_Int8>		maDecoded;
190 	com::sun::star::uno::Any&	mrAny;
191     const rtl::OUString         mrItemName;
192 	XMLConfigBaseContext*		mpBaseContext;
193 
194 public:
195 	XMLConfigItemContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
196 									const ::com::sun::star::uno::Reference<
197 									::com::sun::star::xml::sax::XAttributeList>& xAttrList,
198 									com::sun::star::uno::Any& rAny,
199                                     const rtl::OUString& rItemName,
200 									XMLConfigBaseContext* pBaseContext);
201 	virtual ~XMLConfigItemContext();
202 
203 	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
204 													const rtl::OUString& rLocalName,
205 													const ::com::sun::star::uno::Reference<
206 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList );
207 	virtual void Characters( const ::rtl::OUString& rChars );
208 
209 	virtual void EndElement();
210 
211     virtual void ManipulateConfigItem();
212 };
213 
214 //=============================================================================
215 
216 class XMLConfigItemSetContext : public XMLConfigBaseContext
217 {
218 public:
219 	XMLConfigItemSetContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
220 									const ::com::sun::star::uno::Reference<
221 									::com::sun::star::xml::sax::XAttributeList>& xAttrList,
222 									com::sun::star::uno::Any& rAny,
223 									XMLConfigBaseContext* pBaseContext);
224 	virtual ~XMLConfigItemSetContext();
225 
226 	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
227 													const rtl::OUString& rLocalName,
228 													const ::com::sun::star::uno::Reference<
229 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList );
230 
231 	virtual void EndElement();
232 };
233 
234 //=============================================================================
235 
236 class XMLConfigItemMapNamedContext : public XMLConfigBaseContext
237 {
238 public:
239 	XMLConfigItemMapNamedContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
240 									const ::com::sun::star::uno::Reference<
241 									::com::sun::star::xml::sax::XAttributeList>& xAttrList,
242 									com::sun::star::uno::Any& rAny,
243 									XMLConfigBaseContext* pBaseContext);
244 	virtual ~XMLConfigItemMapNamedContext();
245 
246 	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
247 													const rtl::OUString& rLocalName,
248 													const ::com::sun::star::uno::Reference<
249 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList );
250 
251 	virtual void EndElement();
252 };
253 
254 //=============================================================================
255 
256 class XMLConfigItemMapIndexedContext : public XMLConfigBaseContext
257 {
258 private:
259 	rtl::OUString maConfigItemName;
260 
261 public:
262 	XMLConfigItemMapIndexedContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
263 									const rtl::OUString& rLName,
264 									const ::com::sun::star::uno::Reference<
265 									::com::sun::star::xml::sax::XAttributeList>& xAttrList,
266 									com::sun::star::uno::Any& rAny,
267 									const rtl::OUString& rConfigItemName,
268 									XMLConfigBaseContext* pBaseContext);
269 	virtual ~XMLConfigItemMapIndexedContext();
270 
271 	virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
272 													const rtl::OUString& rLocalName,
273 													const ::com::sun::star::uno::Reference<
274 										::com::sun::star::xml::sax::XAttributeList>& xAttrList );
275 
276 	virtual void EndElement();
277 };
278 
279 //=============================================================================
280 
281 SvXMLImportContext *CreateSettingsContext(SvXMLImport& rImport, sal_uInt16 p_nPrefix,
282 						const rtl::OUString& rLocalName,
283 						const uno::Reference<xml::sax::XAttributeList>& xAttrList,
284 						beans::PropertyValue& rProp, XMLConfigBaseContext* pBaseContext)
285 {
286 	SvXMLImportContext *pContext = 0;
287 
288 	rProp.Name = rtl::OUString();
289 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
290 	for( sal_Int16 i=0; i < nAttrCount; i++ )
291 	{
292 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
293 		rtl::OUString aLocalName;
294 		sal_uInt16 nPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
295 											sAttrName, &aLocalName );
296 		rtl::OUString sValue = xAttrList->getValueByIndex( i );
297 
298 		if (nPrefix == XML_NAMESPACE_CONFIG)
299 		{
300 			if (IsXMLToken(aLocalName, XML_NAME))
301 				rProp.Name = sValue;
302 		}
303 	}
304 
305 	if (p_nPrefix == XML_NAMESPACE_CONFIG)
306 	{
307 		if (IsXMLToken(rLocalName, XML_CONFIG_ITEM))
308 			pContext = new XMLConfigItemContext(rImport, p_nPrefix, rLocalName, xAttrList, rProp.Value, rProp.Name, pBaseContext);
309 		else if((IsXMLToken(rLocalName, XML_CONFIG_ITEM_SET)) ||
310 				(IsXMLToken(rLocalName, XML_CONFIG_ITEM_MAP_ENTRY)) )
311 			pContext = new XMLConfigItemSetContext(rImport, p_nPrefix, rLocalName, xAttrList, rProp.Value, pBaseContext);
312 		else if(IsXMLToken(rLocalName, XML_CONFIG_ITEM_MAP_NAMED))
313 			pContext = new XMLConfigItemMapNamedContext(rImport, p_nPrefix, rLocalName, xAttrList, rProp.Value, pBaseContext);
314 		else if(IsXMLToken(rLocalName, XML_CONFIG_ITEM_MAP_INDEXED))
315 			pContext = new XMLConfigItemMapIndexedContext(rImport, p_nPrefix, rLocalName, xAttrList, rProp.Value, rProp.Name, pBaseContext);
316 	}
317 
318 	if( !pContext )
319 		pContext = new SvXMLImportContext( rImport, p_nPrefix, rLocalName );
320 
321 	return pContext;
322 }
323 
324 //=============================================================================
325 namespace
326 {
327     struct SettingsGroup
328     {
329         ::rtl::OUString sGroupName;
330         uno::Any        aSettings;
331 
332         SettingsGroup()
333             :sGroupName()
334             ,aSettings()
335         {
336         }
337 
338         SettingsGroup( const ::rtl::OUString& _rGroupName, const uno::Any& _rSettings )
339             :sGroupName( _rGroupName )
340             ,aSettings( _rSettings )
341         {
342         }
343     };
344 }
345 
346 struct XMLDocumentSettingsContext_Data
347 {
348 	com::sun::star::uno::Any	    aViewProps;
349 	com::sun::star::uno::Any	    aConfigProps;
350     ::std::list< SettingsGroup >    aDocSpecificSettings;
351 };
352 
353 //=============================================================================
354 
355 XMLDocumentSettingsContext::XMLDocumentSettingsContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
356 					const uno::Reference<xml::sax::XAttributeList>& )
357 	: SvXMLImportContext( rImport, nPrfx, rLName )
358     , m_pData( new XMLDocumentSettingsContext_Data )
359 {
360 	// here are no attributes
361 }
362 
363 XMLDocumentSettingsContext::~XMLDocumentSettingsContext()
364 {
365 }
366 
367 SvXMLImportContext *XMLDocumentSettingsContext::CreateChildContext( sal_uInt16 p_nPrefix,
368 									 const rtl::OUString& rLocalName,
369 									 const ::com::sun::star::uno::Reference<
370 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList )
371 {
372 	SvXMLImportContext *pContext = 0;
373 	rtl::OUString sName;
374 
375 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
376 	for( sal_Int16 i=0; i < nAttrCount; i++ )
377 	{
378 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
379 		rtl::OUString aLocalName;
380 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(
381 											sAttrName, &aLocalName );
382 		rtl::OUString sValue = xAttrList->getValueByIndex( i );
383 
384 		if (nPrefix == XML_NAMESPACE_CONFIG)
385 		{
386 			if (IsXMLToken(aLocalName, XML_NAME))
387 				sName = sValue;
388 		}
389 	}
390 
391 	if (p_nPrefix == XML_NAMESPACE_CONFIG)
392 	{
393 		if (IsXMLToken(rLocalName, XML_CONFIG_ITEM_SET))
394 		{
395 			::rtl::OUString aLocalConfigName;
396 			sal_uInt16 nConfigPrefix =
397 				GetImport().GetNamespaceMap().GetKeyByAttrName(
398 											sName, &aLocalConfigName );
399 
400 			if( XML_NAMESPACE_OOO == nConfigPrefix )
401 			{
402 				if (IsXMLToken(aLocalConfigName, XML_VIEW_SETTINGS))
403 					pContext = new XMLConfigItemSetContext(GetImport(),
404 										p_nPrefix, rLocalName, xAttrList,
405 										m_pData->aViewProps, NULL);
406 				else if (IsXMLToken(aLocalConfigName,
407 												XML_CONFIGURATION_SETTINGS))
408 					pContext = new XMLConfigItemSetContext(GetImport(),
409 										p_nPrefix, rLocalName, xAttrList,
410 										m_pData->aConfigProps, NULL);
411                 else
412                 {
413                     m_pData->aDocSpecificSettings.push_back( SettingsGroup( aLocalConfigName, uno::Any() ) );
414 
415                     ::std::list< SettingsGroup >::reverse_iterator settingsPos =
416                         m_pData->aDocSpecificSettings.rbegin();
417 
418                     pContext = new XMLConfigItemSetContext(GetImport(),
419 										p_nPrefix, rLocalName, xAttrList,
420 										settingsPos->aSettings, NULL);
421                 }
422 			}
423 		}
424 	}
425 
426 	if( !pContext )
427 		pContext = new SvXMLImportContext( GetImport(), p_nPrefix, rLocalName );
428 
429 	return pContext;
430 }
431 
432 void XMLDocumentSettingsContext::EndElement()
433 {
434 	uno::Sequence<beans::PropertyValue> aSeqViewProps;
435 	if (m_pData->aViewProps >>= aSeqViewProps)
436 	{
437 		GetImport().SetViewSettings(aSeqViewProps);
438 		sal_Int32 i(aSeqViewProps.getLength() - 1);
439 		sal_Bool bFound(sal_False);
440 		while((i >= 0) && !bFound)
441 		{
442 			if (aSeqViewProps[i].Name.compareToAscii("Views") == 0)
443 			{
444 				bFound = sal_True;
445 				uno::Reference<container::XIndexAccess> xIndexAccess;
446 				if (aSeqViewProps[i].Value >>= xIndexAccess)
447 				{
448 					uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetImport().GetModel(), uno::UNO_QUERY);
449 					if (xViewDataSupplier.is())
450 						xViewDataSupplier->setViewData(xIndexAccess);
451 				}
452 			}
453 			else
454 				i--;
455 		}
456 	}
457 
458     sal_Bool bLoadDocPrinter( sal_True );
459     ::comphelper::ConfigurationHelper::readDirectKey(
460         ::comphelper::getProcessServiceFactory(),
461         C2U("org.openoffice.Office.Common/"), C2U("Save/Document"), C2U("LoadPrinter"),
462         ::comphelper::ConfigurationHelper::E_READONLY ) >>= bLoadDocPrinter;
463     uno::Sequence<beans::PropertyValue> aSeqConfigProps;
464     if ( m_pData->aConfigProps >>= aSeqConfigProps )
465     {
466         if ( !bLoadDocPrinter )
467         {
468             sal_Int32 i = aSeqConfigProps.getLength() - 1;
469             int nFound = 0;
470 
471             while ( ( i >= 0 ) && nFound < 2 )
472             {
473                 rtl::OUString sProp( aSeqConfigProps[i].Name );
474 
475                 if ( sProp.compareToAscii("PrinterName") == 0 )
476                 {
477                     rtl::OUString sEmpty;
478                     aSeqConfigProps[i].Value = uno::makeAny( sEmpty );
479                     nFound++;
480                 }
481                 else if ( sProp.compareToAscii("PrinterSetup") == 0 )
482                 {
483                     uno::Sequence< sal_Int8 > aEmpty;
484                     aSeqConfigProps[i].Value = uno::makeAny( aEmpty );
485                     nFound++;
486                 }
487 
488                 i--;
489             }
490         }
491 
492         GetImport().SetConfigurationSettings( aSeqConfigProps );
493     }
494 
495     for (   ::std::list< SettingsGroup >::const_iterator settings = m_pData->aDocSpecificSettings.begin();
496             settings != m_pData->aDocSpecificSettings.end();
497             ++settings
498         )
499     {
500         uno::Sequence< beans::PropertyValue > aDocSettings;
501         OSL_VERIFY( settings->aSettings >>= aDocSettings );
502         GetImport().SetDocumentSpecificSettings( settings->sGroupName, aDocSettings );
503     }
504 }
505 
506 //=============================================================================
507 
508 XMLConfigBaseContext::XMLConfigBaseContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
509 		const rtl::OUString& rLName, com::sun::star::uno::Any& rTempAny,
510 		XMLConfigBaseContext* pTempBaseContext)
511 	: SvXMLImportContext( rImport, nPrfx, rLName ),
512 	// #110680#
513 	maProps(rImport.getServiceFactory()),
514 	maProp(),
515 	mrAny(rTempAny),
516 	mpBaseContext(pTempBaseContext)
517 {
518 }
519 
520 XMLConfigBaseContext::~XMLConfigBaseContext()
521 {
522 }
523 
524 //=============================================================================
525 
526 XMLConfigItemSetContext::XMLConfigItemSetContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
527 									const rtl::OUString& rLName,
528 									const ::com::sun::star::uno::Reference<
529 									::com::sun::star::xml::sax::XAttributeList>&,
530 									com::sun::star::uno::Any& rAny,
531 									XMLConfigBaseContext* pBaseContext)
532 	: XMLConfigBaseContext( rImport, nPrfx, rLName, rAny, pBaseContext )
533 {
534 	// here are no attributes
535 }
536 
537 XMLConfigItemSetContext::~XMLConfigItemSetContext()
538 {
539 }
540 
541 SvXMLImportContext *XMLConfigItemSetContext::CreateChildContext( sal_uInt16 nPrefix,
542 									 const rtl::OUString& rLocalName,
543 									 const ::com::sun::star::uno::Reference<
544 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList )
545 {
546 	return CreateSettingsContext(GetImport(), nPrefix, rLocalName, xAttrList, maProp, this);
547 }
548 
549 void XMLConfigItemSetContext::EndElement()
550 {
551 	mrAny <<= maProps.GetSequence();
552 	if (mpBaseContext)
553 		mpBaseContext->AddPropertyValue();
554 }
555 
556 //=============================================================================
557 
558 XMLConfigItemContext::XMLConfigItemContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
559 									const ::com::sun::star::uno::Reference<
560 									::com::sun::star::xml::sax::XAttributeList>& xAttrList,
561 									com::sun::star::uno::Any& rTempAny,
562                                     const rtl::OUString& rTempItemName,
563 									XMLConfigBaseContext* pTempBaseContext)
564 	: SvXMLImportContext(rImport, nPrfx, rLName),
565 	mrAny(rTempAny),
566     mrItemName(rTempItemName),
567 	mpBaseContext(pTempBaseContext)
568 {
569 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
570 	for( sal_Int16 i=0; i < nAttrCount; i++ )
571 	{
572 		rtl::OUString sAttrName = xAttrList->getNameByIndex( i );
573 		rtl::OUString aLocalName;
574 		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(
575 											sAttrName, &aLocalName );
576 		rtl::OUString sValue = xAttrList->getValueByIndex( i );
577 
578 		if (nPrefix == XML_NAMESPACE_CONFIG)
579 		{
580 			if (IsXMLToken(aLocalName, XML_TYPE))
581 				msType = sValue;
582 		}
583 	}
584 }
585 
586 XMLConfigItemContext::~XMLConfigItemContext()
587 {
588 }
589 
590 SvXMLImportContext *XMLConfigItemContext::CreateChildContext( sal_uInt16 nPrefix,
591 													const rtl::OUString& rLocalName,
592 													const ::com::sun::star::uno::Reference<
593 									  	::com::sun::star::xml::sax::XAttributeList>& )
594 {
595 	SvXMLImportContext* pContext = new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
596 	return pContext;
597 }
598 
599 void XMLConfigItemContext::Characters( const ::rtl::OUString& rChars )
600 {
601 	if (IsXMLToken(msType, XML_BASE64BINARY))
602 	{
603 		rtl::OUString sTrimmedChars( rChars.trim() );
604 		if( sTrimmedChars.getLength() )
605 		{
606 			rtl::OUString sChars;
607 			if( msValue )
608 			{
609 				sChars = msValue;
610 				sChars += sTrimmedChars;
611 				msValue = rtl::OUString();
612 			}
613 			else
614 			{
615 				sChars = sTrimmedChars;
616 			}
617 			uno::Sequence<sal_Int8> aBuffer((sChars.getLength() / 4) * 3 );
618 			sal_Int32 nCharsDecoded =
619 				GetImport().GetMM100UnitConverter().
620 					decodeBase64SomeChars( aBuffer, sChars );
621 			sal_uInt32 nStartPos(maDecoded.getLength());
622 			sal_uInt32 nCount(aBuffer.getLength());
623 			maDecoded.realloc(nStartPos + nCount);
624 			sal_Int8* pDecoded = maDecoded.getArray();
625 			sal_Int8* pBuffer = aBuffer.getArray();
626 			for (sal_uInt32 i = 0; i < nCount; i++, pBuffer++)
627 				pDecoded[nStartPos + i] = *pBuffer;
628 			if( nCharsDecoded != sChars.getLength() )
629 				msValue = sChars.copy( nCharsDecoded );
630 		}
631 	}
632 	else
633 		msValue += rChars;
634 }
635 
636 
637 void XMLConfigItemContext::EndElement()
638 {
639 	if (mpBaseContext)
640 	{
641 		if (IsXMLToken(msType, XML_BOOLEAN))
642 		{
643 			sal_Bool bValue(sal_False);
644 			if (IsXMLToken(msValue, XML_TRUE))
645 				bValue = sal_True;
646 			mrAny <<= bValue;
647 		}
648 		else if (IsXMLToken(msType, XML_BYTE))
649 		{
650 			sal_Int32 nValue(0);
651 			SvXMLUnitConverter::convertNumber(nValue, msValue);
652 			mrAny <<= static_cast<sal_Int8>(nValue);
653 		}
654 		else if (IsXMLToken(msType, XML_SHORT))
655 		{
656 			sal_Int32 nValue(0);
657 			SvXMLUnitConverter::convertNumber(nValue, msValue);
658 			mrAny <<= static_cast<sal_Int16>(nValue);
659 		}
660 		else if (IsXMLToken(msType, XML_INT))
661 		{
662 			sal_Int32 nValue(0);
663 			SvXMLUnitConverter::convertNumber(nValue, msValue);
664 			mrAny <<= nValue;
665 		}
666 		else if (IsXMLToken(msType, XML_LONG))
667 		{
668 			sal_Int64 nValue(msValue.toInt64());
669 			mrAny <<= nValue;
670 		}
671 		else if (IsXMLToken(msType, XML_DOUBLE))
672 		{
673 			double fValue(0.0);
674 			SvXMLUnitConverter::convertDouble(fValue, msValue);
675 			mrAny <<= fValue;
676 		}
677 		else if (IsXMLToken(msType, XML_STRING))
678 		{
679 			mrAny <<= msValue;
680 		}
681 		else if (IsXMLToken(msType, XML_DATETIME))
682 		{
683 			util::DateTime aDateTime;
684 			SvXMLUnitConverter::convertDateTime(aDateTime, msValue);
685 			mrAny <<= aDateTime;
686 		}
687 		else if (IsXMLToken(msType, XML_BASE64BINARY))
688 		{
689 			mrAny <<= maDecoded;
690 		}
691 		else {
692 			DBG_ERROR("wrong type");
693         }
694 
695         ManipulateConfigItem();
696 
697 		mpBaseContext->AddPropertyValue();
698 	}
699 	else {
700 		DBG_ERROR("no BaseContext");
701     }
702 }
703 
704 /** There are some instances where there is a mismatch between API and
705  * XML mapping of a setting. In this case, this method allows us to
706  * manipulate the values accordingly. */
707 void XMLConfigItemContext::ManipulateConfigItem()
708 {
709     if( mrItemName.equalsAsciiL(
710             RTL_CONSTASCII_STRINGPARAM( "PrinterIndependentLayout" ) ) )
711     {
712         rtl::OUString sValue;
713         mrAny >>= sValue;
714 
715         sal_Int16 nTmp = document::PrinterIndependentLayout::HIGH_RESOLUTION;
716 
717         if( sValue.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("enabled")) ||
718             sValue.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("low-resolution")) )
719         {
720             nTmp = document::PrinterIndependentLayout::LOW_RESOLUTION;
721         }
722         else if( sValue.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("disabled")) )
723         {
724             nTmp = document::PrinterIndependentLayout::DISABLED;
725         }
726         // else: default to high_resolution
727 
728         mrAny <<= nTmp;
729     }
730 	else if( (mrItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ColorTableURL" ) ) ) ||
731 			 (mrItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LineEndTableURL" ) ) ) ||
732 			 (mrItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HatchTableURL" ) ) ) ||
733 			 (mrItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DashTableURL" ) ) ) ||
734 			 (mrItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GradientTableURL") ) ) ||
735 			 (mrItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "BitmapTableURL" ) ) ) )
736 	{
737 		if( GetImport().getServiceFactory().is() ) try
738 		{
739 			uno::Reference< util::XStringSubstitution > xStringSubsitution(
740 				GetImport().getServiceFactory()->
741 					createInstance(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.PathSubstitution" ) ) ), uno::UNO_QUERY );
742 
743 			if( xStringSubsitution.is() )
744 			{
745 				rtl::OUString aURL;
746 				mrAny >>= aURL;
747 				aURL = xStringSubsitution->substituteVariables( aURL, sal_False );
748 				mrAny <<= aURL;
749 			}
750 		}
751 		catch( uno::Exception& )
752 		{
753 		}
754 	}
755 }
756 
757 
758 //=============================================================================
759 
760 XMLConfigItemMapNamedContext::XMLConfigItemMapNamedContext(SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLName,
761 									const ::com::sun::star::uno::Reference<
762 									::com::sun::star::xml::sax::XAttributeList>&,
763 									com::sun::star::uno::Any& rAny,
764 									XMLConfigBaseContext* pBaseContext)
765 	: XMLConfigBaseContext(rImport, nPrfx, rLName, rAny, pBaseContext)
766 {
767 }
768 
769 XMLConfigItemMapNamedContext::~XMLConfigItemMapNamedContext()
770 {
771 }
772 
773 SvXMLImportContext *XMLConfigItemMapNamedContext::CreateChildContext( sal_uInt16 nPrefix,
774 													const rtl::OUString& rLocalName,
775 													const ::com::sun::star::uno::Reference<
776 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList )
777 {
778 	return CreateSettingsContext(GetImport(), nPrefix, rLocalName, xAttrList, maProp, this);
779 }
780 
781 void XMLConfigItemMapNamedContext::EndElement()
782 {
783 	if (mpBaseContext)
784 	{
785 		mrAny <<= maProps.GetNameContainer();
786 		mpBaseContext->AddPropertyValue();
787 	}
788 	else {
789 		DBG_ERROR("no BaseContext");
790     }
791 }
792 
793 //=============================================================================
794 
795 XMLConfigItemMapIndexedContext::XMLConfigItemMapIndexedContext(SvXMLImport& rImport, sal_uInt16 nPrfx,
796 									const rtl::OUString& rLName,
797 									const ::com::sun::star::uno::Reference<
798 									::com::sun::star::xml::sax::XAttributeList>&,
799 									com::sun::star::uno::Any& rAny,
800 									const ::rtl::OUString& rConfigItemName,
801 									XMLConfigBaseContext* pBaseContext)
802 	: XMLConfigBaseContext(rImport, nPrfx, rLName, rAny, pBaseContext),
803 	  maConfigItemName( rConfigItemName )
804 {
805 }
806 
807 XMLConfigItemMapIndexedContext::~XMLConfigItemMapIndexedContext()
808 {
809 }
810 
811 SvXMLImportContext *XMLConfigItemMapIndexedContext::CreateChildContext( sal_uInt16 nPrefix,
812 													const rtl::OUString& rLocalName,
813 													const ::com::sun::star::uno::Reference<
814 										::com::sun::star::xml::sax::XAttributeList>& xAttrList )
815 {
816 	return CreateSettingsContext(GetImport(), nPrefix, rLocalName, xAttrList, maProp, this);
817 }
818 
819 void XMLConfigItemMapIndexedContext::EndElement()
820 {
821 	if (mpBaseContext)
822 	{
823 		if( maConfigItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ForbiddenCharacters" ) ) )
824 		{
825 			uno::Reference< i18n::XForbiddenCharacters > xForbChars;
826 
827 			// get the forbidden characters from the document
828 			uno::Reference< lang::XMultiServiceFactory > xFac( GetImport().GetModel(), uno::UNO_QUERY );
829 			if( xFac.is() )
830 			{
831 				uno::Reference< beans::XPropertySet > xProps( xFac->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.Settings" ) ) ), uno::UNO_QUERY );
832 				if( xProps.is() && xProps->getPropertySetInfo()->hasPropertyByName( maConfigItemName ) )
833 				{
834 					xProps->getPropertyValue( maConfigItemName ) >>= xForbChars;
835 				}
836 			}
837 
838 			if( xForbChars.is() )
839 			{
840 
841 				uno::Reference< container::XIndexAccess > xIndex( maProps.GetIndexContainer(), uno::UNO_QUERY );
842 
843 				const sal_Int32 nCount = xIndex->getCount();
844 				uno::Sequence < beans::PropertyValue > aProps;
845 				for (sal_Int32 i = 0; i < nCount; i++)
846 				{
847 					if ((xIndex->getByIndex( i ) >>= aProps) && (aProps.getLength() == XML_FORBIDDEN_CHARACTER_MAX ) )
848 					{
849 						beans::PropertyValue *pForChar = aProps.getArray();
850 						i18n::ForbiddenCharacters aForbid;
851 						lang::Locale aLocale;
852 						const rtl::OUString sLanguage  ( RTL_CONSTASCII_USTRINGPARAM ( "Language" ) );
853 						const rtl::OUString sCountry   ( RTL_CONSTASCII_USTRINGPARAM ( "Country" ) );
854 						const rtl::OUString sVariant   ( RTL_CONSTASCII_USTRINGPARAM ( "Variant" ) );
855 						const rtl::OUString sBeginLine ( RTL_CONSTASCII_USTRINGPARAM ( "BeginLine" ) );
856 						const rtl::OUString sEndLine   ( RTL_CONSTASCII_USTRINGPARAM ( "EndLine" ) );
857 						sal_Bool bHaveLanguage = sal_False, bHaveCountry = sal_False, bHaveVariant = sal_False,
858 								 bHaveBegin = sal_False, bHaveEnd = sal_False;
859 
860 						for ( sal_Int32 j = 0 ; j < XML_FORBIDDEN_CHARACTER_MAX ; j++ )
861 						{
862 							if (pForChar->Name.equals (sLanguage ) )
863 							{
864 								pForChar->Value >>= aLocale.Language;
865 								bHaveLanguage = sal_True;
866 							}
867 							else if (pForChar->Name.equals (sCountry ) )
868 							{
869 								pForChar->Value >>= aLocale.Country;
870 								bHaveCountry = sal_True;
871 							}
872 							else if (pForChar->Name.equals (sVariant ) )
873 							{
874 								pForChar->Value >>= aLocale.Variant;
875 								bHaveVariant = sal_True;
876 							}
877 							else if (pForChar->Name.equals (sBeginLine ) )
878 							{
879 								pForChar->Value >>= aForbid.beginLine;
880 								bHaveBegin = sal_True;
881 							}
882 							else if (pForChar->Name.equals (sEndLine ) )
883 							{
884 								pForChar->Value >>= aForbid.endLine;
885 								bHaveEnd = sal_True;
886 							}
887 							pForChar++;
888 						}
889 
890 						if ( bHaveLanguage && bHaveCountry && bHaveVariant && bHaveBegin && bHaveEnd )
891 						{
892 							try
893 							{
894 								xForbChars->setForbiddenCharacters( aLocale, aForbid );
895 							}
896 							catch( uno::Exception& )
897 							{
898 								DBG_ERROR( "Exception while importing forbidden characters" );
899 							}
900 						}
901 					}
902 				}
903 			}
904 			else
905 			{
906 				DBG_ERROR( "could not get the XForbiddenCharacters from document!" );
907 				mrAny <<= maProps.GetIndexContainer();
908 			}
909 		}
910 		else if( maConfigItemName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Symbols" ) ) )
911 		{
912 			uno::Reference< container::XIndexAccess > xIndex( maProps.GetIndexContainer(), uno::UNO_QUERY );
913 
914 			const sal_Int32 nCount = xIndex->getCount();
915 			uno::Sequence < beans::PropertyValue > aProps;
916 			uno::Sequence < formula::SymbolDescriptor > aSymbolList ( nCount );
917 
918 			formula::SymbolDescriptor *pDescriptor = aSymbolList.getArray();
919 
920 			const rtl::OUString sName     ( RTL_CONSTASCII_USTRINGPARAM ( "Name" ) );
921 			const rtl::OUString sExportName ( RTL_CONSTASCII_USTRINGPARAM ( "ExportName" ) );
922 			const rtl::OUString sFontName ( RTL_CONSTASCII_USTRINGPARAM ( "FontName" ) );
923 			const rtl::OUString sSymbolSet ( RTL_CONSTASCII_USTRINGPARAM ( "SymbolSet" ) );
924 			const rtl::OUString sCharacter ( RTL_CONSTASCII_USTRINGPARAM ( "Character" ) );
925 			const rtl::OUString sCharSet  ( RTL_CONSTASCII_USTRINGPARAM ( "CharSet" ) );
926 			const rtl::OUString sFamily   ( RTL_CONSTASCII_USTRINGPARAM ( "Family" ) );
927 			const rtl::OUString sPitch    ( RTL_CONSTASCII_USTRINGPARAM ( "Pitch" ) );
928 			const rtl::OUString sWeight   ( RTL_CONSTASCII_USTRINGPARAM ( "Weight" ) );
929 			const rtl::OUString sItalic   ( RTL_CONSTASCII_USTRINGPARAM ( "Italic" ) );
930 			sal_Int16 nNumFullEntries = 0;
931 
932 			for ( sal_Int32 i = 0; i < nCount; i++ )
933 			{
934 				if ((xIndex->getByIndex( i ) >>= aProps) && (aProps.getLength() == XML_SYMBOL_DESCRIPTOR_MAX ) )
935 				{
936 					sal_Bool bHaveName = sal_False, bHaveExportName = sal_False, bHaveCharSet = sal_False,
937 					 		 bHaveFontName = sal_False, bHaveFamily = sal_False, bHavePitch = sal_False,
938 					 		 bHaveWeight = sal_False, bHaveItalic = sal_False, bHaveSymbolSet = sal_False,
939 							 bHaveCharacter = sal_False;
940 					beans::PropertyValue *pSymbol = aProps.getArray();
941 
942 					for ( sal_Int32 j = 0 ; j < XML_SYMBOL_DESCRIPTOR_MAX ; j++ )
943 					{
944 						if (pSymbol->Name.equals ( sName ) )
945 						{
946 							pSymbol->Value >>= pDescriptor[nNumFullEntries].sName;
947 							bHaveName = sal_True;
948 						}
949 						else if (pSymbol->Name.equals (sExportName ) )
950 						{
951 							pSymbol->Value >>= pDescriptor[nNumFullEntries].sExportName;
952 							bHaveExportName = sal_True;
953 						}
954 						else if (pSymbol->Name.equals (sFontName ) )
955 						{
956 							pSymbol->Value >>= pDescriptor[nNumFullEntries].sFontName;
957 							bHaveFontName = sal_True;
958 						}
959 						else if (pSymbol->Name.equals (sCharSet ) )
960 						{
961 							pSymbol->Value >>= pDescriptor[nNumFullEntries].nCharSet;
962 							bHaveCharSet = sal_True;
963 						}
964 						else if (pSymbol->Name.equals (sFamily ) )
965 						{
966 							pSymbol->Value >>= pDescriptor[nNumFullEntries].nFamily;
967 							bHaveFamily = sal_True;
968 						}
969 						else if (pSymbol->Name.equals (sPitch ) )
970 						{
971 							pSymbol->Value >>= pDescriptor[nNumFullEntries].nPitch;
972 							bHavePitch = sal_True;
973 						}
974 						else if (pSymbol->Name.equals (sWeight ) )
975 						{
976 							pSymbol->Value >>= pDescriptor[nNumFullEntries].nWeight;
977 							bHaveWeight = sal_True;
978 						}
979 						else if (pSymbol->Name.equals (sItalic ) )
980 						{
981 							pSymbol->Value >>= pDescriptor[nNumFullEntries].nItalic;
982 							bHaveItalic = sal_True;
983 						}
984 						else if (pSymbol->Name.equals (sSymbolSet ) )
985 						{
986 							pSymbol->Value >>= pDescriptor[nNumFullEntries].sSymbolSet;
987 							bHaveSymbolSet = sal_True;
988 						}
989 						else if (pSymbol->Name.equals (sCharacter ) )
990 						{
991 							pSymbol->Value >>= pDescriptor[nNumFullEntries].nCharacter;
992 							bHaveCharacter = sal_True;
993 						}
994 						pSymbol++;
995 					}
996 					if ( bHaveName && bHaveExportName && bHaveCharSet && bHaveFontName && bHaveCharacter
997 						 && bHaveFamily && bHavePitch && bHaveWeight && bHaveItalic && bHaveSymbolSet)
998 						nNumFullEntries++;
999 				}
1000 			}
1001 			aSymbolList.realloc (nNumFullEntries);
1002 			mrAny <<= aSymbolList;
1003 		}
1004 		else
1005 		{
1006 			mrAny <<= maProps.GetIndexContainer();
1007 		}
1008 		mpBaseContext->AddPropertyValue();
1009 	}
1010 	else {
1011 		DBG_ERROR("no BaseContext");
1012     }
1013 }
1014 
1015