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 31 32 #include <hintids.hxx> 33 #include <unotools/tempfile.hxx> 34 #include <svl/urihelper.hxx> 35 #include <svl/stritem.hxx> 36 #include <svl/eitem.hxx> 37 #include <sfx2/app.hxx> 38 #include <sfx2/docfile.hxx> 39 #include <sfx2/docfilt.hxx> 40 #include <sfx2/fcontnr.hxx> 41 #include <sfx2/bindings.hxx> 42 #include <sfx2/request.hxx> 43 #include <fmtinfmt.hxx> 44 #include <fmtanchr.hxx> 45 #include <doc.hxx> 46 #include <IDocumentUndoRedo.hxx> 47 #include <docary.hxx> 48 #include <pam.hxx> 49 #include <ndtxt.hxx> 50 #include <docsh.hxx> 51 #include <globdoc.hxx> 52 #include <shellio.hxx> 53 #include <swundo.hxx> // fuer die UndoIds 54 #include <section.hxx> 55 #include <doctxm.hxx> 56 #include <poolfmt.hxx> 57 #include <switerator.hxx> 58 #include <com/sun/star/uno/Reference.h> 59 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 60 #include <com/sun/star/document/XDocumentProperties.hpp> 61 62 using namespace ::com::sun::star; 63 64 enum SwSplitDocType 65 { 66 SPLITDOC_TO_GLOBALDOC, 67 SPLITDOC_TO_HTML 68 }; 69 70 sal_Bool SwDoc::GenerateGlobalDoc( const String& rPath, 71 const SwTxtFmtColl* pSplitColl ) 72 { 73 return SplitDoc( SPLITDOC_TO_GLOBALDOC, rPath, pSplitColl ); 74 } 75 76 //#outline level,add by zhaojianwei 77 sal_Bool SwDoc::GenerateGlobalDoc( const String& rPath, int nOutlineLevel ) 78 { 79 return SplitDoc( SPLITDOC_TO_GLOBALDOC, rPath, nOutlineLevel ); 80 } 81 sal_Bool SwDoc::GenerateHTMLDoc( const String& rPath, int nOutlineLevel ) 82 { 83 return SplitDoc( SPLITDOC_TO_HTML, rPath, nOutlineLevel ); 84 } 85 //<-end,zhaojianwei 86 87 sal_Bool SwDoc::GenerateHTMLDoc( const String& rPath, 88 const SwTxtFmtColl* pSplitColl ) 89 { 90 #ifdef JP_TEST 91 if( !pSplitColl ) 92 { 93 sal_uInt8 nLvl = 1; 94 const SwTxtFmtColls& rFmtColls =*GetTxtFmtColls(); 95 for( sal_uInt16 n = rFmtColls.Count(); n; ) 96 //if( nLvl == rFmtColls[ --n ]->GetOutlineLevel() )//#outline level,zhaojianwei 97 if( nLvl == rFmtColls[ --n ]->GetAttrOutlineLevel() -1 )//<-end,zhaojianwei 0814 98 { 99 pSplitColl = rFmtColls[ n ]; 100 break; 101 } 102 103 if( !pSplitColl ) 104 pSplitColl = GetTxtCollFromPool( RES_POOLCOLL_HEADLINE2 ); 105 } 106 #endif 107 108 return SplitDoc( SPLITDOC_TO_HTML, rPath, pSplitColl ); 109 } 110 111 sal_Bool SwDoc::SplitDoc( sal_uInt16 eDocType, const String& rPath, 112 const SwTxtFmtColl* pSplitColl ) 113 { 114 // ueber alle Node der Vorlage Iterieren und dafuer einzelne 115 // Dokumente erzeugen und in diesem gegen 116 // - gelinkte Bereiche (GlobalDoc) 117 // - Links (HTML) 118 // austauschen. 119 // Am Ende wird dieses Doc als GlobalDoc/HTML-Doc gespreichert. 120 if( !pDocShell || !pDocShell->GetMedium() || 121 ( SPLITDOC_TO_GLOBALDOC == eDocType && get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) ) 122 return sal_False; 123 124 sal_uInt16 nOutl = 0; 125 SwOutlineNodes* pOutlNds = (SwOutlineNodes*)&GetNodes().GetOutLineNds(); 126 SwNodePtr pSttNd; 127 128 if( pSplitColl ) 129 { 130 // wenn keine OutlineNumerierung ist, dann benutze eigenes Array 131 // und sammel die Nodes zusammen. 132 //if( NO_NUMBERING == pSplitColl->GetOutlineLevel() )//#outline level,zhaojianwei 133 if( pSplitColl->GetAttrOutlineLevel() == 0 )//<-end,zhaojianwei, 0814 134 { 135 pOutlNds = new SwOutlineNodes( 8, 8 ); 136 SwIterator<SwTxtNode,SwFmtColl> aIter( *pSplitColl ); 137 for( SwTxtNode* pTNd = aIter.First(); pTNd; pTNd = aIter.Next() ) 138 if( pTNd->GetNodes().IsDocNodes() ) 139 pOutlNds->Insert( pTNd ); 140 141 if( !pOutlNds->Count() ) 142 { 143 delete pOutlNds; 144 return sal_False; 145 } 146 } 147 } 148 else 149 { 150 // dann suche die Gliederungs - Vorlage, der 1. Ebene 151 const SwTxtFmtColls& rFmtColls =*GetTxtFmtColls(); 152 for( sal_uInt16 n = rFmtColls.Count(); n; ) 153 //if( !rFmtColls[ --n ]->GetOutlineLevel() )//#outline level,zhaojianwei 154 if ( rFmtColls[ --n ]->GetAttrOutlineLevel() == 1 )//<-end,zhaojianwei 155 { 156 pSplitColl = rFmtColls[ n ]; 157 break; 158 } 159 160 if( !pSplitColl ) 161 return sal_False; 162 } 163 164 const SfxFilter* pFilter; 165 switch( eDocType ) 166 { 167 case SPLITDOC_TO_HTML: 168 pFilter = SwIoSystem::GetFilterOfFormat( String::CreateFromAscii( 169 RTL_CONSTASCII_STRINGPARAM( "HTML" ))); 170 break; 171 172 default: 173 // case SPLITDOC_TO_GLOBALDOC: 174 pFilter = SwIoSystem::GetFilterOfFormat( 175 String::CreateFromAscii( FILTER_XML )); 176 eDocType = SPLITDOC_TO_GLOBALDOC; 177 break; 178 } 179 180 if( !pFilter ) 181 return sal_False; 182 183 // Undo/Redline aufjedenfall abschalten 184 GetIDocumentUndoRedo().DoUndo(false); 185 SetRedlineMode_intern( (RedlineMode_t)(GetRedlineMode() & ~nsRedlineMode_t::REDLINE_ON)); 186 187 String sExt( pFilter->GetSuffixes().GetToken(0, ',') ); 188 if( !sExt.Len() ) 189 sExt.AssignAscii( "sxw" ); 190 if( '.' != sExt.GetChar( 0 ) ) 191 sExt.Insert( '.', 0 ); 192 193 INetURLObject aEntry(rPath); 194 String sLeading(aEntry.GetBase()); 195 aEntry.removeSegment(); 196 String sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE ); 197 utl::TempFile aTemp(sLeading,&sExt,&sPath ); 198 aTemp.EnableKillingFile(); 199 200 DateTime aTmplDate; 201 { 202 Time a2Min( 0 ); a2Min.SetMin( 2 ); 203 aTmplDate += a2Min; 204 } 205 206 207 // alle Ungueltigen ueberspringen 208 while( nOutl < pOutlNds->Count() && 209 pOutlNds->GetObject( nOutl )->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) 210 ++nOutl; 211 212 do { 213 pSttNd = 0; 214 215 SwNodePtr pNd; 216 for( ; nOutl < pOutlNds->Count(); ++nOutl ) 217 if( ( pNd = pOutlNds->GetObject( nOutl ))->GetTxtNode()-> 218 GetTxtColl() == pSplitColl && 219 !pNd->FindTableNode() ) 220 { 221 pSttNd = pNd; 222 break; 223 } 224 225 if( pSttNd ) 226 { 227 SwNodePtr pEndNd = 0; 228 for( ++nOutl; nOutl < pOutlNds->Count(); ++nOutl ) 229 { 230 pNd = pOutlNds->GetObject( nOutl ); 231 SwTxtFmtColl* pTColl = pNd->GetTxtNode()->GetTxtColl(); 232 233 //if( ( pTColl == pSplitColl || //#outline level,zhaojianwei 234 // ( NO_NUMBERING != pSplitColl->GetOutlineLevel() && 235 // pTColl->GetOutlineLevel() < 236 // pSplitColl->GetOutlineLevel() )) && 237 // !pNd->FindTableNode() ) 238 if( ( pTColl == pSplitColl || 239 ( pSplitColl->GetAttrOutlineLevel() > 0 && 240 pTColl->GetAttrOutlineLevel() > 0 && 241 pTColl->GetAttrOutlineLevel() < 242 pSplitColl->GetAttrOutlineLevel() )) && 243 !pNd->FindTableNode() ) //<-end,zhaojianwei 244 { 245 pEndNd = pNd; 246 247 break; 248 } 249 } 250 SwNodeIndex aEndIdx( pEndNd ? *pEndNd 251 : GetNodes().GetEndOfContent() ); 252 253 // die Nodes komplett rausschreiben 254 String sFileName; 255 if( pSttNd->GetIndex() + 1 < aEndIdx.GetIndex() ) 256 { 257 SfxObjectShellLock xDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); 258 if( xDocSh->DoInitNew( 0 ) ) 259 { 260 SwDoc* pDoc = ((SwDocShell*)(&xDocSh))->GetDoc(); 261 262 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 263 ((SwDocShell*)(&xDocSh))->GetModel(), 264 uno::UNO_QUERY_THROW); 265 uno::Reference<document::XDocumentProperties> xDocProps( 266 xDPS->getDocumentProperties()); 267 DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties"); 268 // the GlobalDoc is the template 269 xDocProps->setTemplateName(aEmptyStr); 270 ::util::DateTime uDT(aTmplDate.Get100Sec(), 271 aTmplDate.GetSec(), aTmplDate.GetMin(), 272 aTmplDate.GetHour(), aTmplDate.GetDay(), 273 aTmplDate.GetMonth(), aTmplDate.GetYear()); 274 xDocProps->setTemplateDate(uDT); 275 xDocProps->setTemplateURL(rPath); 276 //JP 14.06.99: Set the text of the "split para" as title 277 // from the new doc. Is the current doc has 278 // a title, insert it at begin. 279 String sTitle( xDocProps->getTitle() ); 280 if( sTitle.Len() ) 281 sTitle.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " )); 282 sTitle += ((SwTxtNode*)pSttNd)->GetExpandTxt(); 283 xDocProps->setTitle( sTitle ); 284 285 // Vorlagen ersetzen 286 pDoc->ReplaceStyles( *this ); 287 288 // KapitelNumerierung uebernehmen 289 if( pOutlineRule ) 290 pDoc->SetOutlineNumRule( *pOutlineRule ); 291 292 SwNodeRange aRg( *pSttNd, 0, aEndIdx.GetNode() ); 293 SwNodeIndex aTmpIdx( pDoc->GetNodes().GetEndOfContent() ); 294 GetNodes()._Copy( aRg, aTmpIdx, sal_False ); 295 296 // den initialen TextNode loeschen 297 SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), 2 ); 298 if( aIdx.GetIndex() + 1 != 299 pDoc->GetNodes().GetEndOfContent().GetIndex() ) 300 pDoc->GetNodes().Delete( aIdx, 1 ); 301 302 // alle Flys in dem Bereich 303 CopyFlyInFlyImpl( aRg, 0, aIdx ); 304 305 306 // und noch alle Bookmarks 307 // ????? 308 309 utl::TempFile aTempFile2(sLeading,&sExt,&sPath ); 310 sFileName = aTempFile2.GetURL(); 311 SfxMedium* pTmpMed = new SfxMedium( sFileName, 312 STREAM_STD_READWRITE, sal_True ); 313 pTmpMed->SetFilter( pFilter ); 314 315 // fuer den HTML-Filter mussen wir aber ein Layout 316 // haben, damit Textrahmen/Controls/OLE-Objecte korrekt 317 // als Grafik exportiert werden koennen. 318 if( SPLITDOC_TO_HTML == eDocType && 319 pDoc->GetSpzFrmFmts()->Count() ) 320 { 321 /* SfxViewFrame* pFrame = */ 322 SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 ); 323 } 324 xDocSh->DoSaveAs( *pTmpMed ); 325 xDocSh->DoSaveCompleted( pTmpMed ); 326 327 // beim Fehler wird keine FileLinkSection eingefuegt 328 if( xDocSh->GetError() ) 329 sFileName.Erase(); 330 } 331 xDocSh->DoClose(); 332 } 333 334 // dann koennen ja die Bereiche eingefuegt werden 335 if( sFileName.Len() ) 336 { 337 switch( eDocType ) 338 { 339 case SPLITDOC_TO_HTML: 340 { 341 // loesche alle Nodes im Bereich und setze im "Start- 342 // Node" den Link auf das gespeicherte Doc 343 sal_uLong nNodeDiff = aEndIdx.GetIndex() - 344 pSttNd->GetIndex() - 1; 345 if( nNodeDiff ) 346 { 347 SwPaM aTmp( *pSttNd, aEndIdx.GetNode(), 1, -1 ); 348 aTmp.GetPoint()->nContent.Assign( 0, 0 ); 349 aTmp.GetMark()->nContent.Assign( 0, 0 ); 350 SwNodeIndex aSIdx( aTmp.GetMark()->nNode ); 351 SwNodeIndex aEIdx( aTmp.GetPoint()->nNode ); 352 353 // versuche hinters Ende zu verschieben 354 if( !aTmp.Move( fnMoveForward, fnGoNode ) ) 355 { 356 // na gut, dann an den Anfang 357 aTmp.Exchange(); 358 if( !aTmp.Move( fnMoveBackward, fnGoNode )) 359 { 360 ASSERT( sal_False, "kein Node mehr vorhanden" ); 361 } 362 } 363 // Bookmarks usw. verschieben 364 CorrAbs( aSIdx, aEIdx, *aTmp.GetPoint(), sal_True); 365 366 // stehen noch FlyFrames rum, loesche auch diese 367 for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n ) 368 { 369 SwFrmFmt* pFly = (*GetSpzFrmFmts())[n]; 370 const SwFmtAnchor* pAnchor = &pFly->GetAnchor(); 371 SwPosition const*const pAPos = 372 pAnchor->GetCntntAnchor(); 373 if (pAPos && 374 ((FLY_AT_PARA == pAnchor->GetAnchorId()) || 375 (FLY_AT_CHAR == pAnchor->GetAnchorId())) && 376 aSIdx <= pAPos->nNode && 377 pAPos->nNode < aEIdx ) 378 { 379 DelLayoutFmt( pFly ); 380 --n; 381 } 382 } 383 384 GetNodes().Delete( aSIdx, nNodeDiff ); 385 } 386 387 // dann setze im StartNode noch den Link: 388 SwFmtINetFmt aINet( sFileName , aEmptyStr ); 389 SwTxtNode* pTNd = (SwTxtNode*)pSttNd; 390 pTNd->InsertItem( aINet, 0, pTNd->GetTxt().Len() ); 391 392 // wenn der nicht mehr gefunden wird, kann das nur 393 // ein Bug sein! 394 if( !pOutlNds->Seek_Entry( pSttNd, &nOutl )) 395 pSttNd = 0; 396 ++nOutl; 397 } 398 break; 399 400 default: 401 { 402 String sNm( INetURLObject( sFileName ).GetName() ); 403 SwSectionData aSectData( FILE_LINK_SECTION, 404 GetUniqueSectionName( &sNm )); 405 SwSectionFmt* pFmt = MakeSectionFmt( 0 ); 406 aSectData.SetLinkFileName(sFileName); 407 aSectData.SetProtectFlag(true); 408 409 aEndIdx--; // im InsertSection ist Ende inclusive 410 while( aEndIdx.GetNode().IsStartNode() ) 411 aEndIdx--; 412 413 // JP 06.07.99 - Bug 67361 - is any Section ends or 414 // starts in the new sectionrange, they must end or 415 // start before or behind the range! 416 SwSectionNode* pSectNd = pSttNd->FindSectionNode(); 417 while( pSectNd && pSectNd->EndOfSectionIndex() 418 <= aEndIdx.GetIndex() ) 419 { 420 const SwNode* pSectEnd = pSectNd->EndOfSectionNode(); 421 if( pSectNd->GetIndex() + 1 == 422 pSttNd->GetIndex() ) 423 { 424 sal_Bool bMvIdx = aEndIdx == *pSectEnd; 425 DelSectionFmt( pSectNd->GetSection().GetFmt() ); 426 if( bMvIdx ) 427 aEndIdx--; 428 } 429 else 430 { 431 SwNodeRange aRg( *pSttNd, *pSectEnd ); 432 SwNodeIndex aIdx( *pSectEnd, 1 ); 433 GetNodes()._MoveNodes( aRg, GetNodes(), aIdx ); 434 } 435 pSectNd = pSttNd->FindSectionNode(); 436 } 437 438 pSectNd = aEndIdx.GetNode().FindSectionNode(); 439 while( pSectNd && pSectNd->GetIndex() > 440 pSttNd->GetIndex() ) 441 { 442 // #i15712# don't attempt to split sections if 443 // they are fully enclosed in [pSectNd,aEndIdx]. 444 if( aEndIdx < pSectNd->EndOfSectionIndex() ) 445 { 446 SwNodeRange aRg( *pSectNd, 1, aEndIdx, 1 ); 447 SwNodeIndex aIdx( *pSectNd ); 448 GetNodes()._MoveNodes( aRg, GetNodes(), aIdx ); 449 } 450 451 pSectNd = pSttNd->FindSectionNode(); 452 } 453 454 // -> #i26762# 455 // Ensure order of start and end of section is sane. 456 SwNodeIndex aStartIdx(*pSttNd); 457 458 if (aEndIdx >= aStartIdx) 459 { 460 pSectNd = GetNodes().InsertTextSection(aStartIdx, 461 *pFmt, aSectData, 0, &aEndIdx, false); 462 } 463 else 464 { 465 pSectNd = GetNodes().InsertTextSection(aEndIdx, 466 *pFmt, aSectData, 0, &aStartIdx, false); 467 } 468 // <- #i26762# 469 470 pSectNd->GetSection().CreateLink( CREATE_CONNECT ); 471 } 472 break; 473 } 474 } 475 } 476 } while( pSttNd ); 477 478 // if( pOutlNds != (SwOutlineNodes*)&GetNodes().GetOutLineNds(); 479 if( pOutlNds != &GetNodes().GetOutLineNds() ) 480 delete pOutlNds; 481 482 switch( eDocType ) 483 { 484 case SPLITDOC_TO_HTML: 485 if( get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 486 { 487 // dann alles verbliebenen Bereiche aufheben 488 while( GetSections().Count() ) 489 DelSectionFmt( GetSections()[ 0 ] ); 490 491 SfxFilterContainer* pFCntnr = pDocShell->GetFactory().GetFilterContainer(); 492 pFilter = pFCntnr->GetFilter4EA( pFilter->GetTypeName(), SFX_FILTER_EXPORT ); 493 } 494 break; 495 496 // case SPLITDOC_TO_GLOBALDOC: 497 default: 498 // dann das Globaldoc speichern 499 set(IDocumentSettingAccess::GLOBAL_DOCUMENT, true); 500 set(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS, false); 501 } 502 503 // Medium istn't locked after reopen the document. Bug 91462 504 SfxRequest aReq( SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON, GetAttrPool() ); 505 aReq.AppendItem( SfxStringItem( SID_FILE_NAME, rPath ) ); 506 aReq.AppendItem( SfxBoolItem( SID_SAVETO, sal_True ) ); 507 if(pFilter) 508 aReq.AppendItem( SfxStringItem( SID_FILTER_NAME, pFilter->GetName() ) ); 509 const SfxBoolItem *pRet = (const SfxBoolItem*)pDocShell->ExecuteSlot( aReq ); 510 511 return pRet && pRet->GetValue(); 512 } 513 514 //#outline level,add by zhaojianwei 515 sal_Bool SwDoc::SplitDoc( sal_uInt16 eDocType, const String& rPath, int nOutlineLevel ) 516 { 517 if( !pDocShell || !pDocShell->GetMedium() || 518 ( SPLITDOC_TO_GLOBALDOC == eDocType && get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) ) 519 return sal_False; 520 521 sal_uInt16 nOutl = 0; 522 SwOutlineNodes* pOutlNds = (SwOutlineNodes*)&GetNodes().GetOutLineNds(); 523 SwNodePtr pSttNd; 524 525 const SfxFilter* pFilter; 526 switch( eDocType ) 527 { 528 case SPLITDOC_TO_HTML: 529 pFilter = SwIoSystem::GetFilterOfFormat( String::CreateFromAscii( 530 RTL_CONSTASCII_STRINGPARAM( "HTML" ))); 531 break; 532 533 default: 534 // case SPLITDOC_TO_GLOBALDOC: 535 pFilter = SwIoSystem::GetFilterOfFormat( 536 String::CreateFromAscii( FILTER_XML )); 537 eDocType = SPLITDOC_TO_GLOBALDOC; 538 break; 539 } 540 541 if( !pFilter ) 542 return sal_False; 543 544 // Undo/Redline aufjedenfall abschalten 545 GetIDocumentUndoRedo().DoUndo(false); 546 SetRedlineMode_intern( (RedlineMode_t)(GetRedlineMode() & ~nsRedlineMode_t::REDLINE_ON)); 547 548 String sExt( pFilter->GetSuffixes().GetToken(0, ',') ); 549 if( !sExt.Len() ) 550 sExt.AssignAscii( "sxw" ); 551 if( '.' != sExt.GetChar( 0 ) ) 552 sExt.Insert( '.', 0 ); 553 554 INetURLObject aEntry(rPath); 555 String sLeading(aEntry.GetBase()); 556 aEntry.removeSegment(); 557 String sPath = aEntry.GetMainURL( INetURLObject::NO_DECODE ); 558 utl::TempFile aTemp(sLeading,&sExt,&sPath ); 559 aTemp.EnableKillingFile(); 560 561 DateTime aTmplDate; 562 { 563 Time a2Min( 0 ); a2Min.SetMin( 2 ); 564 aTmplDate += a2Min; 565 } 566 567 568 // alle Ungueltigen ueberspringen 569 while( nOutl < pOutlNds->Count() && 570 pOutlNds->GetObject( nOutl )->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) 571 ++nOutl; 572 573 do { 574 pSttNd = 0; 575 576 SwNodePtr pNd; 577 for( ; nOutl < pOutlNds->Count(); ++nOutl ) 578 if( ( pNd = pOutlNds->GetObject( nOutl ))->GetTxtNode()->GetAttrOutlineLevel() == nOutlineLevel && 579 !pNd->FindTableNode() ) 580 { 581 pSttNd = pNd; 582 break; 583 } 584 585 if( pSttNd ) 586 { 587 SwNodePtr pEndNd = 0; 588 for( ++nOutl; nOutl < pOutlNds->Count(); ++nOutl ) 589 { 590 pNd = pOutlNds->GetObject( nOutl ); 591 592 const int nLevel = pNd->GetTxtNode()->GetAttrOutlineLevel(); 593 594 if( ( 0 < nLevel && nLevel <= nOutlineLevel ) && 595 !pNd->FindTableNode() ) 596 { 597 pEndNd = pNd; 598 599 break; 600 } 601 } 602 SwNodeIndex aEndIdx( pEndNd ? *pEndNd 603 : GetNodes().GetEndOfContent() ); 604 605 String sFileName; 606 if( pSttNd->GetIndex() + 1 < aEndIdx.GetIndex() ) 607 { 608 SfxObjectShellLock xDocSh( new SwDocShell( SFX_CREATE_MODE_INTERNAL )); 609 if( xDocSh->DoInitNew( 0 ) ) 610 { 611 SwDoc* pDoc = ((SwDocShell*)(&xDocSh))->GetDoc(); 612 613 uno::Reference<document::XDocumentPropertiesSupplier> xDPS( 614 ((SwDocShell*)(&xDocSh))->GetModel(), 615 uno::UNO_QUERY_THROW); 616 uno::Reference<document::XDocumentProperties> xDocProps( 617 xDPS->getDocumentProperties()); 618 DBG_ASSERT(xDocProps.is(), "Doc has no DocumentProperties"); 619 // the GlobalDoc is the template 620 xDocProps->setTemplateName(aEmptyStr); 621 ::util::DateTime uDT(aTmplDate.Get100Sec(), 622 aTmplDate.GetSec(), aTmplDate.GetMin(), 623 aTmplDate.GetHour(), aTmplDate.GetDay(), 624 aTmplDate.GetMonth(), aTmplDate.GetYear()); 625 xDocProps->setTemplateDate(uDT); 626 xDocProps->setTemplateURL(rPath); 627 //JP 14.06.99: Set the text of the "split para" as title 628 // from the new doc. Is the current doc has 629 // a title, insert it at begin. 630 String sTitle( xDocProps->getTitle() ); 631 if( sTitle.Len() ) 632 sTitle.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ": " )); 633 sTitle += ((SwTxtNode*)pSttNd)->GetExpandTxt(); 634 xDocProps->setTitle( sTitle ); 635 636 // Vorlagen ersetzen 637 pDoc->ReplaceStyles( *this ); 638 639 // KapitelNumerierung uebernehmen 640 if( pOutlineRule ) 641 pDoc->SetOutlineNumRule( *pOutlineRule ); 642 643 SwNodeRange aRg( *pSttNd, 0, aEndIdx.GetNode() ); 644 SwNodeIndex aTmpIdx( pDoc->GetNodes().GetEndOfContent() ); 645 GetNodes()._Copy( aRg, aTmpIdx, sal_False ); 646 647 // den initialen TextNode loeschen 648 SwNodeIndex aIdx( pDoc->GetNodes().GetEndOfExtras(), 2 ); 649 if( aIdx.GetIndex() + 1 != 650 pDoc->GetNodes().GetEndOfContent().GetIndex() ) 651 pDoc->GetNodes().Delete( aIdx, 1 ); 652 653 // alle Flys in dem Bereich 654 CopyFlyInFlyImpl( aRg, 0, aIdx ); 655 656 657 // und noch alle Bookmarks 658 // ????? 659 660 utl::TempFile aTempFile2(sLeading,&sExt,&sPath ); 661 sFileName = aTempFile2.GetURL(); 662 SfxMedium* pTmpMed = new SfxMedium( sFileName, 663 STREAM_STD_READWRITE, sal_True ); 664 pTmpMed->SetFilter( pFilter ); 665 666 // fuer den HTML-Filter mussen wir aber ein Layout 667 // haben, damit Textrahmen/Controls/OLE-Objecte korrekt 668 // als Grafik exportiert werden koennen. 669 if( SPLITDOC_TO_HTML == eDocType && 670 pDoc->GetSpzFrmFmts()->Count() ) 671 { 672 /* SfxViewFrame* pFrame = */ 673 SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 ); 674 } 675 xDocSh->DoSaveAs( *pTmpMed ); 676 xDocSh->DoSaveCompleted( pTmpMed ); 677 678 // beim Fehler wird keine FileLinkSection eingefuegt 679 if( xDocSh->GetError() ) 680 sFileName.Erase(); 681 } 682 xDocSh->DoClose(); 683 } 684 685 // dann koennen ja die Bereiche eingefuegt werden 686 if( sFileName.Len() ) 687 { 688 switch( eDocType ) 689 { 690 case SPLITDOC_TO_HTML: 691 { 692 // loesche alle Nodes im Bereich und setze im "Start- 693 // Node" den Link auf das gespeicherte Doc 694 sal_uLong nNodeDiff = aEndIdx.GetIndex() - 695 pSttNd->GetIndex() - 1; 696 if( nNodeDiff ) 697 { 698 SwPaM aTmp( *pSttNd, aEndIdx.GetNode(), 1, -1 ); 699 aTmp.GetPoint()->nContent.Assign( 0, 0 ); 700 aTmp.GetMark()->nContent.Assign( 0, 0 ); 701 SwNodeIndex aSIdx( aTmp.GetMark()->nNode ); 702 SwNodeIndex aEIdx( aTmp.GetPoint()->nNode ); 703 704 // versuche hinters Ende zu verschieben 705 if( !aTmp.Move( fnMoveForward, fnGoNode ) ) 706 { 707 // na gut, dann an den Anfang 708 aTmp.Exchange(); 709 if( !aTmp.Move( fnMoveBackward, fnGoNode )) 710 { 711 ASSERT( sal_False, "kein Node mehr vorhanden" ); 712 } 713 } 714 // Bookmarks usw. verschieben 715 CorrAbs( aSIdx, aEIdx, *aTmp.GetPoint(), sal_True); 716 717 // stehen noch FlyFrames rum, loesche auch diese 718 for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n ) 719 { 720 SwFrmFmt* pFly = (*GetSpzFrmFmts())[n]; 721 const SwFmtAnchor* pAnchor = &pFly->GetAnchor(); 722 SwPosition const*const pAPos = 723 pAnchor->GetCntntAnchor(); 724 if (pAPos && 725 ((FLY_AT_PARA == pAnchor->GetAnchorId()) || 726 (FLY_AT_CHAR == pAnchor->GetAnchorId())) && 727 aSIdx <= pAPos->nNode && 728 pAPos->nNode < aEIdx ) 729 { 730 DelLayoutFmt( pFly ); 731 --n; 732 } 733 } 734 735 GetNodes().Delete( aSIdx, nNodeDiff ); 736 } 737 738 // dann setze im StartNode noch den Link: 739 SwFmtINetFmt aINet( sFileName , aEmptyStr ); 740 SwTxtNode* pTNd = (SwTxtNode*)pSttNd; 741 pTNd->InsertItem( aINet, 0, pTNd->GetTxt().Len() ); 742 743 // wenn der nicht mehr gefunden wird, kann das nur 744 // ein Bug sein! 745 if( !pOutlNds->Seek_Entry( pSttNd, &nOutl )) 746 pSttNd = 0; 747 ++nOutl; 748 } 749 break; 750 751 default: 752 { 753 String sNm( INetURLObject( sFileName ).GetName() ); 754 SwSectionData aSectData( FILE_LINK_SECTION, 755 GetUniqueSectionName( &sNm )); 756 SwSectionFmt* pFmt = MakeSectionFmt( 0 ); 757 aSectData.SetLinkFileName(sFileName); 758 aSectData.SetProtectFlag(true); 759 760 aEndIdx--; // im InsertSection ist Ende inclusive 761 while( aEndIdx.GetNode().IsStartNode() ) 762 aEndIdx--; 763 764 // JP 06.07.99 - Bug 67361 - is any Section ends or 765 // starts in the new sectionrange, they must end or 766 // start before or behind the range! 767 SwSectionNode* pSectNd = pSttNd->FindSectionNode(); 768 while( pSectNd && pSectNd->EndOfSectionIndex() 769 <= aEndIdx.GetIndex() ) 770 { 771 const SwNode* pSectEnd = pSectNd->EndOfSectionNode(); 772 if( pSectNd->GetIndex() + 1 == 773 pSttNd->GetIndex() ) 774 { 775 sal_Bool bMvIdx = aEndIdx == *pSectEnd; 776 DelSectionFmt( pSectNd->GetSection().GetFmt() ); 777 if( bMvIdx ) 778 aEndIdx--; 779 } 780 else 781 { 782 SwNodeRange aRg( *pSttNd, *pSectEnd ); 783 SwNodeIndex aIdx( *pSectEnd, 1 ); 784 GetNodes()._MoveNodes( aRg, GetNodes(), aIdx ); 785 } 786 pSectNd = pSttNd->FindSectionNode(); 787 } 788 789 pSectNd = aEndIdx.GetNode().FindSectionNode(); 790 while( pSectNd && pSectNd->GetIndex() > 791 pSttNd->GetIndex() ) 792 { 793 if( aEndIdx < pSectNd->EndOfSectionIndex() ) 794 { 795 SwNodeRange aRg( *pSectNd, 1, aEndIdx, 1 ); 796 SwNodeIndex aIdx( *pSectNd ); 797 GetNodes()._MoveNodes( aRg, GetNodes(), aIdx ); 798 } 799 800 pSectNd = pSttNd->FindSectionNode(); 801 } 802 803 SwNodeIndex aStartIdx(*pSttNd); 804 805 if (aEndIdx >= aStartIdx) 806 { 807 pSectNd = GetNodes().InsertTextSection(aStartIdx, 808 *pFmt, aSectData, 0, &aEndIdx, false); 809 } 810 else 811 { 812 pSectNd = GetNodes().InsertTextSection(aEndIdx, 813 *pFmt, aSectData, 0, &aStartIdx, false); 814 } 815 816 pSectNd->GetSection().CreateLink( CREATE_CONNECT ); 817 } 818 break; 819 } 820 } 821 } 822 } while( pSttNd ); 823 824 if( pOutlNds != &GetNodes().GetOutLineNds() ) 825 delete pOutlNds; 826 827 switch( eDocType ) 828 { 829 case SPLITDOC_TO_HTML: 830 if( get(IDocumentSettingAccess::GLOBAL_DOCUMENT) ) 831 { 832 while( GetSections().Count() ) 833 DelSectionFmt( GetSections()[ 0 ] ); 834 835 SfxFilterContainer* pFCntnr = pDocShell->GetFactory().GetFilterContainer(); 836 pFilter = pFCntnr->GetFilter4EA( pFilter->GetTypeName(), SFX_FILTER_EXPORT ); 837 } 838 break; 839 840 // case SPLITDOC_TO_GLOBALDOC: 841 default: 842 set(IDocumentSettingAccess::GLOBAL_DOCUMENT, true); 843 set(IDocumentSettingAccess::GLOBAL_DOCUMENT_SAVE_LINKS, false); 844 } 845 846 SfxRequest aReq( SID_SAVEASDOC, SFX_CALLMODE_SYNCHRON, GetAttrPool() ); 847 aReq.AppendItem( SfxStringItem( SID_FILE_NAME, rPath ) ); 848 aReq.AppendItem( SfxBoolItem( SID_SAVETO, sal_True ) ); 849 if(pFilter) 850 aReq.AppendItem( SfxStringItem( SID_FILTER_NAME, pFilter->GetName() ) ); 851 const SfxBoolItem *pRet = (const SfxBoolItem*)pDocShell->ExecuteSlot( aReq ); 852 853 return pRet && pRet->GetValue(); 854 }//<-end,zhaojianwei 855 856