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());
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