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