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