xref: /trunk/main/sw/source/core/swg/SwXMLTextBlocks1.cxx (revision a5b190bfa3e1bed4623e2958a8877664a3b5506c)
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_sw.hxx"
30 #include <com/sun/star/embed/ElementModes.hpp>
31 #include <com/sun/star/embed/XTransactedObject.hpp>
32 #include <svl/macitem.hxx>
33 #include <svtools/unoevent.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <unotools/streamwrap.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <com/sun/star/xml/sax/InputSource.hpp>
38 #include <com/sun/star/io/XActiveDataSource.hpp>
39 #include <com/sun/star/xml/sax/XParser.hpp>
40 #include <com/sun/star/document/XStorageBasedDocument.hpp>
41 #include <doc.hxx>
42 #ifndef _DOCSH_HXX
43 #include <docsh.hxx>
44 #endif
45 #include <shellio.hxx>
46 #include <SwXMLTextBlocks.hxx>
47 #include <SwXMLBlockImport.hxx>
48 #include <SwXMLBlockExport.hxx>
49 #include <swevent.hxx>
50 #include <swerror.h>
51 #include <errhdl.hxx>
52 
53 
54 #define STREAM_STGREAD  ( STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE )
55 #define STREAM_STGWRITE ( STREAM_READ | STREAM_WRITE | STREAM_SHARE_DENYWRITE )
56 
57 sal_Char __FAR_DATA XMLN_BLOCKLIST[] = "BlockList.xml";
58 
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::container;
62 using ::rtl::OUString;
63 
64 using ::xmloff::token::XML_BLOCK_LIST;
65 using ::xmloff::token::XML_UNFORMATTED_TEXT;
66 using ::xmloff::token::GetXMLToken;
67 
68 sal_uLong SwXMLTextBlocks::GetDoc( sal_uInt16 nIdx )
69 {
70     String aFolderName ( GetPackageName ( nIdx ) );
71 
72     if (!IsOnlyTextBlock ( nIdx ) )
73     {
74         try
75         {
76             xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ );
77             xMedium = new SfxMedium(xRoot, GetBaseURL(), S2U("writer8"));
78             SwReader aReader(*xMedium,aFolderName, pDoc );
79             ReadXML->SetBlockMode( sal_True );
80             aReader.Read( *ReadXML );
81             ReadXML->SetBlockMode( sal_False );
82             // Ole objects fails to display when inserted into document
83             // because the ObjectReplacement folder ( and contents are missing )
84             rtl::OUString sObjReplacements( RTL_CONSTASCII_USTRINGPARAM( "ObjectReplacements" ) );
85             if ( xRoot->hasByName( sObjReplacements ) )
86             {
87                 uno::Reference< document::XStorageBasedDocument > xDocStor( pDoc->GetDocShell()->GetModel(), uno::UNO_QUERY_THROW );
88                 uno::Reference< embed::XStorage > xStr( xDocStor->getDocumentStorage() );
89                 if ( xStr.is() )
90                 {
91                     xRoot->copyElementTo( sObjReplacements, xStr, sObjReplacements );
92                     uno::Reference< embed::XTransactedObject > xTrans( xStr, uno::UNO_QUERY );
93                     if ( xTrans.is() )
94                         xTrans->commit();
95                 }
96             }
97         }
98         catch( uno::Exception& )
99         {
100         }
101 
102         xRoot = 0;
103     }
104     else
105     {
106         String aStreamName = aFolderName + (OUString) String::CreateFromAscii(".xml");
107         try
108         {
109             xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ );
110             uno::Reference < io::XStream > xStream = xRoot->openStreamElement( aStreamName, embed::ElementModes::READ );
111 
112             uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
113                 comphelper::getProcessServiceFactory();
114             ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" );
115             if( !xServiceFactory.is() )
116             {
117                 // Throw an exception ?
118             }
119 
120             xml::sax::InputSource aParserInput;
121             aParserInput.sSystemId = aNames [ nIdx ] ->aPackageName;
122 
123             aParserInput.aInputStream = xStream->getInputStream();
124 
125             // get parser
126             uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
127                     OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
128             ASSERT( xXMLParser.is(),
129                     "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
130             if( !xXMLParser.is() )
131             {
132                 // Maybe throw an exception?
133             }
134 
135             // get filter
136             // #110680#
137             // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( *this, aCur, sal_True );
138             uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( xServiceFactory, *this, aCur, sal_True );
139 
140             // connect parser and filter
141             uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
142             xParser->setDocumentHandler( xFilter );
143 
144             // parse
145             try
146             {
147                 xParser->parseStream( aParserInput );
148             }
149             catch( xml::sax::SAXParseException&  )
150             {
151                 // re throw ?
152             }
153             catch( xml::sax::SAXException&  )
154             {
155                 // re throw ?
156             }
157             catch( io::IOException& )
158             {
159                 // re throw ?
160             }
161 
162             bInfoChanged = sal_False;
163             MakeBlockText(aCur);
164         }
165         catch( uno::Exception& )
166         {
167         }
168 
169         xRoot = 0;
170     }
171     return 0;
172 }
173 
174 // event description for autotext events; this constant should really be
175 // taken from unocore/unoevents.cxx or ui/unotxt.cxx
176 const struct SvEventDescription aAutotextEvents[] =
177 {
178     { SW_EVENT_START_INS_GLOSSARY,  "OnInsertStart" },
179     { SW_EVENT_END_INS_GLOSSARY,    "OnInsertDone" },
180     { 0, NULL }
181 };
182 
183 sal_uLong SwXMLTextBlocks::GetMacroTable( sal_uInt16 nIdx,
184                                       SvxMacroTableDtor& rMacroTbl,
185                                       sal_Bool bFileAlreadyOpen )
186 {
187     // set current auto text
188 
189     aShort = aNames[ nIdx ]->aShort;
190     aLong = aNames[ nIdx ]->aLong;
191     aPackageName = aNames[ nIdx ]->aPackageName;
192 
193     sal_uLong nRet = 0;
194 
195     // open stream in proper sub-storage
196     if( !bFileAlreadyOpen )
197     {
198         CloseFile();
199         nRet = OpenFile ( sal_True );
200     }
201     if ( 0 == nRet )
202     {
203         try
204         {
205             xRoot = xBlkRoot->openStorageElement( aPackageName, embed::ElementModes::READ );
206             long nTmp = SOT_FORMATSTR_ID_STARWRITER_60;
207             sal_Bool bOasis = ( SotStorage::GetVersion( xRoot ) > nTmp );
208 
209             OUString sStreamName = OUString::createFromAscii("atevent.xml");
210             uno::Reference < io::XStream > xDocStream = xRoot->openStreamElement(
211                 sStreamName, embed::ElementModes::READ );
212             DBG_ASSERT(xDocStream.is(), "Can't create stream");
213             if ( xDocStream.is() )
214             {
215                 uno::Reference<io::XInputStream> xInputStream = xDocStream->getInputStream();
216 
217                 // prepare ParserInputSrouce
218                 xml::sax::InputSource aParserInput;
219                 aParserInput.sSystemId = aName;
220                 aParserInput.aInputStream = xInputStream;
221 
222                 // get service factory
223                 uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
224                     comphelper::getProcessServiceFactory();
225                 if ( xServiceFactory.is() )
226                 {
227 
228                     // get parser
229                     OUString sParserService( RTL_CONSTASCII_USTRINGPARAM(
230                         "com.sun.star.xml.sax.Parser" ) );
231                     uno::Reference< xml::sax::XParser > xParser(
232                         xServiceFactory->createInstance(sParserService),
233                         UNO_QUERY );
234                     DBG_ASSERT( xParser.is(), "Can't create parser" );
235                     if( xParser.is() )
236                     {
237                         // create descriptor and reference to it. Either
238                         // both or neither must be kept because of the
239                         // reference counting!
240                         SvMacroTableEventDescriptor* pDescriptor =
241                             new SvMacroTableEventDescriptor(aAutotextEvents);
242                         uno::Reference<XNameReplace> xReplace = pDescriptor;
243                         Sequence<Any> aFilterArguments( 1 );
244                         aFilterArguments[0] <<= xReplace;
245 
246                         // get filter
247                         OUString sFilterComponent( OUString::createFromAscii(
248                             bOasis
249                             ? "com.sun.star.comp.Writer.XMLOasisAutotextEventsImporter"
250                             : "com.sun.star.comp.Writer.XMLAutotextEventsImporter"));
251                         uno::Reference< xml::sax::XDocumentHandler > xFilter(
252                             xServiceFactory->createInstanceWithArguments(
253                                 sFilterComponent, aFilterArguments),
254                             UNO_QUERY );
255                         DBG_ASSERT( xFilter.is(),
256                                     "can't instantiate atevents filter");
257                         if ( xFilter.is() )
258                         {
259                             // connect parser and filter
260                             xParser->setDocumentHandler( xFilter );
261 
262                             // connect model and filter
263                             uno::Reference<document::XImporter> xImporter( xFilter,
264                                                                     UNO_QUERY );
265 
266                             // we don't need a model
267                             // xImporter->setTargetDocument( xModelComponent );
268 
269                             // parse the stream
270                             try
271                             {
272                                 xParser->parseStream( aParserInput );
273                             }
274                             catch( xml::sax::SAXParseException& )
275                             {
276                                 // workaround for #83452#: SetSize doesn't work
277                                 // nRet = ERR_SWG_READ_ERROR;
278                             }
279                             catch( xml::sax::SAXException& )
280                             {
281                                 nRet = ERR_SWG_READ_ERROR;
282                             }
283                             catch( io::IOException& )
284                             {
285                                 nRet = ERR_SWG_READ_ERROR;
286                             }
287 
288                             // and finally, copy macro into table
289                             if (0 == nRet)
290                                 pDescriptor->copyMacrosIntoTable(rMacroTbl);
291                         }
292                         else
293                             nRet = ERR_SWG_READ_ERROR;
294                     }
295                     else
296                         nRet = ERR_SWG_READ_ERROR;
297 
298                 }
299                 else
300                     nRet = ERR_SWG_READ_ERROR;
301             }
302             else
303                 nRet = ERR_SWG_READ_ERROR;
304         }
305         catch( uno::Exception& )
306         {
307             nRet = ERR_SWG_READ_ERROR;
308         }
309     }
310     else
311         nRet = ERR_SWG_READ_ERROR;
312 
313     // success!
314     return nRet;
315 }
316 
317 
318 sal_uLong SwXMLTextBlocks::GetBlockText( const String& rShort, String& rText )
319 {
320     sal_uLong n = 0;
321     sal_Bool bTextOnly = sal_True;
322     String aFolderName;
323     GeneratePackageName ( rShort, aFolderName );
324     String aStreamName = aFolderName + (OUString) String::CreateFromAscii(".xml");
325     rText.Erase();
326 
327     try
328     {
329         xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ );
330         uno::Reference < container::XNameAccess > xAccess( xRoot, uno::UNO_QUERY );
331         if ( !xAccess->hasByName( aStreamName ) || !xRoot->isStreamElement( aStreamName ) )
332         {
333             bTextOnly = sal_False;
334             aStreamName = String::CreateFromAscii("content.xml");
335         }
336 
337         uno::Reference < io::XStream > xContents = xRoot->openStreamElement( aStreamName, embed::ElementModes::READ );
338         uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
339             comphelper::getProcessServiceFactory();
340         ASSERT( xServiceFactory.is(), "XMLReader::Read: got no service manager" );
341         if( !xServiceFactory.is() )
342         {
343             // Throw an exception ?
344         }
345 
346         xml::sax::InputSource aParserInput;
347         aParserInput.sSystemId = aName;
348         aParserInput.aInputStream = xContents->getInputStream();
349 
350         // get parser
351         uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
352                 OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
353         ASSERT( xXMLParser.is(),
354                 "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
355         if( !xXMLParser.is() )
356         {
357             // Maybe throw an exception?
358         }
359 
360         // get filter
361         // #110680#
362         // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( *this, rText, bTextOnly );
363         uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLTextBlockImport( xServiceFactory, *this, rText, bTextOnly );
364 
365         // connect parser and filter
366         uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
367         xParser->setDocumentHandler( xFilter );
368 
369         // parse
370         try
371         {
372             xParser->parseStream( aParserInput );
373         }
374         catch( xml::sax::SAXParseException&  )
375         {
376             // re throw ?
377         }
378         catch( xml::sax::SAXException&  )
379         {
380             // re throw ?
381         }
382         catch( io::IOException& )
383         {
384             // re throw ?
385         }
386 
387         xRoot = 0;
388     }
389     catch ( uno::Exception& )
390     {
391         ASSERT( sal_False, "Tried to open non-existent folder or stream!");
392     }
393 
394     return n;
395 }
396 
397 sal_uLong SwXMLTextBlocks::PutBlockText( const String& rShort, const String& ,
398                                      const String& rText,  const String& rPackageName )
399 {
400     GetIndex ( rShort );
401     /*
402     if (xBlkRoot->IsContained ( rPackageName ) )
403     {
404         xBlkRoot->Remove ( rPackageName );
405         xBlkRoot->Commit ( );
406     }
407     */
408     String aFolderName( rPackageName );
409     String aStreamName = aFolderName + (OUString) String::CreateFromAscii(".xml");
410 
411     uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
412         comphelper::getProcessServiceFactory();
413     ASSERT( xServiceFactory.is(),
414             "XMLReader::Read: got no service manager" );
415     if( !xServiceFactory.is() )
416     {
417         // Throw an exception ?
418     }
419 
420     uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
421          OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
422     DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
423     sal_uLong nRes = 0;
424 
425     try
426     {
427     xRoot = xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::WRITE );
428     uno::Reference < io::XStream > xDocStream = xRoot->openStreamElement( aStreamName,
429                 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
430 
431     uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
432     String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
433     OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( "text/xml") );
434     Any aAny;
435     aAny <<= aMime;
436     xSet->setPropertyValue( aPropName, aAny );
437     uno::Reference < io::XOutputStream > xOut = xDocStream->getOutputStream();
438     uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
439     xSrc->setOutputStream(xOut);
440 
441     uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter,
442         uno::UNO_QUERY);
443 
444     // #110680#
445     // SwXMLTextBlockExport aExp(*this, GetXMLToken ( XML_UNFORMATTED_TEXT ), xHandler);
446     SwXMLTextBlockExport aExp( xServiceFactory, *this, GetXMLToken ( XML_UNFORMATTED_TEXT ), xHandler);
447 
448     aExp.exportDoc( rText );
449 
450     uno::Reference < embed::XTransactedObject > xTrans( xRoot, uno::UNO_QUERY );
451     if ( xTrans.is() )
452         xTrans->commit();
453 
454     if (! (nFlags & SWXML_NOROOTCOMMIT) )
455     {
456         uno::Reference < embed::XTransactedObject > xTmpTrans( xBlkRoot, uno::UNO_QUERY );
457         if ( xTmpTrans.is() )
458             xTmpTrans->commit();
459     }
460     }
461     catch ( uno::Exception& )
462     {
463         nRes = ERR_SWG_WRITE_ERROR;
464     }
465 
466     xRoot = 0;
467 
468     //TODO/LATER: error handling
469     /*
470     sal_uLong nErr = xBlkRoot->GetError();
471     sal_uLong nRes = 0;
472     if( nErr == SVSTREAM_DISK_FULL )
473         nRes = ERR_W4W_WRITE_FULL;
474     else if( nErr != SVSTREAM_OK )
475         nRes = ERR_SWG_WRITE_ERROR;
476     */
477     if( !nRes )         // damit ueber GetText & nCur aufs Doc zugegriffen
478         MakeBlockText( rText );
479 
480     return nRes;
481 }
482 
483 void SwXMLTextBlocks::ReadInfo( void )
484 {
485     try
486     {
487     const OUString sDocName( RTL_CONSTASCII_USTRINGPARAM( XMLN_BLOCKLIST ) );
488     uno::Reference < container::XNameAccess > xAccess( xBlkRoot, uno::UNO_QUERY );
489     if ( xAccess.is() && xAccess->hasByName( sDocName ) && xBlkRoot->isStreamElement( sDocName ) )
490     {
491         uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
492                 comphelper::getProcessServiceFactory();
493         ASSERT( xServiceFactory.is(),
494                 "XMLReader::Read: got no service manager" );
495         if( !xServiceFactory.is() )
496         {
497             // Throw an exception ?
498         }
499 
500         xml::sax::InputSource aParserInput;
501         aParserInput.sSystemId = sDocName;
502 
503         uno::Reference < io::XStream > xDocStream = xBlkRoot->openStreamElement( sDocName, embed::ElementModes::READ );
504         aParserInput.aInputStream = xDocStream->getInputStream();
505 
506         // get parser
507         uno::Reference< XInterface > xXMLParser = xServiceFactory->createInstance(
508             OUString::createFromAscii("com.sun.star.xml.sax.Parser") );
509         ASSERT( xXMLParser.is(),
510             "XMLReader::Read: com.sun.star.xml.sax.Parser service missing" );
511         if( !xXMLParser.is() )
512         {
513             // Maybe throw an exception?
514         }
515 
516         // get filter
517         // #110680#
518         // uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLBlockListImport( *this );
519         uno::Reference< xml::sax::XDocumentHandler > xFilter = new SwXMLBlockListImport( xServiceFactory, *this );
520 
521         // connect parser and filter
522         uno::Reference< xml::sax::XParser > xParser( xXMLParser, UNO_QUERY );
523         xParser->setDocumentHandler( xFilter );
524 
525         // parse
526         try
527         {
528             xParser->parseStream( aParserInput );
529         }
530         catch( xml::sax::SAXParseException&  )
531         {
532             // re throw ?
533         }
534         catch( xml::sax::SAXException&  )
535         {
536             // re throw ?
537         }
538         catch( io::IOException& )
539         {
540             // re throw ?
541         }
542     }
543     }
544     catch ( uno::Exception& )
545     {
546     }
547 }
548 void SwXMLTextBlocks::WriteInfo( void )
549 {
550     if ( xBlkRoot.is() || 0 == OpenFile ( sal_False ) )
551     {
552         uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
553             comphelper::getProcessServiceFactory();
554         DBG_ASSERT( xServiceFactory.is(),
555                 "XMLReader::Read: got no service manager" );
556         if( !xServiceFactory.is() )
557         {
558             // Throw an exception ?
559         }
560 
561         uno::Reference < XInterface > xWriter (xServiceFactory->createInstance(
562          OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.sax.Writer"))));
563         DBG_ASSERT(xWriter.is(),"com.sun.star.xml.sax.Writer service missing");
564         OUString sDocName( RTL_CONSTASCII_USTRINGPARAM( XMLN_BLOCKLIST ) );
565 
566         /*
567         if ( xBlkRoot->IsContained( sDocName) )
568         {
569             xBlkRoot->Remove ( sDocName );
570             xBlkRoot->Commit();
571         }
572         */
573 
574         try
575         {
576         uno::Reference < io::XStream > xDocStream = xBlkRoot->openStreamElement( sDocName,
577                     embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
578 
579         uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
580         String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
581         OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( "text/xml") );
582         Any aAny;
583         aAny <<= aMime;
584         xSet->setPropertyValue( aPropName, aAny );
585         uno::Reference < io::XOutputStream > xOut = xDocStream->getOutputStream();
586         uno::Reference<io::XActiveDataSource> xSrc(xWriter, uno::UNO_QUERY);
587         xSrc->setOutputStream(xOut);
588 
589         uno::Reference<xml::sax::XDocumentHandler> xHandler(xWriter, uno::UNO_QUERY);
590 
591         // #110680#
592         // SwXMLBlockListExport aExp(*this, OUString::createFromAscii(XMLN_BLOCKLIST), xHandler);
593         SwXMLBlockListExport aExp( xServiceFactory, *this, OUString::createFromAscii(XMLN_BLOCKLIST), xHandler);
594 
595         aExp.exportDoc( XML_BLOCK_LIST );
596 
597         uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY );
598         if ( xTrans.is() )
599             xTrans->commit();
600         }
601         catch ( uno::Exception& )
602         {
603         }
604 
605         bInfoChanged = sal_False;
606         return;
607     }
608 }
609 
610 sal_uLong SwXMLTextBlocks::SetMacroTable(
611     sal_uInt16 nIdx,
612     const SvxMacroTableDtor& rMacroTbl,
613     sal_Bool bFileAlreadyOpen )
614 {
615     // set current autotext
616     aShort = aNames[ nIdx ]->aShort;
617     aLong = aNames[ nIdx ]->aLong;
618     aPackageName = aNames[ nIdx ]->aPackageName;
619 
620     // start XML autotext event export
621     sal_uLong nRes = 0;
622 
623     uno::Reference< lang::XMultiServiceFactory > xServiceFactory =
624         comphelper::getProcessServiceFactory();
625     ASSERT( xServiceFactory.is(),
626             "XML autotext event write:: got no service manager" );
627     if( !xServiceFactory.is() )
628         return ERR_SWG_WRITE_ERROR;
629 
630     // Get model
631     uno::Reference< lang::XComponent > xModelComp(
632         pDoc->GetDocShell()->GetModel(), UNO_QUERY );
633     ASSERT( xModelComp.is(), "XMLWriter::Write: got no model" );
634     if( !xModelComp.is() )
635         return ERR_SWG_WRITE_ERROR;
636 
637     // open stream in proper sub-storage
638     if( !bFileAlreadyOpen )
639     {
640         CloseFile();    // close (it may be open in read-only-mode)
641         nRes = OpenFile ( sal_False );
642     }
643 
644     if ( 0 == nRes )
645     {
646         try
647         {
648             xRoot = xBlkRoot->openStorageElement( aPackageName, embed::ElementModes::WRITE );
649             OUString sStreamName( RTL_CONSTASCII_USTRINGPARAM("atevent.xml") );
650             long nTmp = SOT_FORMATSTR_ID_STARWRITER_60;
651             sal_Bool bOasis = ( SotStorage::GetVersion( xRoot ) > nTmp );
652 
653             uno::Reference < io::XStream > xDocStream = xRoot->openStreamElement( sStreamName,
654                         embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
655 
656             uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
657             String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
658             OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( "text/xml") );
659             Any aAny;
660             aAny <<= aMime;
661             xSet->setPropertyValue( aPropName, aAny );
662             uno::Reference < io::XOutputStream > xOutputStream = xDocStream->getOutputStream();
663 
664             // get XML writer
665             uno::Reference< io::XActiveDataSource > xSaxWriter(
666                 xServiceFactory->createInstance(
667                     OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
668                 UNO_QUERY );
669             ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
670             if( xSaxWriter.is() )
671             {
672 
673                 // connect XML writer to output stream
674                 xSaxWriter->setOutputStream( xOutputStream );
675                 uno::Reference<xml::sax::XDocumentHandler> xDocHandler(
676                     xSaxWriter, UNO_QUERY);
677 
678                 // construct events object
679                 uno::Reference<XNameAccess> xEvents =
680                     new SvMacroTableEventDescriptor(rMacroTbl,aAutotextEvents);
681 
682                 // prepare arguments (prepend doc handler to given arguments)
683                 Sequence<Any> aParams(2);
684                 aParams[0] <<= xDocHandler;
685                 aParams[1] <<= xEvents;
686 
687                 // get filter component
688                 uno::Reference< document::XExporter > xExporter(
689                     xServiceFactory->createInstanceWithArguments(
690                         OUString::createFromAscii(
691                          bOasis
692                             ? "com.sun.star.comp.Writer.XMLOasisAutotextEventsExporter"
693                             : "com.sun.star.comp.Writer.XMLAutotextEventsExporter"),
694                         aParams), UNO_QUERY);
695                 ASSERT( xExporter.is(),
696                         "can't instantiate export filter component" );
697                 if( xExporter.is() )
698                 {
699                     // connect model and filter
700                     xExporter->setSourceDocument( xModelComp );
701 
702                     // filter!
703                     Sequence<beans::PropertyValue> aFilterProps( 0 );
704                     uno::Reference < document::XFilter > xFilter( xExporter,
705                                                              UNO_QUERY );
706                     xFilter->filter( aFilterProps );
707                 }
708                 else
709                     nRes = ERR_SWG_WRITE_ERROR;
710             }
711             else
712                 nRes = ERR_SWG_WRITE_ERROR;
713 
714             // finally, commit stream, sub-storage and storage
715             uno::Reference < embed::XTransactedObject > xTmpTrans( xRoot, uno::UNO_QUERY );
716             if ( xTmpTrans.is() )
717                 xTmpTrans->commit();
718 
719             if ( !bFileAlreadyOpen )
720             {
721                 uno::Reference < embed::XTransactedObject > xTrans( xBlkRoot, uno::UNO_QUERY );
722                 if ( xTrans.is() )
723                     xTrans->commit();
724             }
725 
726             xRoot = 0;
727         }
728         catch ( uno::Exception& )
729         {
730             nRes = ERR_SWG_WRITE_ERROR;
731         }
732 
733         if( !bFileAlreadyOpen )
734             CloseFile();
735     }
736     else
737         nRes = ERR_SWG_WRITE_ERROR;
738 
739     return nRes;
740 }
741 
742