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