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