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