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