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