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