Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/urlobj.hxx>
21 : #include <com/sun/star/document/XGraphicObjectResolver.hpp>
22 : #include <com/sun/star/embed/ElementModes.hpp>
23 : #include <com/sun/star/io/XActiveDataControl.hpp>
24 : #include <com/sun/star/io/XActiveDataSource.hpp>
25 : #include <com/sun/star/xml/sax/Parser.hpp>
26 : #include <com/sun/star/container/XNameContainer.hpp>
27 : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
28 : #include <com/sun/star/uno/Sequence.hxx>
29 : #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
30 : #include <com/sun/star/drawing/LineDash.hpp>
31 : #include <com/sun/star/awt/Gradient.hpp>
32 : #include <com/sun/star/drawing/Hatch.hpp>
33 : #include <com/sun/star/io/XOutputStream.hpp>
34 : #include <com/sun/star/io/XSeekable.hpp>
35 : #include <comphelper/processfactory.hxx>
36 : #include <comphelper/storagehelper.hxx>
37 : #include <unotools/streamwrap.hxx>
38 : #include <rtl/ustrbuf.hxx>
39 : #include <sax/tools/converter.hxx>
40 : #include <sfx2/docfile.hxx>
41 : #include "xmloff/xmlnmspe.hxx"
42 : #include "xmloff/nmspmap.hxx"
43 :
44 : #include "xmloff/xmltoken.hxx"
45 : #include "xmloff/xmlmetae.hxx"
46 : #include "xmloff/DashStyle.hxx"
47 : #include "xmloff/GradientStyle.hxx"
48 : #include "xmloff/HatchStyle.hxx"
49 : #include "xmloff/ImageStyle.hxx"
50 : #include "xmloff/MarkerStyle.hxx"
51 : #include <xmloff/xmlictxt.hxx>
52 : #include "svx/xmlgrhlp.hxx"
53 : #include "xmloff/attrlist.hxx"
54 :
55 : #include "xmlxtimp.hxx"
56 :
57 : #include <cstdio>
58 :
59 : using namespace com::sun::star;
60 : using namespace com::sun::star::container;
61 : using namespace com::sun::star::document;
62 : using namespace com::sun::star::uno;
63 : using namespace com::sun::star::awt;
64 : using namespace com::sun::star::lang;
65 : using namespace com::sun::star::xml::sax;
66 : using namespace ::xmloff::token;
67 : using namespace cppu;
68 :
69 : sal_Char const sXML_np__office[] = "__office";
70 : sal_Char const sXML_np__office_ooo[] = "___office";
71 : sal_Char const sXML_np__draw[] = "__draw";
72 : sal_Char const sXML_np__draw_ooo[] = "___draw";
73 : sal_Char const sXML_np__ooo[] = "__ooo";
74 : sal_Char const sXML_np__xlink[] = "__xlink";
75 :
76 :
77 :
78 : enum SvxXMLTableImportContextEnum { stice_unknown, stice_color, stice_marker, stice_dash, stice_hatch, stice_gradient, stice_bitmap };
79 :
80 :
81 :
82 : class SvxXMLTableImportContext : public SvXMLImportContext
83 : {
84 : public:
85 : SvxXMLTableImportContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const uno::Reference< XAttributeList >& xAttrList, SvxXMLTableImportContextEnum eContext, const uno::Reference< XNameContainer >& xTable,
86 : bool bOOoFormat );
87 : virtual ~SvxXMLTableImportContext();
88 :
89 : virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList ) SAL_OVERRIDE;
90 :
91 : protected:
92 : void importColor( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName );
93 : void importMarker( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName );
94 : void importDash( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName );
95 : void importHatch( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName );
96 : void importGradient( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName );
97 : void importBitmap( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName );
98 :
99 : private:
100 : uno::Reference< XNameContainer > mxTable;
101 : SvxXMLTableImportContextEnum meContext;
102 : bool mbOOoFormat;
103 : };
104 :
105 :
106 :
107 135 : SvxXMLTableImportContext::SvxXMLTableImportContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const uno::Reference< XAttributeList >&, SvxXMLTableImportContextEnum eContext, const uno::Reference< XNameContainer >& xTable, bool bOOoFormat )
108 : : SvXMLImportContext( rImport, nPrfx, rLName ), mxTable( xTable ), meContext( eContext ),
109 135 : mbOOoFormat( bOOoFormat )
110 : {
111 135 : }
112 :
113 270 : SvxXMLTableImportContext::~SvxXMLTableImportContext()
114 : {
115 270 : }
116 :
117 2034 : SvXMLImportContext *SvxXMLTableImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& rAttrList )
118 : {
119 2034 : if( XML_NAMESPACE_DRAW == nPrefix )
120 : {
121 2034 : uno::Reference< XAttributeList > xAttrList( rAttrList );
122 2838 : if( mbOOoFormat &&
123 1034 : (stice_dash == meContext || stice_hatch == meContext ||
124 20 : stice_bitmap == meContext) )
125 : {
126 784 : SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList );
127 784 : xAttrList = pAttrList;
128 784 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
129 5082 : for( sal_Int16 i=0; i < nAttrCount; i++ )
130 : {
131 4298 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
132 8596 : OUString aLocalName;
133 : sal_uInt16 nPrefix_ =
134 4298 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
135 4298 : &aLocalName );
136 4298 : if( XML_NAMESPACE_XLINK == nPrefix_ &&
137 4298 : stice_bitmap == meContext &&
138 0 : IsXMLToken( aLocalName, XML_HREF ) )
139 : {
140 0 : const OUString rValue = xAttrList->getValueByIndex( i );
141 0 : if( !rValue.isEmpty() && '#' == rValue[0] )
142 0 : pAttrList->SetValueByIndex( i, rValue.copy( 1 ) );
143 : }
144 10028 : else if( XML_NAMESPACE_DRAW == nPrefix_ &&
145 7646 : ( ( stice_dash == meContext &&
146 6264 : (IsXMLToken( aLocalName, XML_DOTS1_LENGTH ) ||
147 5616 : IsXMLToken( aLocalName, XML_DOTS2_LENGTH ) ||
148 5756 : IsXMLToken( aLocalName, XML_DISTANCE )) ) ||
149 4006 : ( stice_hatch == meContext &&
150 950 : IsXMLToken( aLocalName, XML_HATCH_DISTANCE ) ) ) )
151 : {
152 1432 : const OUString rValue = xAttrList->getValueByIndex( i );
153 1432 : sal_Int32 nPos = rValue.getLength();
154 2864 : while( nPos && rValue[nPos-1] <= ' ' )
155 0 : --nPos;
156 2864 : if( nPos > 2 &&
157 3810 : ('c'==rValue[nPos-2] || 'C'==rValue[nPos-2]) &&
158 946 : ('h'==rValue[nPos-1] || 'H'==rValue[nPos-1]) )
159 : {
160 946 : pAttrList->SetValueByIndex( i, rValue.copy( 0, nPos-2 ) );
161 1432 : }
162 : }
163 4298 : }
164 : }
165 : try
166 : {
167 2034 : Any aAny;
168 4068 : OUString aName;
169 :
170 2034 : switch( meContext )
171 : {
172 : case stice_color:
173 0 : importColor( nPrefix, rLocalName, xAttrList, aAny, aName );
174 0 : break;
175 : case stice_marker:
176 20 : importMarker( nPrefix, rLocalName, xAttrList, aAny, aName );
177 20 : break;
178 : case stice_dash:
179 594 : importDash( nPrefix, rLocalName, xAttrList, aAny, aName );
180 594 : break;
181 : case stice_hatch:
182 190 : importHatch( nPrefix, rLocalName, xAttrList, aAny, aName );
183 190 : break;
184 : case stice_gradient:
185 1020 : importGradient( nPrefix, rLocalName, xAttrList, aAny, aName );
186 1020 : break;
187 : case stice_bitmap:
188 210 : importBitmap( nPrefix, rLocalName, xAttrList, aAny, aName );
189 210 : break;
190 : case stice_unknown:
191 0 : break;
192 : }
193 :
194 2034 : if( !aName.isEmpty() && aAny.hasValue() )
195 : {
196 2034 : if( mxTable->hasByName( aName ) )
197 : {
198 54 : mxTable->replaceByName( aName, aAny );
199 : }
200 : else
201 : {
202 1980 : mxTable->insertByName( aName, aAny );
203 : }
204 2034 : }
205 : }
206 0 : catch (const uno::Exception&)
207 : {
208 2034 : }
209 : }
210 :
211 2034 : return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
212 : }
213 :
214 0 : void SvxXMLTableImportContext::importColor( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName )
215 : {
216 : (void)nPrfx;
217 : (void)rLocalName;
218 :
219 0 : const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
220 0 : for( sal_Int16 i=0; i < nAttrCount; i++ )
221 : {
222 0 : const OUString& rFullAttrName = xAttrList->getNameByIndex( i );
223 0 : OUString aLocalName;
224 0 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rFullAttrName, &aLocalName );
225 :
226 :
227 0 : if( XML_NAMESPACE_DRAW == nPrefix )
228 : {
229 0 : if( aLocalName == GetXMLToken(XML_NAME) )
230 : {
231 0 : rName = xAttrList->getValueByIndex( i );
232 : }
233 0 : else if( aLocalName == GetXMLToken(XML_COLOR) )
234 : {
235 0 : sal_Int32 nColor(0);
236 : ::sax::Converter::convertColor(nColor,
237 0 : xAttrList->getValueByIndex( i ));
238 0 : rAny <<= nColor;
239 : }
240 : }
241 0 : }
242 0 : }
243 :
244 20 : void SvxXMLTableImportContext::importMarker( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName )
245 : {
246 : (void)nPrfx;
247 : (void)rLocalName;
248 :
249 : try
250 : {
251 20 : XMLMarkerStyleImport aMarkerStyle( GetImport() );
252 20 : aMarkerStyle.importXML( xAttrList, rAny, rName );
253 : }
254 0 : catch (const Exception&)
255 : {
256 : OSL_FAIL("SvxXMLTableImportContext::importMarker(), exception caught!");
257 : }
258 20 : }
259 :
260 594 : void SvxXMLTableImportContext::importDash( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName )
261 : {
262 : (void)nPrfx;
263 : (void)rLocalName;
264 :
265 : try
266 : {
267 594 : XMLDashStyleImport aDashStyle( GetImport() );
268 594 : aDashStyle.importXML( xAttrList, rAny, rName );
269 : }
270 0 : catch (const Exception&)
271 : {
272 : OSL_FAIL("SvxXMLTableImportContext::importDash(), exception caught!");
273 : }
274 594 : }
275 :
276 190 : void SvxXMLTableImportContext::importHatch( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName )
277 : {
278 : (void)nPrfx;
279 : (void)rLocalName;
280 :
281 : try
282 : {
283 190 : XMLHatchStyleImport aHatchStyle( GetImport() );
284 190 : aHatchStyle.importXML( xAttrList, rAny, rName );
285 : }
286 0 : catch (const Exception&)
287 : {
288 : OSL_FAIL("SvxXMLTableImportContext::importHatch(), exception caught!");
289 : }
290 190 : }
291 :
292 1020 : void SvxXMLTableImportContext::importGradient( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName )
293 : {
294 : (void)nPrfx;
295 : (void)rLocalName;
296 :
297 : try
298 : {
299 1020 : XMLGradientStyleImport aGradientStyle( GetImport() );
300 1020 : aGradientStyle.importXML( xAttrList, rAny, rName );
301 : }
302 0 : catch (const Exception&)
303 : {
304 : OSL_FAIL("SvxXMLTableImportContext::importGradient(), exception caught!");
305 : }
306 1020 : }
307 :
308 210 : void SvxXMLTableImportContext::importBitmap( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName )
309 : {
310 : (void)nPrfx;
311 : (void)rLocalName;
312 :
313 : try
314 : {
315 210 : XMLImageStyle aImageStyle;
316 210 : aImageStyle.importXML( xAttrList, rAny, rName, GetImport() );
317 : }
318 0 : catch (const Exception&)
319 : {
320 : OSL_FAIL("SvxXMLTableImportContext::importBitmap(), exception caught!");
321 : }
322 210 : }
323 :
324 :
325 :
326 : // #110680#
327 486 : SvxXMLXTableImport::SvxXMLXTableImport(
328 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rContext,
329 : const uno::Reference< XNameContainer > & rTable,
330 : uno::Reference< XGraphicObjectResolver >& xGrfResolver )
331 : : SvXMLImport(rContext, "", SvXMLImportFlags::NONE),
332 486 : mrTable( rTable )
333 : {
334 486 : SetGraphicResolver( xGrfResolver );
335 :
336 486 : GetNamespaceMap().Add( OUString( sXML_np__ooo ), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
337 486 : GetNamespaceMap().Add( OUString( sXML_np__office ), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
338 486 : GetNamespaceMap().Add( OUString( sXML_np__draw ), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
339 486 : GetNamespaceMap().Add( OUString( sXML_np__xlink ), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
340 :
341 : // OOo namespaces for reading OOo 1.1 files
342 486 : GetNamespaceMap().Add( OUString( sXML_np__office_ooo ),
343 486 : GetXMLToken(XML_N_OFFICE_OOO),
344 972 : XML_NAMESPACE_OFFICE );
345 486 : GetNamespaceMap().Add( OUString( sXML_np__draw_ooo ),
346 486 : GetXMLToken(XML_N_DRAW_OOO),
347 972 : XML_NAMESPACE_DRAW );
348 486 : }
349 :
350 972 : SvxXMLXTableImport::~SvxXMLXTableImport() throw ()
351 : {
352 972 : }
353 :
354 10 : static void openStorageStream( xml::sax::InputSource *pParserInput,
355 : SvXMLGraphicHelper **ppGraphicHelper,
356 : uno::Reference < embed::XStorage > xStorage )
357 : {
358 10 : uno::Reference < io::XStream > xIStm;
359 10 : xIStm.set( xStorage->openStreamElement( "Content.xml", embed::ElementModes::READ ), uno::UNO_QUERY_THROW );
360 10 : if( !xIStm.is() )
361 : {
362 : OSL_FAIL( "could not open Content stream" );
363 10 : return;
364 : }
365 10 : pParserInput->aInputStream = xIStm->getInputStream();
366 10 : *ppGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ );
367 : }
368 :
369 534 : bool SvxXMLXTableImport::load( const OUString &rPath, const OUString &rReferer,
370 : const uno::Reference < embed::XStorage > &xStorage,
371 : const uno::Reference< XNameContainer >& xTable,
372 : bool *bOptLoadedFromStorage ) throw()
373 : {
374 534 : bool bRet = true;
375 534 : SvXMLGraphicHelper* pGraphicHelper = 0;
376 :
377 534 : INetURLObject aURLObj( rPath );
378 534 : bool bUseStorage = aURLObj.GetProtocol() == INetProtocol::NotValid; // a relative path
379 :
380 : try
381 : {
382 534 : uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
383 :
384 1068 : uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create( xContext );
385 :
386 1068 : xml::sax::InputSource aParserInput;
387 1068 : comphelper::LifecycleProxy aNasty;
388 :
389 534 : if( !bUseStorage || !xStorage.is() )
390 : {
391 486 : SfxMedium aMedium( rPath, rReferer, StreamMode::READ | StreamMode::NOCREATE );
392 486 : aParserInput.sSystemId = aMedium.GetName();
393 :
394 486 : if( aMedium.IsStorage() )
395 : {
396 10 : uno::Reference < embed::XStorage > xMediumStorage( aMedium.GetStorage( false ), uno::UNO_QUERY_THROW );
397 10 : openStorageStream( &aParserInput, &pGraphicHelper, xMediumStorage );
398 : }
399 : else
400 476 : aParserInput.aInputStream = aMedium.GetInputStream();
401 : }
402 : else // relative URL into a storage
403 : {
404 48 : uno::Reference< embed::XStorage > xSubStorage;
405 : try
406 : {
407 48 : xSubStorage = comphelper::OStorageHelper::GetStorageAtPath(
408 0 : xStorage, rPath, embed::ElementModes::READ, aNasty );
409 : }
410 48 : catch (const uno::Exception&)
411 : {
412 : }
413 48 : if( xSubStorage.is() )
414 0 : openStorageStream( &aParserInput, &pGraphicHelper, xSubStorage );
415 : else
416 : {
417 48 : ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xStream;
418 48 : xStream = comphelper::OStorageHelper::GetStreamAtPath(
419 0 : xStorage, rPath, embed::ElementModes::READ, aNasty );
420 0 : if( !xStream.is() )
421 0 : return false;
422 0 : aParserInput.aInputStream = xStream->getInputStream();
423 : }
424 0 : if( bOptLoadedFromStorage )
425 48 : *bOptLoadedFromStorage = true;
426 : }
427 :
428 972 : uno::Reference< XGraphicObjectResolver > xGrfResolver;
429 486 : if (pGraphicHelper)
430 10 : xGrfResolver = pGraphicHelper;
431 :
432 : try
433 : {
434 486 : uno::Reference< io::XSeekable > xSeek( aParserInput.aInputStream, uno::UNO_QUERY_THROW );
435 125 : xSeek->seek( 0 );
436 : }
437 361 : catch (const uno::Exception&)
438 : {
439 : }
440 :
441 621 : uno::Reference< XDocumentHandler > xHandler( new SvxXMLXTableImport( xContext, xTable, xGrfResolver ) );
442 486 : xParser->setDocumentHandler( xHandler );
443 486 : xParser->parseStream( aParserInput );
444 :
445 135 : if( pGraphicHelper )
446 544 : SvXMLGraphicHelper::Destroy( pGraphicHelper );
447 : }
448 798 : catch (const uno::Exception&)
449 : {
450 : // thrown each time you load a document with property tables that are not
451 : // on the current machine. FIXME: would be better to check a file exists
452 : // before importing ...
453 : // fprintf (stderr, "parsing etc. exception '%s'\n",
454 : // OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
455 399 : bRet = false;
456 : }
457 :
458 534 : return bRet;
459 : }
460 :
461 135 : SvXMLImportContext *SvxXMLXTableImport::CreateContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList )
462 : {
463 135 : if( XML_NAMESPACE_OOO == nPrefix ||
464 : XML_NAMESPACE_OFFICE == nPrefix )
465 : {
466 135 : bool bOOoFormat = (XML_NAMESPACE_OFFICE == nPrefix);
467 135 : Type aType = mrTable->getElementType();
468 :
469 135 : if ( rLocalName == "color-table" )
470 : {
471 0 : if( aType == ::cppu::UnoType<sal_Int32>::get() )
472 0 : return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_color, mrTable, bOOoFormat );
473 : }
474 135 : else if ( rLocalName == "marker-table" )
475 : {
476 1 : if( aType == cppu::UnoType<drawing::PolyPolygonBezierCoords>::get())
477 1 : return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_marker, mrTable, bOOoFormat );
478 : }
479 134 : else if ( rLocalName == "dash-table" )
480 : {
481 54 : if( aType == cppu::UnoType<drawing::LineDash>::get())
482 54 : return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_dash, mrTable, bOOoFormat );
483 : }
484 80 : else if ( rLocalName == "hatch-table" )
485 : {
486 19 : if( aType == cppu::UnoType<drawing::Hatch>::get())
487 19 : return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_hatch, mrTable, bOOoFormat );
488 : }
489 61 : else if ( rLocalName == "gradient-table" )
490 : {
491 51 : if( aType == cppu::UnoType<awt::Gradient>::get())
492 51 : return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_gradient, mrTable, bOOoFormat );
493 : }
494 10 : else if ( rLocalName == "bitmap-table" )
495 : {
496 10 : if( aType == ::cppu::UnoType<OUString>::get())
497 10 : return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_bitmap, mrTable, bOOoFormat );
498 0 : }
499 : }
500 :
501 0 : return new SvXMLImportContext( *this, nPrefix, rLocalName );
502 : }
503 :
504 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|