xref: /trunk/main/sw/source/core/doc/docglbl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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