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 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(), S2U("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 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 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 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 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 } 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 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