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