xref: /AOO41X/main/sw/source/core/doc/doclay.cxx (revision 7b6b9ddb4b63a97ea0214b9472b5270bbf674949)
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 #include <unotools/linguprops.hxx>
28 #include <unotools/lingucfg.hxx>
29 #include <com/sun/star/embed/EmbedStates.hpp>
30 #include <hintids.hxx>
31 #include <com/sun/star/util/XCloseable.hpp>
32 #include <sfx2/progress.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdpage.hxx>
35 #include <editeng/keepitem.hxx>
36 #include <editeng/ulspitem.hxx>
37 #include <editeng/lrspitem.hxx>
38 #include <editeng/boxitem.hxx>
39 #include <editeng/shaditem.hxx>
40 #include <editeng/protitem.hxx>
41 #include <editeng/opaqitem.hxx>
42 #include <editeng/prntitem.hxx>
43 #include <svx/fmglob.hxx>
44 #include <svx/svdouno.hxx>
45 #include <svx/fmpage.hxx>
46 #include <editeng/frmdiritem.hxx>
47 
48 #include <swmodule.hxx>
49 #include <modcfg.hxx>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <rtl/logfile.hxx>
52 #include <SwStyleNameMapper.hxx>
53 #include <fchrfmt.hxx>
54 #include <errhdl.hxx>
55 #include <frmatr.hxx>
56 #include <txatbase.hxx>
57 #include <fmtfld.hxx>
58 #include <fmtornt.hxx>
59 #include <fmtcntnt.hxx>
60 #include <fmtanchr.hxx>
61 #include <fmtfsize.hxx>
62 #include <fmtsrnd.hxx>
63 #include <fmtflcnt.hxx>
64 #include <fmtcnct.hxx>
65 #include <frmfmt.hxx>
66 #include <dcontact.hxx>
67 #include <txtflcnt.hxx>
68 #include <docfld.hxx>   // fuer Expression-Felder
69 #include <pam.hxx>
70 #include <ndtxt.hxx>
71 #include <ndnotxt.hxx>
72 #include <ndole.hxx>
73 #include <doc.hxx>
74 #include <IDocumentUndoRedo.hxx>
75 #include <rootfrm.hxx>
76 #include <pagefrm.hxx>
77 #include <cntfrm.hxx>
78 #include <flyfrm.hxx>
79 #include <fesh.hxx>
80 #include <docsh.hxx>
81 #include <dflyobj.hxx>
82 #include <dcontact.hxx>
83 #include <swundo.hxx>
84 #include <flypos.hxx>
85 #include <UndoInsert.hxx>
86 #include <expfld.hxx>       // InsertLabel
87 #include <poolfmt.hxx>      // PoolVorlagen-Id's
88 #include <docary.hxx>
89 #include <swtable.hxx>
90 #include <tblsel.hxx>
91 #include <viewopt.hxx>
92 #include <fldupde.hxx>
93 #include <txtftn.hxx>
94 #include <ftnidx.hxx>
95 #include <ftninfo.hxx>
96 #include <pagedesc.hxx>
97 #include <PostItMgr.hxx>
98 #include <comcore.hrc>      // STR-ResId's
99 
100 // #i11176#
101 #include <unoframe.hxx>
102 // OD 2004-05-24 #i28701#
103 #include <sortedobjs.hxx>
104 
105 // --> OD 2004-07-26 #i32089#
106 #include <vector>
107 // <--
108 
109 using namespace ::com::sun::star;
110 using ::rtl::OUString;
111 
112 #define DEF_FLY_WIDTH    2268   //Defaultbreite fuer FlyFrms    (2268 == 4cm)
113 
114 /* #109161# */
115 static bool lcl_IsItemSet(const SwCntntNode & rNode, sal_uInt16 which)
116 {
117     bool bResult = false;
118 
119     if (SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(which))
120         bResult = true;
121 
122     return bResult;
123 }
124 
125 /*************************************************************************
126 |*
127 |*  SwDoc::MakeLayoutFmt()
128 |*
129 |*  Beschreibung        Erzeugt ein neues Format das in seinen Einstellungen
130 |*      Defaultmaessig zu dem Request passt. Das Format wird in das
131 |*      entsprechende Formate-Array gestellt.
132 |*      Wenn bereits ein passendes Format existiert, so wird dies
133 |*      zurueckgeliefert.
134 |*  Ersterstellung      MA 22. Sep. 92
135 |*  Letzte Aenderung    JP 08.05.98
136 |*
137 |*************************************************************************/
138 
139 SwFrmFmt *SwDoc::MakeLayoutFmt( RndStdIds eRequest, const SfxItemSet* pSet )
140 {
141     SwFrmFmt *pFmt = 0;
142     const sal_Bool bMod = IsModified();
143     sal_Bool bHeader = sal_False;
144 
145     switch ( eRequest )
146     {
147     case RND_STD_HEADER:
148     case RND_STD_HEADERL:
149     case RND_STD_HEADERR:
150         {
151             bHeader = sal_True;
152             // kein break, es geht unten weiter
153         }
154     case RND_STD_FOOTER:
155     case RND_STD_FOOTERL:
156     case RND_STD_FOOTERR:
157         {
158             pFmt = new SwFrmFmt( GetAttrPool(),
159                                  (bHeader ? "Header" : "Footer"),
160                                  GetDfltFrmFmt() );
161 
162             SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() );
163             SwStartNode* pSttNd =
164                 GetNodes().MakeTextSection
165                 ( aTmpIdx,
166                   bHeader ? SwHeaderStartNode : SwFooterStartNode,
167                   GetTxtCollFromPool(static_cast<sal_uInt16>( bHeader
168                                      ? ( eRequest == RND_STD_HEADERL
169                                          ? RES_POOLCOLL_HEADERL
170                                          : eRequest == RND_STD_HEADERR
171                                          ? RES_POOLCOLL_HEADERR
172                                          : RES_POOLCOLL_HEADER )
173                                      : ( eRequest == RND_STD_FOOTERL
174                                          ? RES_POOLCOLL_FOOTERL
175                                          : eRequest == RND_STD_FOOTERR
176                                          ? RES_POOLCOLL_FOOTERR
177                                          : RES_POOLCOLL_FOOTER )
178                                      ) ) );
179             pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
180 
181             if( pSet )      // noch ein paar Attribute setzen ?
182                 pFmt->SetFmtAttr( *pSet );
183 
184             // JP: warum zuruecksetzen ???  Doc. ist doch veraendert ???
185             // bei den Fly auf jedenfall verkehrt !!
186             if ( !bMod )
187                 ResetModified();
188         }
189         break;
190 
191     case RND_DRAW_OBJECT:
192         {
193             pFmt = MakeDrawFrmFmt( aEmptyStr, GetDfltFrmFmt() );
194             if( pSet )      // noch ein paar Attribute setzen ?
195                 pFmt->SetFmtAttr( *pSet );
196 
197             if (GetIDocumentUndoRedo().DoesUndo())
198             {
199                 GetIDocumentUndoRedo().AppendUndo(
200                     new SwUndoInsLayFmt(pFmt, 0, 0));
201             }
202         }
203         break;
204 
205 #ifdef DBG_UTIL
206     case FLY_AT_PAGE:
207     case FLY_AT_CHAR:
208     case FLY_AT_FLY:
209     case FLY_AT_PARA:
210     case FLY_AS_CHAR:
211         ASSERT( false, "use new interface instead: SwDoc::MakeFlySection!" );
212         break;
213 #endif
214 
215     default:
216         ASSERT( !this,
217                 "Layoutformat mit ungueltigem Request angefordert." );
218 
219     }
220     return pFmt;
221 }
222 /*************************************************************************
223 |*
224 |*  SwDoc::DelLayoutFmt()
225 |*
226 |*  Beschreibung        Loescht das angegebene Format, der Inhalt wird mit
227 |*      geloescht.
228 |*  Ersterstellung      MA 23. Sep. 92
229 |*  Letzte Aenderung    MA 05. Feb. 93
230 |*
231 |*************************************************************************/
232 
233 void SwDoc::DelLayoutFmt( SwFrmFmt *pFmt )
234 {
235     //Verkettung von Rahmen muss ggf. zusammengefuehrt werden.
236     //Bevor die Frames vernichtet werden, damit die Inhalte der Rahmen
237     //ggf. entsprechend gerichtet werden.
238     const SwFmtChain &rChain = pFmt->GetChain();
239     if ( rChain.GetPrev() )
240     {
241         SwFmtChain aChain( rChain.GetPrev()->GetChain() );
242         aChain.SetNext( rChain.GetNext() );
243         SetAttr( aChain, *rChain.GetPrev() );
244     }
245     if ( rChain.GetNext() )
246     {
247         SwFmtChain aChain( rChain.GetNext()->GetChain() );
248         aChain.SetPrev( rChain.GetPrev() );
249         SetAttr( aChain, *rChain.GetNext() );
250     }
251 
252     const SwNodeIndex* pCntIdx = pFmt->GetCntnt().GetCntntIdx();
253     if (pCntIdx && !GetIDocumentUndoRedo().DoesUndo())
254     {
255         //Verbindung abbauen, falls es sich um ein OLE-Objekt handelt.
256         SwOLENode* pOLENd = GetNodes()[ pCntIdx->GetIndex()+1 ]->GetOLENode();
257         if( pOLENd && pOLENd->GetOLEObj().IsOleRef() )
258         {
259             /*
260             SwDoc* pDoc = (SwDoc*)pFmt->GetDoc();
261             if( pDoc )
262             {
263                 SfxObjectShell* p = pDoc->GetPersist();
264                 if( p )     // muss da sein
265                 {
266                     SvInfoObjectRef aRef( p->Find( pOLENd->GetOLEObj().GetName() ) );
267                     if( aRef.Is() )
268                         aRef->SetObj(0);
269                 }
270             } */
271 
272             // TODO/MBA: the old object closed the object, cleared all references to it, but didn't remove it from the container.
273             // I have no idea, why, nobody could explain it - so I do my very best to mimic this behavior
274             //uno::Reference < util::XCloseable > xClose( pOLENd->GetOLEObj().GetOleRef(), uno::UNO_QUERY );
275             //if ( xClose.is() )
276             {
277                 try
278                 {
279                     pOLENd->GetOLEObj().GetOleRef()->changeState( embed::EmbedStates::LOADED );
280                 }
281                 catch ( uno::Exception& )
282                 {
283                 }
284             }
285 
286             //pOLENd->GetOLEObj().GetOleRef() = 0;
287         }
288     }
289 
290     //Frms vernichten.
291     pFmt->DelFrms();
292 
293     // erstmal sind nur Fly's Undofaehig
294     const sal_uInt16 nWh = pFmt->Which();
295     if (GetIDocumentUndoRedo().DoesUndo() &&
296         (RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh))
297     {
298         GetIDocumentUndoRedo().AppendUndo( new SwUndoDelLayFmt( pFmt ));
299     }
300     else
301     {
302         // --> OD 2004-07-26 #i32089# - delete at-frame anchored objects
303         if ( nWh == RES_FLYFRMFMT )
304         {
305             // determine frame formats of at-frame anchored objects
306             const SwNodeIndex* pCntntIdx = pFmt->GetCntnt().GetCntntIdx();
307             if ( pCntntIdx )
308             {
309                 const SwSpzFrmFmts* pTbl = pFmt->GetDoc()->GetSpzFrmFmts();
310                 if ( pTbl )
311                 {
312                     std::vector<SwFrmFmt*> aToDeleteFrmFmts;
313                     const sal_uLong nNodeIdxOfFlyFmt( pCntntIdx->GetIndex() );
314 
315                     for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
316                     {
317                         SwFrmFmt* pTmpFmt = (*pTbl)[i];
318                         const SwFmtAnchor &rAnch = pTmpFmt->GetAnchor();
319                         if ( rAnch.GetAnchorId() == FLY_AT_FLY &&
320                              rAnch.GetCntntAnchor()->nNode.GetIndex() == nNodeIdxOfFlyFmt )
321                         {
322                             aToDeleteFrmFmts.push_back( pTmpFmt );
323                         }
324                     }
325 
326                     // delete found frame formats
327                     while ( !aToDeleteFrmFmts.empty() )
328                     {
329                         SwFrmFmt* pTmpFmt = aToDeleteFrmFmts.back();
330                         pFmt->GetDoc()->DelLayoutFmt( pTmpFmt );
331 
332                         aToDeleteFrmFmts.pop_back();
333                     }
334                 }
335             }
336         }
337         // <--
338 
339         //Inhalt Loeschen.
340         if( pCntIdx )
341         {
342             SwNode *pNode = &pCntIdx->GetNode();
343             ((SwFmtCntnt&)pFmt->GetFmtAttr( RES_CNTNT )).SetNewCntntIdx( 0 );
344             DeleteSection( pNode );
345         }
346 
347         // ggfs. bei Zeichengebundenen Flys das Zeichen loeschen
348         const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
349         if ((FLY_AS_CHAR == rAnchor.GetAnchorId()) && rAnchor.GetCntntAnchor())
350         {
351             const SwPosition* pPos = rAnchor.GetCntntAnchor();
352             SwTxtNode *pTxtNd = pPos->nNode.GetNode().GetTxtNode();
353 
354             // attribute is still in text node, delete it
355             if ( pTxtNd )
356             {
357                 SwTxtFlyCnt* const pAttr = static_cast<SwTxtFlyCnt*>(
358                     pTxtNd->GetTxtAttrForCharAt( pPos->nContent.GetIndex(),
359                         RES_TXTATR_FLYCNT ));
360                 if ( pAttr && (pAttr->GetFlyCnt().GetFrmFmt() == pFmt) )
361                 {
362                     // dont delete, set pointer to 0
363                     const_cast<SwFmtFlyCnt&>(pAttr->GetFlyCnt()).SetFlyFmt();
364                     SwIndex aIdx( pPos->nContent );
365                     pTxtNd->EraseText( aIdx, 1 );
366                 }
367             }
368         }
369 
370         DelFrmFmt( pFmt );
371     }
372     SetModified();
373 }
374 
375 /*************************************************************************
376 |*
377 |*  SwDoc::CopyLayoutFmt()
378 |*
379 |*  Beschreibung        Kopiert das angegebene Format pSrc in pDest und
380 |*                      returnt pDest. Wenn es noch kein pDest gibt, wird
381 |*                      eins angelegt.
382 |*                      JP: steht das Source Format in einem anderen
383 |*                          Dokument, so kopiere auch dann noch richtig !!
384 |*                          Vom chaos::Anchor-Attribut wird die Position immer
385 |*                          auf 0 gesetzt !!!
386 |*
387 |*  Ersterstellung      BP 18.12.92
388 |*  Letzte Aenderung    MA 17. Jul. 96
389 |*
390 |*************************************************************************/
391 
392 SwFrmFmt *SwDoc::CopyLayoutFmt( const SwFrmFmt& rSource,
393                                 const SwFmtAnchor& rNewAnchor,
394                                 bool bSetTxtFlyAtt, bool bMakeFrms )
395 {
396     const bool bFly = RES_FLYFRMFMT == rSource.Which();
397     const bool bDraw = RES_DRAWFRMFMT == rSource.Which();
398     ASSERT( bFly || bDraw, "this method only works for fly or draw" );
399 
400     SwDoc* pSrcDoc = (SwDoc*)rSource.GetDoc();
401 
402     // #108784# may we copy this object?
403     // We may, unless it's 1) it's a control (and therfore a draw)
404     //                     2) anchored in a header/footer
405     //                     3) anchored (to paragraph?)
406     bool bMayNotCopy = false;
407     if( bDraw )
408     {
409         const SwDrawContact* pDrawContact =
410             static_cast<const SwDrawContact*>( rSource.FindContactObj() );
411 
412         bMayNotCopy =
413             ((FLY_AT_PARA == rNewAnchor.GetAnchorId()) ||
414              (FLY_AT_FLY  == rNewAnchor.GetAnchorId()) ||
415              (FLY_AT_CHAR == rNewAnchor.GetAnchorId())) &&
416             rNewAnchor.GetCntntAnchor() &&
417             IsInHeaderFooter( rNewAnchor.GetCntntAnchor()->nNode ) &&
418             pDrawContact != NULL  &&
419             pDrawContact->GetMaster() != NULL  &&
420             CheckControlLayer( pDrawContact->GetMaster() );
421     }
422 
423     // just return if we can't copy this
424     if( bMayNotCopy )
425         return NULL;
426 
427     SwFrmFmt* pDest = GetDfltFrmFmt();
428     if( rSource.GetRegisteredIn() != pSrcDoc->GetDfltFrmFmt() )
429         pDest = CopyFrmFmt( *(SwFrmFmt*)rSource.GetRegisteredIn() );
430     if( bFly )
431     {
432         // #i11176#
433         // To do a correct cloning concerning the ZOrder for all objects
434         // it is necessary to actually create a draw object for fly frames, too.
435         // These are then added to the DrawingLayer (which needs to exist).
436         // Together with correct sorting of all drawinglayer based objects
437         // before cloning ZOrder transfer works correctly then.
438         SwFlyFrmFmt *pFormat = MakeFlyFrmFmt( rSource.GetName(), pDest );
439         pDest = pFormat;
440 
441         SwXFrame::GetOrCreateSdrObject(pFormat);
442     }
443     else
444         pDest = MakeDrawFrmFmt( aEmptyStr, pDest );
445 
446     // alle anderen/neue Attribute kopieren.
447     pDest->CopyAttrs( rSource );
448 
449     //Chains werden nicht kopiert.
450     pDest->ResetFmtAttr( RES_CHAIN );
451 
452     if( bFly )
453     {
454         //Der Inhalt wird dupliziert.
455         const SwNode& rCSttNd = rSource.GetCntnt().GetCntntIdx()->GetNode();
456         SwNodeRange aRg( rCSttNd, 1, *rCSttNd.EndOfSectionNode() );
457 
458         SwNodeIndex aIdx( GetNodes().GetEndOfAutotext() );
459         SwStartNode* pSttNd = GetNodes().MakeEmptySection( aIdx, SwFlyStartNode );
460 
461         // erst den chaos::Anchor/CntntIndex setzen, innerhalb des Kopierens
462         // auf die Werte zugegriffen werden kann (DrawFmt in Kopf-/Fusszeilen)
463         aIdx = *pSttNd;
464         SwFmtCntnt aAttr( rSource.GetCntnt() );
465         aAttr.SetNewCntntIdx( &aIdx );
466         pDest->SetFmtAttr( aAttr );
467         pDest->SetFmtAttr( rNewAnchor );
468 
469         if( !mbCopyIsMove || this != pSrcDoc )
470         {
471             if( mbInReading )
472                 pDest->SetName( aEmptyStr );
473             else
474             {
475                 // Teste erstmal ob der Name schon vergeben ist.
476                 // Wenn ja -> neuen generieren
477                 sal_Int8 nNdTyp = aRg.aStart.GetNode().GetNodeType();
478 
479                 String sOld( pDest->GetName() );
480                 pDest->SetName( aEmptyStr );
481                 if( FindFlyByName( sOld, nNdTyp ) )     // einen gefunden
482                     switch( nNdTyp )
483                     {
484                     case ND_GRFNODE:    sOld = GetUniqueGrfName();      break;
485                     case ND_OLENODE:    sOld = GetUniqueOLEName();      break;
486                     default:            sOld = GetUniqueFrameName();    break;
487                     }
488 
489                 pDest->SetName( sOld );
490             }
491         }
492 
493         if (GetIDocumentUndoRedo().DoesUndo())
494         {
495             GetIDocumentUndoRedo().AppendUndo(new SwUndoInsLayFmt(pDest,0,0));
496         }
497 
498         // sorge dafuer das auch Fly's in Fly's kopiert werden
499         aIdx = *pSttNd->EndOfSectionNode();
500         pSrcDoc->CopyWithFlyInFly( aRg, 0, aIdx, sal_False, sal_True, sal_True );
501     }
502     else
503     {
504         ASSERT( RES_DRAWFRMFMT == rSource.Which(), "Weder Fly noch Draw." );
505         // OD 2005-08-02 #i52780# - Note: moving object to visible layer not needed.
506         SwDrawContact* pSourceContact = (SwDrawContact *)rSource.FindContactObj();
507 
508         SwDrawContact* pContact = new SwDrawContact( (SwDrawFrmFmt*)pDest,
509                                 CloneSdrObj( *pSourceContact->GetMaster(),
510                                         mbCopyIsMove && this == pSrcDoc ) );
511         // --> OD 2005-05-23 #i49730# - notify draw frame format
512         // that position attributes are already set, if the position attributes
513         // are already set at the source draw frame format.
514         if ( pDest->ISA(SwDrawFrmFmt) &&
515              rSource.ISA(SwDrawFrmFmt) &&
516              static_cast<const SwDrawFrmFmt&>(rSource).IsPosAttrSet() )
517         {
518             static_cast<SwDrawFrmFmt*>(pDest)->PosAttrSet();
519         }
520         // <--
521 
522         if( pDest->GetAnchor() == rNewAnchor )
523         {
524             // OD 03.07.2003 #108784# - do *not* connect to layout, if
525             // a <MakeFrms> will not be called.
526             if ( bMakeFrms )
527             {
528                 pContact->ConnectToLayout( &rNewAnchor );
529             }
530         }
531         else
532             pDest->SetFmtAttr( rNewAnchor );
533 
534         if (GetIDocumentUndoRedo().DoesUndo())
535         {
536             GetIDocumentUndoRedo().AppendUndo(new SwUndoInsLayFmt(pDest,0,0));
537         }
538     }
539 
540     if (bSetTxtFlyAtt && (FLY_AS_CHAR == rNewAnchor.GetAnchorId()))
541     {
542         const SwPosition* pPos = rNewAnchor.GetCntntAnchor();
543         SwFmtFlyCnt aFmt( pDest );
544         pPos->nNode.GetNode().GetTxtNode()->InsertItem(
545             aFmt, pPos->nContent.GetIndex(), 0 );
546     }
547 
548     if( bMakeFrms )
549         pDest->MakeFrms();
550 
551     return pDest;
552 }
553 
554 SdrObject* SwDoc::CloneSdrObj( const SdrObject& rObj, sal_Bool bMoveWithinDoc,
555                                 sal_Bool bInsInPage )
556 {
557     // --> OD 2005-08-08 #i52858# - method name changed
558     SdrPage *pPg = GetOrCreateDrawModel()->GetPage( 0 );
559     // <--
560     if( !pPg )
561     {
562         pPg = GetDrawModel()->AllocPage( sal_False );
563         GetDrawModel()->InsertPage( pPg );
564     }
565 
566     SdrObject *pObj = rObj.Clone();
567     if( bMoveWithinDoc && FmFormInventor == pObj->GetObjInventor() )
568     {
569         // bei Controls muss der Name erhalten bleiben
570         uno::Reference< awt::XControlModel >  xModel = ((SdrUnoObj*)pObj)->GetUnoControlModel();
571         uno::Any aVal;
572         uno::Reference< beans::XPropertySet >  xSet(xModel, uno::UNO_QUERY);
573         OUString sName( rtl::OUString::createFromAscii("Name") );
574         if( xSet.is() )
575             aVal = xSet->getPropertyValue( sName );
576         if( bInsInPage )
577             pPg->InsertObject( pObj );
578         if( xSet.is() )
579             xSet->setPropertyValue( sName, aVal );
580     }
581     else if( bInsInPage )
582         pPg->InsertObject( pObj );
583 
584     // OD 02.07.2003 #108784# - for drawing objects: set layer of cloned object
585     // to invisible layer
586     SdrLayerID nLayerIdForClone = rObj.GetLayer();
587     if ( !pObj->ISA(SwFlyDrawObj) &&
588          !pObj->ISA(SwVirtFlyDrawObj) &&
589          !IS_TYPE(SdrObject,pObj) )
590     {
591         if ( IsVisibleLayerId( nLayerIdForClone ) )
592         {
593             nLayerIdForClone = GetInvisibleLayerIdByVisibleOne( nLayerIdForClone );
594         }
595     }
596     pObj->SetLayer( nLayerIdForClone );
597 
598 
599     return pObj;
600 }
601 
602 SwFlyFrmFmt* SwDoc::_MakeFlySection( const SwPosition& rAnchPos,
603                                     const SwCntntNode& rNode,
604                                     RndStdIds eRequestId,
605                                     const SfxItemSet* pFlySet,
606                                     SwFrmFmt* pFrmFmt )
607 {
608     if( !pFrmFmt )
609         pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME );
610 
611     String sName;
612     if( !mbInReading )
613         switch( rNode.GetNodeType() )
614         {
615         case ND_GRFNODE:        sName = GetUniqueGrfName();     break;
616         case ND_OLENODE:        sName = GetUniqueOLEName();     break;
617         default:                sName = GetUniqueFrameName();       break;
618         }
619     SwFlyFrmFmt* pFmt = MakeFlyFrmFmt( sName, pFrmFmt );
620 
621     //Inhalt erzeugen und mit dem Format verbinden.
622     //CntntNode erzeugen und in die Autotextsection stellen
623     SwNodeRange aRange( GetNodes().GetEndOfAutotext(), -1,
624                         GetNodes().GetEndOfAutotext() );
625     GetNodes().SectionDown( &aRange, SwFlyStartNode );
626 
627     pFmt->SetFmtAttr( SwFmtCntnt( rNode.StartOfSectionNode() ));
628 
629 
630     const SwFmtAnchor* pAnchor = 0;
631     if( pFlySet )
632     {
633         pFlySet->GetItemState( RES_ANCHOR, sal_False,
634                                 (const SfxPoolItem**)&pAnchor );
635         if( SFX_ITEM_SET == pFlySet->GetItemState( RES_CNTNT, sal_False ))
636         {
637             SfxItemSet aTmpSet( *pFlySet );
638             aTmpSet.ClearItem( RES_CNTNT );
639             pFmt->SetFmtAttr( aTmpSet );
640         }
641         else
642             pFmt->SetFmtAttr( *pFlySet );
643     }
644 
645     // Anker noch nicht gesetzt ?
646     RndStdIds eAnchorId = pAnchor ? pAnchor->GetAnchorId()
647                                   : pFmt->GetAnchor().GetAnchorId();
648     // --> OD 2010-01-07 #i107811#
649     // Assure that at-page anchored fly frames have a page num or a content anchor set.
650     if ( !pAnchor ||
651          ( FLY_AT_PAGE != pAnchor->GetAnchorId() &&
652            !pAnchor->GetCntntAnchor() ) ||
653          ( FLY_AT_PAGE == pAnchor->GetAnchorId() &&
654            !pAnchor->GetCntntAnchor() &&
655            pAnchor->GetPageNum() == 0 ) )
656     {
657         // dann setze ihn, wird im Undo gebraucht
658         SwFmtAnchor aAnch( pFmt->GetAnchor() );
659         if (pAnchor && (FLY_AT_FLY == pAnchor->GetAnchorId()))
660         {
661             SwPosition aPos( *rAnchPos.nNode.GetNode().FindFlyStartNode() );
662             aAnch.SetAnchor( &aPos );
663             eAnchorId = FLY_AT_FLY;
664         }
665         else
666         {
667             if( eRequestId != aAnch.GetAnchorId() &&
668                 SFX_ITEM_SET != pFmt->GetItemState( RES_ANCHOR, sal_True ) )
669             {
670                 aAnch.SetType( eRequestId );
671             }
672 
673             eAnchorId = aAnch.GetAnchorId();
674             if ( FLY_AT_PAGE != eAnchorId ||
675                  ( FLY_AT_PAGE == eAnchorId &&
676                    ( !pAnchor ||
677                      aAnch.GetPageNum() == 0 ) ) )
678             {
679                 aAnch.SetAnchor( &rAnchPos );
680             }
681         }
682         // <--
683         pFmt->SetFmtAttr( aAnch );
684     }
685     else
686         eAnchorId = pFmt->GetAnchor().GetAnchorId();
687 
688     if ( FLY_AS_CHAR == eAnchorId )
689     {
690         xub_StrLen nStt = rAnchPos.nContent.GetIndex();
691         SwTxtNode * pTxtNode = rAnchPos.nNode.GetNode().GetTxtNode();
692 
693         ASSERT(pTxtNode!= 0, "There should be a SwTxtNode!");
694 
695         if (pTxtNode != NULL)
696         {
697             SwFmtFlyCnt aFmt( pFmt );
698             pTxtNode->InsertItem( aFmt, nStt, nStt );
699         }
700     }
701 
702     if( SFX_ITEM_SET != pFmt->GetAttrSet().GetItemState( RES_FRM_SIZE ))
703     {
704         SwFmtFrmSize aFmtSize( ATT_VAR_SIZE, 0, DEF_FLY_WIDTH );
705         const SwNoTxtNode* pNoTxtNode = rNode.GetNoTxtNode();
706         if( pNoTxtNode )
707         {
708             //Groesse einstellen.
709             Size aSize( pNoTxtNode->GetTwipSize() );
710             if( MINFLY > aSize.Width() )
711                 aSize.Width() = DEF_FLY_WIDTH;
712             aFmtSize.SetWidth( aSize.Width() );
713             if( aSize.Height() )
714             {
715                 aFmtSize.SetHeight( aSize.Height() );
716                 aFmtSize.SetHeightSizeType( ATT_FIX_SIZE );
717             }
718         }
719         pFmt->SetFmtAttr( aFmtSize );
720     }
721 
722     // Frames anlegen
723     if( GetCurrentViewShell() )
724         pFmt->MakeFrms();           // ???  //swmod 071108//swmod 071225
725 
726     if (GetIDocumentUndoRedo().DoesUndo())
727     {
728         sal_uLong nNodeIdx = rAnchPos.nNode.GetIndex();
729         xub_StrLen nCntIdx = rAnchPos.nContent.GetIndex();
730         GetIDocumentUndoRedo().AppendUndo(
731             new SwUndoInsLayFmt( pFmt, nNodeIdx, nCntIdx ));
732     }
733 
734     SetModified();
735     return pFmt;
736 }
737 
738 SwFlyFrmFmt* SwDoc::MakeFlySection( RndStdIds eAnchorType,
739                                     const SwPosition* pAnchorPos,
740                                     const SfxItemSet* pFlySet,
741                                     SwFrmFmt* pFrmFmt, sal_Bool bCalledFromShell )
742 {
743     SwFlyFrmFmt* pFmt = 0;
744     sal_Bool bCallMake = sal_True;
745     if ( !pAnchorPos && (FLY_AT_PAGE != eAnchorType) )
746     {
747         const SwFmtAnchor* pAnch;
748         if( (pFlySet && SFX_ITEM_SET == pFlySet->GetItemState(
749                 RES_ANCHOR, sal_False, (const SfxPoolItem**)&pAnch )) ||
750             ( pFrmFmt && SFX_ITEM_SET == pFrmFmt->GetItemState(
751                 RES_ANCHOR, sal_True, (const SfxPoolItem**)&pAnch )) )
752         {
753             if ( (FLY_AT_PAGE != pAnch->GetAnchorId()) )
754             {
755                 pAnchorPos = pAnch->GetCntntAnchor();
756                 if (pAnchorPos)
757                 {
758                     bCallMake = sal_False;
759                 }
760             }
761         }
762     }
763 
764     if( bCallMake )
765     {
766         if( !pFrmFmt )
767             pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME );
768 
769         sal_uInt16 nCollId = static_cast<sal_uInt16>(
770             get(IDocumentSettingAccess::HTML_MODE) ? RES_POOLCOLL_TEXT : RES_POOLCOLL_FRAME );
771 
772         /* #109161# If there exists no adjust item in the paragraph
773             style for the content node of the new fly section
774             propagate an existing adjust item at the anchor to the new
775             content node. */
776         SwCntntNode * pNewTxtNd = GetNodes().MakeTxtNode
777             (SwNodeIndex( GetNodes().GetEndOfAutotext()),
778              GetTxtCollFromPool( nCollId ));
779         SwCntntNode * pAnchorNode = pAnchorPos->nNode.GetNode().GetCntntNode();
780 
781         const SfxPoolItem * pItem = NULL;
782 
783         if (bCalledFromShell && !lcl_IsItemSet(*pNewTxtNd, RES_PARATR_ADJUST) &&
784             SFX_ITEM_SET == pAnchorNode->GetSwAttrSet().
785             GetItemState(RES_PARATR_ADJUST, sal_True, &pItem))
786             static_cast<SwCntntNode *>(pNewTxtNd)->SetAttr(*pItem);
787 
788         pFmt = _MakeFlySection( *pAnchorPos, *pNewTxtNd,
789                                 eAnchorType, pFlySet, pFrmFmt );
790     }
791     return pFmt;
792 }
793 
794 SwFlyFrmFmt* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rSet,
795                                     const SwSelBoxes* pSelBoxes,
796                                     SwFrmFmt *pParent )
797 {
798     SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
799 
800     GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL );
801 
802     SwFlyFrmFmt* pFmt = MakeFlySection( rAnch.GetAnchorId(), rPam.GetPoint(),
803                                         &rSet, pParent );
804 
805     // Wenn Inhalt selektiert ist, so wird dieser jetzt zum Inhalt des
806     // neuen Rahmen. Sprich er wird in die entspr. Sektion des NodesArr
807     //gemoved.
808 
809     if( pFmt )
810     {
811         do {        // middle check loop
812             const SwFmtCntnt &rCntnt = pFmt->GetCntnt();
813             ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
814             SwNodeIndex aIndex( *(rCntnt.GetCntntIdx()), 1 );
815             SwCntntNode *pNode = aIndex.GetNode().GetCntntNode();
816 
817             // ACHTUNG: nicht einen Index auf dem Stack erzeugen, sonst
818             //          kann der CntntnNode am Ende nicht geloscht werden !!
819             SwPosition aPos( aIndex );
820             aPos.nContent.Assign( pNode, 0 );
821 
822             if( pSelBoxes && pSelBoxes->Count() )
823             {
824                 // Tabellenselection
825                 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der
826                 // Breite der Originalen an und move (kopiere/loesche) die
827                 // selektierten Boxen. Die Groessen werden prozentual
828                 // korrigiert.
829 
830                 SwTableNode* pTblNd = (SwTableNode*)(*pSelBoxes)[0]->
831                                                 GetSttNd()->FindTableNode();
832                 if( !pTblNd )
833                     break;
834 
835                 SwTable& rTbl = pTblNd->GetTable();
836 
837                 // ist die gesamte Tabelle selektiert ?
838                 if( pSelBoxes->Count() == rTbl.GetTabSortBoxes().Count() )
839                 {
840                     // verschiebe die gesamte Tabelle
841                     SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode(), 1 );
842 
843                     // wird die gesamte Tabelle verschoben und steht diese
844                     // in einem FlyFrame, dann erzeuge dahinter einen neuen
845                     // TextNode. Dadurch bleibt dieser Fly erhalten !
846                     if( aRg.aEnd.GetNode().IsEndNode() )
847                         GetNodes().MakeTxtNode( aRg.aStart,
848                                     (SwTxtFmtColl*)GetDfltTxtFmtColl() );
849 
850                     MoveNodeRange( aRg, aPos.nNode, DOC_MOVEDEFAULT );
851                 }
852                 else
853                 {
854                     rTbl.MakeCopy( this, aPos, *pSelBoxes );
855                     // Don't delete a part of a table with row span!!
856                     // You could delete the content instead -> ToDo
857                     //rTbl.DeleteSel( this, *pSelBoxes, 0, 0, sal_True, sal_True );
858                 }
859 
860                 // wenn Tabelle im Rahmen, dann ohne nachfolgenden TextNode
861                 aIndex = rCntnt.GetCntntIdx()->GetNode().EndOfSectionIndex() - 1;
862                 ASSERT( aIndex.GetNode().GetTxtNode(),
863                         "hier sollte ein TextNode stehen" );
864                 aPos.nContent.Assign( 0, 0 );       // Index abmelden !!
865                 GetNodes().Delete( aIndex, 1 );
866 
867 //JP erstmal ein Hack, solange keine Flys/Headers/Footers Undofaehig sind
868 // werden erstmal alle Undo - Objecte geloescht.
869 if( GetIDocumentUndoRedo().DoesUndo() )
870 {
871     GetIDocumentUndoRedo().DelAllUndoObj();
872 }
873 
874             }
875             else
876             {
877 /*
878                 // alle Pams verschieben
879                 SwPaM* pTmp = (SwPaM*)&rPam;
880                 do {
881                     if( pTmp->HasMark() &&
882                         *pTmp->GetPoint() != *pTmp->GetMark() )
883                         MoveAndJoin( *pTmp, aPos );
884                 } while( &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ) );
885 */
886                 // copy all Pams and then delete all
887                 SwPaM* pTmp = (SwPaM*)&rPam;
888                 sal_Bool bOldFlag = mbCopyIsMove;
889                 bool const bOldUndo = GetIDocumentUndoRedo().DoesUndo();
890                 mbCopyIsMove = sal_True;
891                 GetIDocumentUndoRedo().DoUndo(false);
892                 do {
893                     if( pTmp->HasMark() &&
894                         *pTmp->GetPoint() != *pTmp->GetMark() )
895                     {
896                         CopyRange( *pTmp, aPos, false );
897                     }
898                     pTmp = static_cast<SwPaM*>(pTmp->GetNext());
899                 } while ( &rPam != pTmp );
900                 mbCopyIsMove = bOldFlag;
901                 GetIDocumentUndoRedo().DoUndo(bOldUndo);
902 
903                 pTmp = (SwPaM*)&rPam;
904                 do {
905                     if( pTmp->HasMark() &&
906                         *pTmp->GetPoint() != *pTmp->GetMark() )
907                     {
908                         DeleteAndJoin( *pTmp );
909                     }
910                     pTmp = static_cast<SwPaM*>(pTmp->GetNext());
911                 } while ( &rPam != pTmp );
912             }
913         } while( sal_False );
914     }
915 
916     SetModified();
917 
918     GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL );
919 
920     return pFmt;
921 }
922 
923 
924     //Einfuegen eines DrawObjectes. Das Object muss bereits im DrawModel
925     // angemeldet sein.
926 SwDrawFrmFmt* SwDoc::Insert( const SwPaM &rRg,
927                              SdrObject& rDrawObj,
928                              const SfxItemSet* pFlyAttrSet,
929                              SwFrmFmt* pDefFmt )
930 {
931     SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( aEmptyStr,
932                                         pDefFmt ? pDefFmt : GetDfltFrmFmt() );
933 
934     const SwFmtAnchor* pAnchor = 0;
935     if( pFlyAttrSet )
936     {
937         pFlyAttrSet->GetItemState( RES_ANCHOR, sal_False,
938                                     (const SfxPoolItem**)&pAnchor );
939         pFmt->SetFmtAttr( *pFlyAttrSet );
940     }
941 
942     RndStdIds eAnchorId = pAnchor ? pAnchor->GetAnchorId()
943                                   : pFmt->GetAnchor().GetAnchorId();
944 
945     // Anker noch nicht gesetzt ?
946     // DrawObjecte duerfen niemals in Kopf-/Fusszeilen landen.
947     const bool bIsAtCntnt = (FLY_AT_PAGE != eAnchorId);
948 
949     const SwNodeIndex* pChkIdx = 0;
950     if( !pAnchor )
951     {
952         pChkIdx = &rRg.GetPoint()->nNode;
953     }
954     else if( bIsAtCntnt )
955     {
956         pChkIdx = pAnchor->GetCntntAnchor()
957                     ? &pAnchor->GetCntntAnchor()->nNode
958                     : &rRg.GetPoint()->nNode;
959     }
960 
961     // OD 24.06.2003 #108784# - allow drawing objects in header/footer, but
962     // control objects aren't allowed in header/footer.
963     if( pChkIdx &&
964         ::CheckControlLayer( &rDrawObj ) &&
965         IsInHeaderFooter( *pChkIdx ) )
966     {
967        pFmt->SetFmtAttr( SwFmtAnchor( eAnchorId = FLY_AT_PAGE ) );
968     }
969     else if( !pAnchor || (bIsAtCntnt && !pAnchor->GetCntntAnchor() ))
970     {
971         // dann setze ihn, wird im Undo gebraucht
972         SwFmtAnchor aAnch( pAnchor ? *pAnchor : pFmt->GetAnchor() );
973         eAnchorId = aAnch.GetAnchorId();
974         if( FLY_AT_FLY == eAnchorId )
975         {
976             SwPosition aPos( *rRg.GetNode()->FindFlyStartNode() );
977             aAnch.SetAnchor( &aPos );
978         }
979         else
980         {
981             aAnch.SetAnchor( rRg.GetPoint() );
982             if ( FLY_AT_PAGE == eAnchorId )
983             {
984                 eAnchorId = rDrawObj.ISA( SdrUnoObj )
985                                     ? FLY_AS_CHAR : FLY_AT_PARA;
986                 aAnch.SetType( eAnchorId );
987             }
988         }
989         pFmt->SetFmtAttr( aAnch );
990     }
991 
992     // bei als Zeichen gebundenen Draws das Attribut im Absatz setzen
993     if ( FLY_AS_CHAR == eAnchorId )
994     {
995         xub_StrLen nStt = rRg.GetPoint()->nContent.GetIndex();
996         SwFmtFlyCnt aFmt( pFmt );
997         rRg.GetPoint()->nNode.GetNode().GetTxtNode()->InsertItem(
998                 aFmt, nStt, nStt );
999     }
1000 
1001     SwDrawContact* pContact = new SwDrawContact( pFmt, &rDrawObj );
1002 
1003     // ggfs. Frames anlegen
1004     if( GetCurrentViewShell() )
1005     {
1006         pFmt->MakeFrms();
1007         // --> OD 2005-02-09 #i42319# - follow-up of #i35635#
1008         // move object to visible layer
1009         // --> OD 2007-07-10 #i79391#
1010         if ( pContact->GetAnchorFrm() )
1011         {
1012             pContact->MoveObjToVisibleLayer( &rDrawObj );
1013         }
1014         // <--
1015     }
1016 
1017     if (GetIDocumentUndoRedo().DoesUndo())
1018     {
1019         GetIDocumentUndoRedo().AppendUndo( new SwUndoInsLayFmt(pFmt, 0, 0) );
1020     }
1021 
1022     SetModified();
1023     return pFmt;
1024 }
1025 
1026 /*************************************************************************
1027 |*
1028 |*  SwDoc::GetAllFlyFmts
1029 |*
1030 |*  Ersterstellung      MA 14. Jul. 93
1031 |*  Letzte Aenderung    MD 23. Feb. 95
1032 |*
1033 |*************************************************************************/
1034 
1035 /*sal_Bool TstFlyRange( const SwPaM* pPam, sal_uInt32 nFlyPos )
1036 {
1037     sal_Bool bOk = sal_False;
1038     const SwPaM* pTmp = pPam;
1039     do {
1040         bOk = pTmp->Start()->nNode.GetIndex() < nFlyPos &&
1041                 pTmp->End()->nNode.GetIndex() > nFlyPos;
1042     } while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
1043     return bOk;
1044 }
1045 */
1046 /* -----------------------------04.04.00 10:55--------------------------------
1047     paragraph frames - o.k. if the PaM includes the paragraph from the beginning
1048                        to the beginning of the next paragraph at least
1049     frames at character - o.k. if the pam start at least at the same position
1050                         as the frame
1051  ---------------------------------------------------------------------------*/
1052 sal_Bool TstFlyRange( const SwPaM* pPam, const SwPosition* pFlyPos,
1053                         RndStdIds nAnchorId )
1054 {
1055     sal_Bool bOk = sal_False;
1056     const SwPaM* pTmp = pPam;
1057     do {
1058         const sal_uInt32 nFlyIndex = pFlyPos->nNode.GetIndex();
1059         const SwPosition* pPaMStart = pTmp->Start();
1060         const SwPosition* pPaMEnd = pTmp->End();
1061         const sal_uInt32 nPamStartIndex = pPaMStart->nNode.GetIndex();
1062         const sal_uInt32 nPamEndIndex = pPaMEnd->nNode.GetIndex();
1063         if (FLY_AT_PARA == nAnchorId)
1064             bOk = (nPamStartIndex < nFlyIndex && nPamEndIndex > nFlyIndex) ||
1065                (((nPamStartIndex == nFlyIndex) && (pPaMStart->nContent.GetIndex() == 0)) &&
1066                (nPamEndIndex > nFlyIndex));
1067         else
1068         {
1069             xub_StrLen nFlyContentIndex = pFlyPos->nContent.GetIndex();
1070             xub_StrLen nPamEndContentIndex = pPaMEnd->nContent.GetIndex();
1071             bOk = (nPamStartIndex < nFlyIndex &&
1072                 (( nPamEndIndex > nFlyIndex )||
1073                  ((nPamEndIndex == nFlyIndex) &&
1074                   (nPamEndContentIndex > nFlyContentIndex))) )
1075                 ||
1076                     (((nPamStartIndex == nFlyIndex) &&
1077                       (pPaMStart->nContent.GetIndex() <= nFlyContentIndex)) &&
1078                      ((nPamEndIndex > nFlyIndex) ||
1079                      (nPamEndContentIndex > nFlyContentIndex )));
1080         }
1081 
1082     } while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
1083     return bOk;
1084 }
1085 
1086 
1087 SwPosFlyFrms SwDoc::GetAllFlyFmts( const SwPaM* pCmpRange, sal_Bool bDrawAlso ) const
1088 {
1089     SwPosFlyFrms aRetval;
1090     SwFrmFmt *pFly;
1091 
1092     // erstmal alle Absatzgebundenen einsammeln
1093     for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n )
1094     {
1095         pFly = (*GetSpzFrmFmts())[ n ];
1096         bool bDrawFmt = bDrawAlso ? RES_DRAWFRMFMT == pFly->Which() : false;
1097         bool bFlyFmt = RES_FLYFRMFMT == pFly->Which();
1098         if( bFlyFmt || bDrawFmt )
1099         {
1100             const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1101             SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1102             if (pAPos &&
1103                 ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1104                  (FLY_AT_FLY  == rAnchor.GetAnchorId()) ||
1105                  (FLY_AT_CHAR == rAnchor.GetAnchorId())))
1106             {
1107                 if( pCmpRange &&
1108                     !TstFlyRange( pCmpRange, pAPos, rAnchor.GetAnchorId() ))
1109                         continue;       // kein gueltiger FlyFrame
1110                 aRetval.insert(SwPosFlyFrmPtr(new SwPosFlyFrm(pAPos->nNode, pFly, aRetval.size())));
1111             }
1112         }
1113     }
1114 
1115     // kein Layout oder nur ein Teil, dann wars das
1116     // Seitenbezogen Flys nur, wenn vollstaendig "gewuenscht" wird !
1117     if( !GetCurrentViewShell() || pCmpRange )   //swmod 071108//swmod 071225
1118     {
1119         return aRetval;
1120     }
1121 
1122     SwPageFrm *pPage = (SwPageFrm*)GetCurrentLayout()->GetLower();  //swmod 080218
1123     while( pPage )
1124     {
1125         if( pPage->GetSortedObjs() )
1126         {
1127             SwSortedObjs &rObjs = *pPage->GetSortedObjs();
1128             for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
1129             {
1130                 SwAnchoredObject* pAnchoredObj = rObjs[i];
1131                 if ( pAnchoredObj->ISA(SwFlyFrm) )
1132                     pFly = &(pAnchoredObj->GetFrmFmt());
1133                 else if ( bDrawAlso )
1134                     pFly = &(pAnchoredObj->GetFrmFmt());
1135                 else
1136                     continue;
1137 
1138                 const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1139                 if ((FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1140                     (FLY_AT_FLY  != rAnchor.GetAnchorId()) &&
1141                     (FLY_AT_CHAR != rAnchor.GetAnchorId()))
1142                 {
1143                     const SwCntntFrm * pCntntFrm = pPage->FindFirstBodyCntnt();
1144                     if ( !pCntntFrm )
1145                     {
1146                         //Oops! Eine leere Seite. Damit der Rahmen nicht ganz
1147                         //verlorengeht (RTF) suchen wir schnell den letzen
1148                         //Cntnt der vor der Seite steht.
1149                         SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev();
1150                         while ( !pCntntFrm && pPrv )
1151                         {
1152                             pCntntFrm = pPrv->FindFirstBodyCntnt();
1153                             pPrv = (SwPageFrm*)pPrv->GetPrev();
1154                         }
1155                     }
1156                     if ( pCntntFrm )
1157                     {
1158                         SwNodeIndex aIdx( *pCntntFrm->GetNode() );
1159                         aRetval.insert(SwPosFlyFrmPtr(new SwPosFlyFrm(aIdx, pFly, aRetval.size())));
1160                     }
1161                 }
1162             }
1163         }
1164         pPage = (SwPageFrm*)pPage->GetNext();
1165     }
1166 
1167     return aRetval;
1168 }
1169 
1170 /*************************************************************************
1171 |*
1172 |*  SwDoc::InsertLabel()
1173 |*
1174 |*  Ersterstellung      MA 11. Feb. 94
1175 |*  Letzte Aenderung    MA 12. Nov. 97
1176 |*
1177 |*************************************************************************/
1178 
1179 /* #i6447# changed behaviour if lcl_CpyAttr:
1180 
1181    If the old item set contains the item to set (no inheritance) copy the item
1182    into the new set.
1183 
1184    If the old item set contains the item by inheritance and the new set
1185    contains the item, too:
1186       If the two items differ copy the item from the old set to the new set.
1187 
1188    Otherwise the new set will not be changed.
1189 */
1190 
1191 void lcl_CpyAttr( SfxItemSet &rNewSet, const SfxItemSet &rOldSet, sal_uInt16 nWhich )
1192 {
1193     const SfxPoolItem *pOldItem = NULL, *pNewItem = NULL;
1194 
1195     rOldSet.GetItemState( nWhich, sal_False, &pOldItem);
1196     if (pOldItem != NULL)
1197         rNewSet.Put( *pOldItem );
1198     else
1199     {
1200         pOldItem = rOldSet.GetItem( nWhich, sal_True);
1201         if (pOldItem != NULL)
1202         {
1203             pNewItem = rNewSet.GetItem( nWhich, sal_True);
1204             if (pNewItem != NULL)
1205             {
1206                 if (*pOldItem != *pNewItem)
1207                     rNewSet.Put( *pOldItem );
1208             }
1209             else {
1210                 ASSERT(0, "What am I doing here?");
1211             }
1212         }
1213         else {
1214             ASSERT(0, "What am I doing here?");
1215         }
1216     }
1217 
1218 }
1219 
1220 
1221 static SwFlyFrmFmt *
1222 lcl_InsertLabel(SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1223         SwUndoInsertLabel *const pUndo,
1224         SwLabelType const eType, String const& rTxt, String const& rSeparator,
1225             const String& rNumberingSeparator,
1226             const sal_Bool bBefore, const sal_uInt16 nId, const sal_uLong nNdIdx,
1227             const String& rCharacterStyle,
1228             const sal_Bool bCpyBrd )
1229 {
1230     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1231 
1232     sal_Bool bTable = sal_False;    //Um etwas Code zu sparen.
1233 
1234     //Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt werden
1235     //muss
1236     OSL_ENSURE( nId == USHRT_MAX  || nId < rDoc.GetFldTypes()->Count(),
1237             "FldType index out of bounds." );
1238     SwFieldType *pType = (nId != USHRT_MAX) ? (*rDoc.GetFldTypes())[nId] : NULL;
1239     OSL_ENSURE(!pType || pType->Which() == RES_SETEXPFLD, "wrong Id for Label");
1240 
1241     SwTxtFmtColl * pColl = NULL;
1242     if( pType )
1243     {
1244         for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; )
1245         {
1246             if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() )
1247             {
1248                 pColl = (*pTxtFmtCollTbl)[i];
1249                 break;
1250             }
1251         }
1252         DBG_ASSERT( pColl, "no text collection found" );
1253     }
1254 
1255     if( !pColl )
1256     {
1257         pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1258     }
1259 
1260     SwTxtNode *pNew = NULL;
1261     SwFlyFrmFmt* pNewFmt = NULL;
1262 
1263     switch ( eType )
1264     {
1265         case LTYPE_TABLE:
1266             bTable = sal_True;
1267             /* Kein Break hier */
1268         case LTYPE_FLY:
1269             //Am Anfang/Ende der Fly-Section den entsprechenden Node mit Feld
1270             //einfuegen (Frame wird automatisch erzeugt).
1271             {
1272                 SwStartNode *pSttNd = rDoc.GetNodes()[nNdIdx]->GetStartNode();
1273                 ASSERT( pSttNd, "Kein StartNode in InsertLabel." );
1274                 sal_uLong nNode;
1275                 if( bBefore )
1276                 {
1277                     nNode = pSttNd->GetIndex();
1278                     if( !bTable )
1279                         ++nNode;
1280                 }
1281                 else
1282                 {
1283                     nNode = pSttNd->EndOfSectionIndex();
1284                     if( bTable )
1285                         ++nNode;
1286                 }
1287 
1288                 if( pUndo )
1289                     pUndo->SetNodePos( nNode );
1290 
1291                 //Node fuer Beschriftungsabsatz erzeugen.
1292                 SwNodeIndex aIdx( rDoc.GetNodes(), nNode );
1293                 pNew = rDoc.GetNodes().MakeTxtNode( aIdx, pColl );
1294             }
1295             break;
1296 
1297         case LTYPE_OBJECT:
1298             {
1299                 //Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden
1300                 // Node mit Feld in den neuen Rahmen, den alten Rahmen mit
1301                 // dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen,
1302                 // Frames erzeugen.
1303 
1304                 //Erstmal das Format zum Fly besorgen und das Layout entkoppeln.
1305                 SwFrmFmt *pOldFmt = rDoc.GetNodes()[nNdIdx]->GetFlyFmt();
1306                 ASSERT( pOldFmt, "Format des Fly nicht gefunden." );
1307                 // --> OD #i115719#
1308                 // <title> and <description> attributes are lost when calling <DelFrms()>.
1309                 // Thus, keep them and restore them after the calling <MakeFrms()>
1310                 const bool bIsSwFlyFrmFmtInstance( dynamic_cast<SwFlyFrmFmt*>(pOldFmt) != 0 );
1311                 const String sTitle( bIsSwFlyFrmFmtInstance
1312                                      ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjTitle()
1313                                      : String() );
1314                 const String sDescription( bIsSwFlyFrmFmtInstance
1315                                            ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjDescription()
1316                                            : String() );
1317                 // <--
1318                 pOldFmt->DelFrms();
1319 
1320                 pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1321                                 rDoc.GetFrmFmtFromPool(RES_POOLFRM_FRAME) );
1322 
1323                 /* #i6447#: Only the selected items are copied from the old
1324                    format. */
1325                 SfxItemSet* pNewSet = pNewFmt->GetAttrSet().Clone( sal_True );
1326 
1327 
1328                 //Diejenigen Attribute uebertragen die auch gesetzt sind,
1329                 //andere sollen weiterhin aus den Vorlagen gueltig werden.
1330                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PRINT );
1331                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_OPAQUE );
1332                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PROTECT );
1333                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1334                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_VERT_ORIENT );
1335                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_HORI_ORIENT );
1336                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_LR_SPACE );
1337                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_UL_SPACE );
1338                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_BACKGROUND );
1339                 if( bCpyBrd )
1340                 {
1341                     // JP 07.07.99: Bug 67029 - if at Grafik no BoxItem but
1342                     //              in the new Format is any, then set the
1343                     //              default item in the new Set. Because
1344                     //              the Size of the Grafik have never been
1345                     //              changed!
1346                     const SfxPoolItem *pItem;
1347                     if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1348                             GetItemState( RES_BOX, sal_True, &pItem ))
1349                         pNewSet->Put( *pItem );
1350                     else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1351                             GetItemState( RES_BOX, sal_True ))
1352                         pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1353 
1354                     if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1355                             GetItemState( RES_SHADOW, sal_True, &pItem ))
1356                         pNewSet->Put( *pItem );
1357                     else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1358                             GetItemState( RES_SHADOW, sal_True ))
1359                         pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1360                 }
1361                 else
1362                 {
1363                     //Die Attribute hart setzen, weil sie sonst aus der
1364                     // Vorlage kommen koenten und dann passt die
1365                     // Grossenberechnung nicht mehr.
1366                     pNewSet->Put( SvxBoxItem(RES_BOX) );
1367                     pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1368 
1369                 }
1370 
1371                 //Anker immer uebertragen, ist sowieso ein hartes Attribut.
1372                 pNewSet->Put( pOldFmt->GetAnchor() );
1373 
1374                 //In der Hoehe soll der neue Varabel sein!
1375                 SwFmtFrmSize aFrmSize( pOldFmt->GetFrmSize() );
1376                 aFrmSize.SetHeightSizeType( ATT_MIN_SIZE );
1377                 pNewSet->Put( aFrmSize );
1378 
1379                 SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection(
1380                             SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1381                             SwFlyStartNode, pColl );
1382                 pNewSet->Put( SwFmtCntnt( pSttNd ));
1383 
1384                 pNewFmt->SetFmtAttr( *pNewSet );
1385 
1386                 //Bei InCntnt's wird es spannend: Das TxtAttribut muss
1387                 //vernichtet werden. Leider reisst dies neben den Frms auch
1388                 //noch das Format mit in sein Grab. Um dass zu unterbinden
1389                 //loesen wir vorher die Verbindung zwischen Attribut und Format.
1390 
1391                 const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1392                 if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1393                 {
1394                     const SwPosition *pPos = rAnchor.GetCntntAnchor();
1395                     SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1396                     ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1397                     const xub_StrLen nIdx = pPos->nContent.GetIndex();
1398                     SwTxtAttr * const pHnt =
1399                         pTxtNode->GetTxtAttrForCharAt(nIdx, RES_TXTATR_FLYCNT);
1400 
1401                     ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1402                                 "Missing FlyInCnt-Hint." );
1403                     ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pOldFmt,
1404                                 "Wrong TxtFlyCnt-Hint." );
1405 
1406                     const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(
1407                             pNewFmt );
1408                 }
1409 
1410 
1411                 //Der Alte soll keinen Umlauf haben, und er soll oben/mittig
1412                 //ausgerichtet sein.
1413                 //Ausserdem soll die Breite 100% betragen und bei Aenderungen
1414                 //Die Hoehe mit anpassen.
1415                 pNewSet->ClearItem();
1416 
1417                 pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1418                 pNewSet->Put( SvxOpaqueItem( RES_OPAQUE, sal_True ) );
1419                 pNewSet->Put( SwFmtVertOrient( text::VertOrientation::TOP ) );
1420                 pNewSet->Put( SwFmtHoriOrient( text::HoriOrientation::CENTER ) );
1421 
1422                 aFrmSize = pOldFmt->GetFrmSize();
1423                 aFrmSize.SetWidthPercent( 100 );
1424                 aFrmSize.SetHeightPercent( 255 );
1425                 pNewSet->Put( aFrmSize );
1426 
1427                 //Die Attribute setzen wir hart, weil sie sonst aus der Vorlage
1428                 //kommen koenten und dann passt die Grossenberechnung nicht mehr.
1429                 if( bCpyBrd )
1430                 {
1431                     pNewSet->Put( SvxBoxItem(RES_BOX) );
1432                     pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1433                 }
1434                 pNewSet->Put( SvxLRSpaceItem(RES_LR_SPACE) );
1435                 pNewSet->Put( SvxULSpaceItem(RES_UL_SPACE) );
1436 
1437                 //Der Alte ist absatzgebunden, und zwar am Absatz im neuen.
1438                 SwFmtAnchor aAnch( FLY_AT_PARA );
1439                 SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1440                 pNew = aAnchIdx.GetNode().GetTxtNode();
1441                 SwPosition aPos( aAnchIdx );
1442                 aAnch.SetAnchor( &aPos );
1443                 pNewSet->Put( aAnch );
1444 
1445                 if( pUndo )
1446                     pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1447                 else
1448                     pOldFmt->SetFmtAttr( *pNewSet );
1449 
1450                 delete pNewSet;
1451 
1452                 //Nun nur noch die Flys erzeugen lassen. Das ueberlassen
1453                 //wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig).
1454                 pNewFmt->MakeFrms();
1455                 // --> OD #i115719#
1456                 if ( bIsSwFlyFrmFmtInstance )
1457                 {
1458                     static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjTitle( sTitle );
1459                     static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjDescription( sDescription );
1460                 }
1461                 // <--
1462             }
1463             break;
1464 
1465         default:
1466             OSL_ENSURE(false, "unknown LabelType?");
1467     }
1468     ASSERT( pNew, "No Label inserted" );
1469     if( pNew )
1470     {
1471         //#i61007# order of captions
1472         sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1473         //String aufbereiten
1474         String aTxt;
1475         if( bOrderNumberingFirst )
1476         {
1477             aTxt = rNumberingSeparator;
1478         }
1479         if( pType)
1480         {
1481             aTxt += pType->GetName();
1482             if( !bOrderNumberingFirst )
1483                 aTxt += ' ';
1484         }
1485         xub_StrLen nIdx = aTxt.Len();
1486         if( rTxt.Len() > 0 )
1487         {
1488             aTxt += rSeparator;
1489         }
1490         xub_StrLen nSepIdx = aTxt.Len();
1491         aTxt += rTxt;
1492 
1493         //String einfuegen
1494         SwIndex aIdx( pNew, 0 );
1495         pNew->InsertText( aTxt, aIdx );
1496 
1497         //
1498         //Feld einfuegen
1499         if(pType)
1500         {
1501             SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC);
1502             if( bOrderNumberingFirst )
1503                 nIdx = 0;
1504             SwFmtFld aFmt( aFld );
1505             pNew->InsertItem( aFmt, nIdx, nIdx );
1506             if(rCharacterStyle.Len())
1507             {
1508                 SwCharFmt* pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1509                 if( !pCharFmt )
1510                 {
1511                     const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName(rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
1512                     pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1513                 }
1514                 if (pCharFmt)
1515                 {
1516                     SwFmtCharFmt aCharFmt( pCharFmt );
1517                     pNew->InsertItem( aCharFmt, 0,
1518                         nSepIdx + 1, nsSetAttrMode::SETATTR_DONTEXPAND );
1519                 }
1520             }
1521         }
1522 
1523         if ( bTable )
1524         {
1525             if ( bBefore )
1526             {
1527                 if ( !pNew->GetSwAttrSet().GetKeep().GetValue()  )
1528                     pNew->SetAttr( SvxFmtKeepItem( sal_True, RES_KEEP ) );
1529             }
1530             else
1531             {
1532                 SwTableNode *const pNd =
1533                     rDoc.GetNodes()[nNdIdx]->GetStartNode()->GetTableNode();
1534                 SwTable &rTbl = pNd->GetTable();
1535                 if ( !rTbl.GetFrmFmt()->GetKeep().GetValue() )
1536                     rTbl.GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem( sal_True, RES_KEEP ) );
1537                 if ( pUndo )
1538                     pUndo->SetUndoKeep();
1539             }
1540         }
1541         rDoc.SetModified();
1542     }
1543 
1544     return pNewFmt;
1545 }
1546 
1547 SwFlyFrmFmt *
1548 SwDoc::InsertLabel(
1549         SwLabelType const eType, String const& rTxt, String const& rSeparator,
1550         String const& rNumberingSeparator,
1551         sal_Bool const bBefore, sal_uInt16 const nId, sal_uLong const nNdIdx,
1552         String const& rCharacterStyle,
1553         sal_Bool const bCpyBrd )
1554 {
1555     SwUndoInsertLabel * pUndo(0);
1556     if (GetIDocumentUndoRedo().DoesUndo())
1557     {
1558         pUndo = new SwUndoInsertLabel(
1559                         eType, rTxt, rSeparator, rNumberingSeparator,
1560                         bBefore, nId, rCharacterStyle, bCpyBrd );
1561     }
1562 
1563     SwFlyFrmFmt *const pNewFmt = lcl_InsertLabel(*this, pTxtFmtCollTbl, pUndo,
1564             eType, rTxt, rSeparator, rNumberingSeparator, bBefore,
1565             nId, nNdIdx, rCharacterStyle, bCpyBrd);
1566 
1567     if (pUndo)
1568     {
1569         GetIDocumentUndoRedo().AppendUndo(pUndo);
1570     }
1571     else
1572     {
1573         GetIDocumentUndoRedo().DelAllUndoObj();
1574     }
1575 
1576     return pNewFmt;
1577 }
1578 
1579 
1580 /*************************************************************************
1581 |*
1582 |*  SwDoc::InsertDrawLabel()
1583 |*
1584 |*  Ersterstellung      MIB 7. Dez. 98
1585 |*  Letzte Aenderung    MIB 7. Dez. 98
1586 |*
1587 |*************************************************************************/
1588 
1589 static SwFlyFrmFmt *
1590 lcl_InsertDrawLabel( SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1591         SwUndoInsertLabel *const pUndo, SwDrawFrmFmt *const pOldFmt,
1592         String const& rTxt,
1593                                      const String& rSeparator,
1594                                      const String& rNumberSeparator,
1595                                      const sal_uInt16 nId,
1596                                      const String& rCharacterStyle,
1597                                      SdrObject& rSdrObj )
1598 {
1599     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1600     ::sw::DrawUndoGuard const drawUndoGuard(rDoc.GetIDocumentUndoRedo());
1601 
1602     // Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt
1603     // werden muss
1604     OSL_ENSURE( nId == USHRT_MAX  || nId < rDoc.GetFldTypes()->Count(),
1605             "FldType index out of bounds" );
1606     SwFieldType *pType = nId != USHRT_MAX ? (*rDoc.GetFldTypes())[nId] : 0;
1607     OSL_ENSURE( !pType || pType->Which() == RES_SETEXPFLD, "Wrong label id" );
1608 
1609     SwTxtFmtColl *pColl = NULL;
1610     if( pType )
1611     {
1612         for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; )
1613         {
1614             if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() )
1615             {
1616                 pColl = (*pTxtFmtCollTbl)[i];
1617                 break;
1618             }
1619         }
1620         DBG_ASSERT( pColl, "no text collection found" );
1621     }
1622 
1623     if( !pColl )
1624     {
1625         pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1626     }
1627 
1628     SwTxtNode* pNew = NULL;
1629     SwFlyFrmFmt* pNewFmt = NULL;
1630 
1631     // Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden
1632     // Node mit Feld in den neuen Rahmen, den alten Rahmen mit
1633     // dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen,
1634     // Frames erzeugen.
1635 
1636     // OD 27.11.2003 #112045# - Keep layer ID of drawing object before removing
1637     // its frames.
1638     // Note: The layer ID is passed to the undo and have to be the correct value.
1639     //       Removing the frames of the drawing object changes its layer.
1640     const SdrLayerID nLayerId = rSdrObj.GetLayer();
1641 
1642     pOldFmt->DelFrms();
1643 
1644     //Bei InCntnt's wird es spannend: Das TxtAttribut muss
1645     //vernichtet werden. Leider reisst dies neben den Frms auch
1646     //noch das Format mit in sein Grab. Um dass zu unterbinden
1647     //loesen wir vorher die Verbindung zwischen Attribut und Format.
1648     SfxItemSet* pNewSet = pOldFmt->GetAttrSet().Clone( sal_False );
1649 
1650     // Ggf. Groesse und Position des Rahmens schuetzen
1651     if ( rSdrObj.IsMoveProtect() || rSdrObj.IsResizeProtect() )
1652     {
1653         SvxProtectItem aProtect(RES_PROTECT);
1654         aProtect.SetCntntProtect( sal_False );
1655         aProtect.SetPosProtect( rSdrObj.IsMoveProtect() );
1656         aProtect.SetSizeProtect( rSdrObj.IsResizeProtect() );
1657         pNewSet->Put( aProtect );
1658     }
1659 
1660     // Umlauf uebernehmen
1661     lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1662 
1663     // Den Rahmen ggf. in den Hintergrund schicken.
1664     // OD 02.07.2003 #108784# - consider 'invisible' hell layer.
1665     if ( rDoc.GetHellId() != nLayerId &&
1666          rDoc.GetInvisibleHellId() != nLayerId )
1667     {
1668         SvxOpaqueItem aOpaque( RES_OPAQUE );
1669         aOpaque.SetValue( sal_True );
1670         pNewSet->Put( aOpaque );
1671     }
1672 
1673     // Position uebernehmen
1674     // OD 2004-04-15 #i26791# - use directly the positioning attributes of
1675     // the drawing object.
1676     pNewSet->Put( pOldFmt->GetHoriOrient() );
1677     pNewSet->Put( pOldFmt->GetVertOrient() );
1678 
1679     pNewSet->Put( pOldFmt->GetAnchor() );
1680 
1681     //In der Hoehe soll der neue Varabel sein!
1682     Size aSz( rSdrObj.GetCurrentBoundRect().GetSize() );
1683     SwFmtFrmSize aFrmSize( ATT_MIN_SIZE, aSz.Width(), aSz.Height() );
1684     pNewSet->Put( aFrmSize );
1685 
1686     // Abstaende auf den neuen Rahmen uebertragen. Eine Umrandung
1687     // gibt es beu Zeichen-Objekten nicht, also muss sie geloescht
1688     // werden.
1689     // MA: Falsch sie wird nicht gesetzt, denn die aus der Vorlage
1690     // soll ruhig wirksam werden
1691     pNewSet->Put( pOldFmt->GetLRSpace() );
1692     pNewSet->Put( pOldFmt->GetULSpace() );
1693 
1694     SwStartNode* pSttNd =
1695         rDoc.GetNodes().MakeTextSection(
1696             SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1697                                     SwFlyStartNode, pColl );
1698 
1699     pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1700                  rDoc.GetFrmFmtFromPool( RES_POOLFRM_FRAME ) );
1701 
1702     // JP 28.10.99: Bug 69487 - set border and shadow to default if the
1703     //              template contains any.
1704     if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( RES_BOX, sal_True ))
1705         pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1706 
1707     if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(RES_SHADOW,sal_True))
1708         pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1709 
1710     pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
1711     pNewFmt->SetFmtAttr( *pNewSet );
1712 
1713     const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1714     if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1715     {
1716         const SwPosition *pPos = rAnchor.GetCntntAnchor();
1717         SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1718         ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1719         const xub_StrLen nIdx = pPos->nContent.GetIndex();
1720         SwTxtAttr * const pHnt =
1721             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
1722 
1723 #ifdef DBG_UTIL
1724         ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1725                     "Missing FlyInCnt-Hint." );
1726         ASSERT( pHnt && ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).
1727                     GetFrmFmt() == (SwFrmFmt*)pOldFmt,
1728                     "Wrong TxtFlyCnt-Hint." );
1729 #endif
1730         const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt( pNewFmt );
1731     }
1732 
1733 
1734     //Der Alte soll keinen Umlauf haben, und er soll oben/mittig
1735     //ausgerichtet sein.
1736     pNewSet->ClearItem();
1737 
1738     pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1739     if (nLayerId == rDoc.GetHellId())
1740     {
1741         rSdrObj.SetLayer( rDoc.GetHeavenId() );
1742     }
1743     // OD 02.07.2003 #108784# - consider drawing objects in 'invisible' hell layer
1744     else if (nLayerId == rDoc.GetInvisibleHellId())
1745     {
1746         rSdrObj.SetLayer( rDoc.GetInvisibleHeavenId() );
1747     }
1748     pNewSet->Put( SvxLRSpaceItem( RES_LR_SPACE ) );
1749     pNewSet->Put( SvxULSpaceItem( RES_UL_SPACE ) );
1750 
1751     // OD 2004-04-15 #i26791# - set position of the drawing object, which is labeled.
1752     pNewSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ) );
1753     pNewSet->Put( SwFmtHoriOrient( 0, text::HoriOrientation::CENTER, text::RelOrientation::FRAME ) );
1754 
1755     //Der Alte ist absatzgebunden, und zwar am Absatz im neuen.
1756     SwFmtAnchor aAnch( FLY_AT_PARA );
1757     SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1758     pNew = aAnchIdx.GetNode().GetTxtNode();
1759     SwPosition aPos( aAnchIdx );
1760     aAnch.SetAnchor( &aPos );
1761     pNewSet->Put( aAnch );
1762 
1763     if( pUndo )
1764     {
1765         pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1766         // OD 2004-04-15 #i26791# - position no longer needed
1767         pUndo->SetDrawObj( nLayerId );
1768     }
1769     else
1770         pOldFmt->SetFmtAttr( *pNewSet );
1771 
1772     delete pNewSet;
1773 
1774     //Nun nur noch die Flys erzeugen lassen. Das ueberlassen
1775     //wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig).
1776     pNewFmt->MakeFrms();
1777 
1778     ASSERT( pNew, "No Label inserted" );
1779 
1780     if( pNew )
1781     {
1782         //#i61007# order of captions
1783         sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1784 
1785         // prepare string
1786         String aTxt;
1787         if( bOrderNumberingFirst )
1788         {
1789             aTxt = rNumberSeparator;
1790         }
1791         if ( pType )
1792         {
1793             aTxt += pType->GetName();
1794             if( !bOrderNumberingFirst )
1795                 aTxt += ' ';
1796         }
1797         xub_StrLen nIdx = aTxt.Len();
1798         aTxt += rSeparator;
1799         xub_StrLen nSepIdx = aTxt.Len();
1800         aTxt += rTxt;
1801 
1802         // insert text
1803         SwIndex aIdx( pNew, 0 );
1804         pNew->InsertText( aTxt, aIdx );
1805 
1806         // insert field
1807         if ( pType )
1808         {
1809             SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC );
1810             if( bOrderNumberingFirst )
1811                 nIdx = 0;
1812             SwFmtFld aFmt( aFld );
1813             pNew->InsertItem( aFmt, nIdx, nIdx );
1814             if ( rCharacterStyle.Len() )
1815             {
1816                 SwCharFmt * pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1817                 if ( !pCharFmt )
1818                 {
1819                     const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName( rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1820                     pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1821                 }
1822                 if ( pCharFmt )
1823                 {
1824                     SwFmtCharFmt aCharFmt( pCharFmt );
1825                     pNew->InsertItem( aCharFmt, 0, nSepIdx + 1,
1826                             nsSetAttrMode::SETATTR_DONTEXPAND );
1827                 }
1828             }
1829         }
1830     }
1831 
1832     return pNewFmt;
1833 }
1834 
1835 SwFlyFrmFmt* SwDoc::InsertDrawLabel(
1836         String const& rTxt,
1837         String const& rSeparator,
1838         String const& rNumberSeparator,
1839         sal_uInt16 const nId,
1840         String const& rCharacterStyle,
1841         SdrObject& rSdrObj )
1842 {
1843     SwDrawContact *const pContact =
1844         static_cast<SwDrawContact*>(GetUserCall( &rSdrObj ));
1845     OSL_ENSURE( RES_DRAWFRMFMT == pContact->GetFmt()->Which(),
1846             "InsertDrawLabel(): not a DrawFrmFmt" );
1847     if (!pContact)
1848         return 0;
1849 
1850     SwDrawFrmFmt* pOldFmt = (SwDrawFrmFmt *)pContact->GetFmt();
1851     if (!pOldFmt)
1852         return 0;
1853 
1854     SwUndoInsertLabel * pUndo = 0;
1855     if (GetIDocumentUndoRedo().DoesUndo())
1856     {
1857         GetIDocumentUndoRedo().ClearRedo();
1858         pUndo = new SwUndoInsertLabel(
1859             LTYPE_DRAW, rTxt, rSeparator, rNumberSeparator, sal_False,
1860             nId, rCharacterStyle, sal_False );
1861     }
1862 
1863     SwFlyFrmFmt *const pNewFmt = lcl_InsertDrawLabel(
1864         *this, pTxtFmtCollTbl, pUndo, pOldFmt,
1865         rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, rSdrObj);
1866 
1867     if (pUndo)
1868     {
1869         GetIDocumentUndoRedo().AppendUndo( pUndo );
1870     }
1871     else
1872     {
1873         GetIDocumentUndoRedo().DelAllUndoObj();
1874     }
1875 
1876     return pNewFmt;
1877 }
1878 
1879 
1880 /*************************************************************************
1881 |*
1882 |*  IDocumentTimerAccess-methods
1883 |*
1884 |*************************************************************************/
1885 
1886 void SwDoc::StartIdling()
1887 {
1888     mbStartIdleTimer = sal_True;
1889     if( !mIdleBlockCount )
1890         aIdleTimer.Start();
1891 }
1892 
1893 void SwDoc::StopIdling()
1894 {
1895     mbStartIdleTimer = sal_False;
1896     aIdleTimer.Stop();
1897 }
1898 
1899 void SwDoc::BlockIdling()
1900 {
1901     aIdleTimer.Stop();
1902     ++mIdleBlockCount;
1903 }
1904 
1905 void SwDoc::UnblockIdling()
1906 {
1907     --mIdleBlockCount;
1908     if( !mIdleBlockCount && mbStartIdleTimer && !aIdleTimer.IsActive() )
1909         aIdleTimer.Start();
1910 }
1911 
1912 
1913 /*************************************************************************
1914 |*
1915 |*  SwDoc::DoIdleJobs()
1916 |*
1917 |*  Ersterstellung      OK 30.03.94
1918 |*  Letzte Aenderung    MA 09. Jun. 95
1919 |*
1920 |*************************************************************************/
1921 
1922 IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
1923 {
1924 #ifdef TIMELOG
1925     static ::rtl::Logfile* pModLogFile = 0;
1926     if( !pModLogFile )
1927         pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
1928 #endif
1929 
1930     SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
1931     if( pTmpRoot &&
1932         !SfxProgress::GetActiveProgress( pDocShell ) )
1933     {
1934         ViewShell *pSh, *pStartSh;
1935         pSh = pStartSh = GetCurrentViewShell();
1936         do {
1937             if( pSh->ActionPend() )
1938             {
1939                 if( pTimer )
1940                     pTimer->Start();
1941                 return 0;
1942             }
1943             pSh = (ViewShell*)pSh->GetNext();
1944         } while( pSh != pStartSh );
1945 
1946         if( pTmpRoot->IsNeedGrammarCheck() )
1947         {
1948             sal_Bool bIsOnlineSpell = pSh->GetViewOptions()->IsOnlineSpell();
1949             sal_Bool bIsAutoGrammar = sal_False;
1950             SvtLinguConfig().GetProperty( ::rtl::OUString::createFromAscii(
1951                         UPN_IS_GRAMMAR_AUTO ) ) >>= bIsAutoGrammar;
1952 
1953             if (bIsOnlineSpell && bIsAutoGrammar)
1954                 StartGrammarChecking( *this );
1955         }
1956         SwFldUpdateFlags nFldUpdFlag;
1957         std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080320
1958         std::set<SwRootFrm*>::iterator pLayIter = aAllLayouts.begin();
1959         for ( ;pLayIter != aAllLayouts.end();pLayIter++ )
1960         {
1961             if ((*pLayIter)->IsIdleFormat())
1962             {
1963                 (*pLayIter)->GetCurrShell()->LayoutIdle();
1964                 break;
1965             }
1966         }
1967         bool bAllValid = pLayIter == aAllLayouts.end() ? 1 : 0;
1968         if( bAllValid && ( AUTOUPD_FIELD_ONLY ==
1969                  ( nFldUpdFlag = getFieldUpdateFlags(true) )
1970                     || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) &&
1971                 GetUpdtFlds().IsFieldsDirty() &&
1972                 !GetUpdtFlds().IsInUpdateFlds() &&
1973                 !IsExpFldsLocked()
1974                 // das umschalten der Feldname fuehrt zu keinem Update der
1975                 // Felder, also der "Hintergrund-Update" immer erfolgen
1976                 /* && !pStartSh->GetViewOptions()->IsFldName()*/ )
1977         {
1978             // chaos::Action-Klammerung!
1979             GetUpdtFlds().SetInUpdateFlds( sal_True );
1980 
1981             pTmpRoot->StartAllAction();
1982 
1983             // no jump on update of fields #i85168#
1984             const sal_Bool bOldLockView = pStartSh->IsViewLocked();
1985             pStartSh->LockView( sal_True );
1986 
1987             GetSysFldType( RES_CHAPTERFLD )->ModifyNotification( 0, 0 );    // KapitelFld
1988             UpdateExpFlds( 0, sal_False );      // Expression-Felder Updaten
1989             UpdateTblFlds(NULL);                // Tabellen
1990             UpdateRefFlds(NULL);                // Referenzen
1991 
1992             pTmpRoot->EndAllAction();
1993 
1994             pStartSh->LockView( bOldLockView );
1995 
1996             GetUpdtFlds().SetInUpdateFlds( sal_False );
1997             GetUpdtFlds().SetFieldsDirty( sal_False );
1998         }
1999     }   //swmod 080219
2000 #ifdef TIMELOG
2001     if( pModLogFile && 1 != (long)pModLogFile )
2002         delete pModLogFile, ((long&)pModLogFile) = 1;
2003 #endif
2004     if( pTimer )
2005         pTimer->Start();
2006     return 0;
2007 }
2008 
2009 IMPL_STATIC_LINK( SwDoc, BackgroundDone, SvxBrushItem*, EMPTYARG )
2010 {
2011     ViewShell *pSh, *pStartSh;
2012     pSh = pStartSh = pThis->GetCurrentViewShell();  //swmod 071108//swmod 071225
2013     if( pStartSh )
2014         do {
2015             if( pSh->GetWin() )
2016             {
2017                 //Fuer Repaint mir virtuellen Device sorgen.
2018                 pSh->LockPaint();
2019                 pSh->UnlockPaint( sal_True );
2020             }
2021             pSh = (ViewShell*)pSh->GetNext();
2022         } while( pSh != pStartSh );
2023     return 0;
2024 }
2025 
2026 static String lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId )
2027 {
2028     ResId aId( nDefStrId, *pSwResMgr );
2029     String aName( aId );
2030     xub_StrLen nNmLen = aName.Len();
2031 
2032     const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
2033 
2034     sal_uInt16 nNum, nTmp, nFlagSize = ( rFmts.Count() / 8 ) +2;
2035     sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
2036     sal_uInt16 n;
2037 
2038     memset( pSetFlags, 0, nFlagSize );
2039 
2040     for( n = 0; n < rFmts.Count(); ++n )
2041     {
2042         const SwFrmFmt* pFlyFmt = rFmts[ n ];
2043         if( RES_FLYFRMFMT == pFlyFmt->Which() &&
2044             pFlyFmt->GetName().Match( aName ) == nNmLen )
2045         {
2046             // Nummer bestimmen und das Flag setzen
2047             nNum = static_cast< sal_uInt16 >( pFlyFmt->GetName().Copy( nNmLen ).ToInt32() );
2048             if( nNum-- && nNum < rFmts.Count() )
2049                 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
2050         }
2051     }
2052 
2053     // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
2054     nNum = rFmts.Count();
2055     for( n = 0; n < nFlagSize; ++n )
2056         if( 0xff != ( nTmp = pSetFlags[ n ] ))
2057         {
2058             // also die Nummer bestimmen
2059             nNum = n * 8;
2060             while( nTmp & 1 )
2061                 ++nNum, nTmp >>= 1;
2062             break;
2063         }
2064 
2065     delete [] pSetFlags;
2066     return aName += String::CreateFromInt32( ++nNum );
2067 }
2068 
2069 String SwDoc::GetUniqueGrfName() const
2070 {
2071     return lcl_GetUniqueFlyName( this, STR_GRAPHIC_DEFNAME );
2072 }
2073 
2074 String SwDoc::GetUniqueOLEName() const
2075 {
2076     return lcl_GetUniqueFlyName( this, STR_OBJECT_DEFNAME );
2077 }
2078 
2079 String SwDoc::GetUniqueFrameName() const
2080 {
2081     return lcl_GetUniqueFlyName( this, STR_FRAME_DEFNAME );
2082 }
2083 
2084 const SwFlyFrmFmt* SwDoc::FindFlyByName( const String& rName, sal_Int8 nNdTyp ) const
2085 {
2086     const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
2087     for( sal_uInt16 n = rFmts.Count(); n; )
2088     {
2089         const SwFrmFmt* pFlyFmt = rFmts[ --n ];
2090         const SwNodeIndex* pIdx;
2091         if( RES_FLYFRMFMT == pFlyFmt->Which() && pFlyFmt->GetName() == rName &&
2092             0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) &&
2093             pIdx->GetNode().GetNodes().IsDocNodes() )
2094         {
2095             if( nNdTyp )
2096             {
2097                 // dann noch auf den richtigen Node-Typ abfragen
2098                 const SwNode* pNd = GetNodes()[ pIdx->GetIndex()+1 ];
2099                 if( nNdTyp == ND_TEXTNODE
2100                         ? !pNd->IsNoTxtNode()
2101                         : nNdTyp == pNd->GetNodeType() )
2102                     return (SwFlyFrmFmt*)pFlyFmt;
2103             }
2104             else
2105                 return (SwFlyFrmFmt*)pFlyFmt;
2106         }
2107     }
2108     return 0;
2109 }
2110 
2111 void SwDoc::SetFlyName( SwFlyFrmFmt& rFmt, const String& rName )
2112 {
2113     String sName( rName );
2114     if( !rName.Len() || FindFlyByName( rName ) )
2115     {
2116         sal_uInt16 nTyp = STR_FRAME_DEFNAME;
2117         const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx();
2118         if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() )
2119             switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2120             {
2121             case ND_GRFNODE:    nTyp = STR_GRAPHIC_DEFNAME; break;
2122             case ND_OLENODE:    nTyp = STR_OBJECT_DEFNAME;  break;
2123             }
2124         sName = lcl_GetUniqueFlyName( this, nTyp );
2125     }
2126     rFmt.SetName( sName, sal_True );
2127     SetModified();
2128 }
2129 
2130 void SwDoc::SetAllUniqueFlyNames()
2131 {
2132     sal_uInt16 n, nFlyNum = 0, nGrfNum = 0, nOLENum = 0;
2133 
2134     ResId nFrmId( STR_FRAME_DEFNAME, *pSwResMgr ),
2135           nGrfId( STR_GRAPHIC_DEFNAME, *pSwResMgr ),
2136           nOLEId( STR_OBJECT_DEFNAME, *pSwResMgr );
2137     String sFlyNm( nFrmId );
2138     String sGrfNm( nGrfId );
2139     String sOLENm( nOLEId );
2140 
2141     if( 255 < ( n = GetSpzFrmFmts()->Count() ))
2142         n = 255;
2143     SwSpzFrmFmts aArr( (sal_Int8)n, 10 );
2144     SwFrmFmtPtr pFlyFmt;
2145     bool bContainsAtPageObjWithContentAnchor = false;
2146 
2147     for( n = GetSpzFrmFmts()->Count(); n; )
2148     {
2149         if( RES_FLYFRMFMT == (pFlyFmt = (*GetSpzFrmFmts())[ --n ])->Which() )
2150         {
2151             sal_uInt16 *pNum = 0;
2152             xub_StrLen nLen;
2153             const String& rNm = pFlyFmt->GetName();
2154             if( rNm.Len() )
2155             {
2156                 if( rNm.Match( sGrfNm ) == ( nLen = sGrfNm.Len() ))
2157                     pNum = &nGrfNum;
2158                 else if( rNm.Match( sFlyNm ) == ( nLen = sFlyNm.Len() ))
2159                     pNum = &nFlyNum;
2160                 else if( rNm.Match( sOLENm ) == ( nLen = sOLENm.Len() ))
2161                     pNum = &nOLENum;
2162 
2163                 if ( pNum && *pNum < ( nLen = static_cast< xub_StrLen >( rNm.Copy( nLen ).ToInt32() ) ) )
2164                     *pNum = nLen;
2165             }
2166             else
2167                 // das wollen wir nachher setzen
2168                 aArr.Insert( pFlyFmt, aArr.Count() );
2169 
2170         }
2171         if ( !bContainsAtPageObjWithContentAnchor )
2172         {
2173             const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
2174             if ( (FLY_AT_PAGE == rAnchor.GetAnchorId()) &&
2175                  rAnchor.GetCntntAnchor() )
2176             {
2177                 bContainsAtPageObjWithContentAnchor = true;
2178             }
2179         }
2180     }
2181     SetContainsAtPageObjWithContentAnchor( bContainsAtPageObjWithContentAnchor );
2182 
2183     const SwNodeIndex* pIdx;
2184 
2185     for( n = aArr.Count(); n; )
2186         if( 0 != ( pIdx = ( pFlyFmt = aArr[ --n ])->GetCntnt().GetCntntIdx() )
2187             && pIdx->GetNode().GetNodes().IsDocNodes() )
2188         {
2189             sal_uInt16 nNum;
2190             String sNm;
2191             switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2192             {
2193             case ND_GRFNODE:
2194                 sNm = sGrfNm;
2195                 nNum = ++nGrfNum;
2196                 break;
2197             case ND_OLENODE:
2198                 sNm = sOLENm;
2199                 nNum = ++nOLENum;
2200                 break;
2201             default:
2202                 sNm = sFlyNm;
2203                 nNum = ++nFlyNum;
2204                 break;
2205             }
2206             pFlyFmt->SetName( sNm += String::CreateFromInt32( nNum ));
2207         }
2208     aArr.Remove( 0, aArr.Count() );
2209 
2210     if( GetFtnIdxs().Count() )
2211     {
2212         SwTxtFtn::SetUniqueSeqRefNo( *this );
2213         // --> FME 2005-08-02 #i52775# Chapter footnotes did not
2214         // get updated correctly. Calling UpdateAllFtn() instead of
2215         // UpdateFtn() solves this problem, but I do not dare to
2216         // call UpdateAllFtn() in all cases: Safety first.
2217         if ( FTNNUM_CHAPTER == GetFtnInfo().eNum )
2218         {
2219             GetFtnIdxs().UpdateAllFtn();
2220         }
2221         // <--
2222         else
2223         {
2224             SwNodeIndex aTmp( GetNodes() );
2225             GetFtnIdxs().UpdateFtn( aTmp );
2226         }
2227     }
2228 }
2229 
2230 sal_Bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
2231 {
2232     // gibt es ein Layout, dann ueber das laufen!!
2233     //  (Das kann dann auch Fly in Fly in Kopfzeile !)
2234     // MIB 9.2.98: Wird auch vom sw3io benutzt, um festzustellen, ob sich
2235     // ein Redline-Objekt in einer Kopf- oder Fusszeile befindet. Da
2236     // Redlines auch an Start- und Endnodes haengen, muss der Index nicht
2237     // unbedingt der eines Content-Nodes sein.
2238     SwNode* pNd = &rIdx.GetNode();
2239     if( pNd->IsCntntNode() && pCurrentView )//swmod 071029//swmod 071225
2240     {
2241         const SwFrm *pFrm = pNd->GetCntntNode()->getLayoutFrm( GetCurrentLayout() );
2242         if( pFrm )
2243         {
2244             const SwFrm *pUp = pFrm->GetUpper();
2245             while ( pUp && !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
2246             {
2247                 if ( pUp->IsFlyFrm() )
2248                     pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
2249                 pUp = pUp->GetUpper();
2250             }
2251             if ( pUp )
2252                 return sal_True;
2253 
2254             return sal_False;
2255         }
2256     }
2257 
2258 
2259     const SwNode* pFlyNd = pNd->FindFlyStartNode();
2260     while( pFlyNd )
2261     {
2262         // dann ueber den Anker nach oben "hangeln"
2263         sal_uInt16 n;
2264         for( n = 0; n < GetSpzFrmFmts()->Count(); ++n )
2265         {
2266             const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[ n ];
2267             const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
2268             if( pIdx && pFlyNd == &pIdx->GetNode() )
2269             {
2270                 const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
2271                 if ((FLY_AT_PAGE == rAnchor.GetAnchorId()) ||
2272                     !rAnchor.GetCntntAnchor() )
2273                 {
2274                     return sal_False;
2275                 }
2276 
2277                 pNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
2278                 pFlyNd = pNd->FindFlyStartNode();
2279                 break;
2280             }
2281         }
2282         if( n >= GetSpzFrmFmts()->Count() )
2283         {
2284             ASSERT( mbInReading, "Fly-Section aber kein Format gefunden" );
2285             return sal_False;
2286         }
2287     }
2288 
2289     return 0 != pNd->FindHeaderStartNode() ||
2290             0 != pNd->FindFooterStartNode();
2291 }
2292 
2293 short SwDoc::GetTextDirection( const SwPosition& rPos,
2294                                const Point* pPt ) const
2295 {
2296     short nRet = -1;
2297 
2298     SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
2299 
2300     // --> OD 2005-02-21 #i42921# - use new method <SwCntntNode::GetTextDirection(..)>
2301     if ( pNd )
2302     {
2303         nRet = pNd->GetTextDirection( rPos, pPt );
2304     }
2305     if ( nRet == -1 )
2306     // <--
2307     {
2308         const SvxFrameDirectionItem* pItem = 0;
2309         if( pNd )
2310         {
2311             // in a flyframe? Then look at that for the correct attribute
2312             const SwFrmFmt* pFlyFmt = pNd->GetFlyFmt();
2313             while( pFlyFmt )
2314             {
2315                 pItem = &pFlyFmt->GetFrmDir();
2316                 if( FRMDIR_ENVIRONMENT == pItem->GetValue() )
2317                 {
2318                     pItem = 0;
2319                     const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
2320                     if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
2321                         pAnchor->GetCntntAnchor())
2322                     {
2323                         pFlyFmt = pAnchor->GetCntntAnchor()->nNode.
2324                                             GetNode().GetFlyFmt();
2325                     }
2326                     else
2327                         pFlyFmt = 0;
2328                 }
2329                 else
2330                     pFlyFmt = 0;
2331             }
2332 
2333             if( !pItem )
2334             {
2335                 const SwPageDesc* pPgDsc = pNd->FindPageDesc( sal_False );
2336                 if( pPgDsc )
2337                     pItem = &pPgDsc->GetMaster().GetFrmDir();
2338             }
2339         }
2340         if( !pItem )
2341             pItem = (SvxFrameDirectionItem*)&GetAttrPool().GetDefaultItem(
2342                                                             RES_FRAMEDIR );
2343         nRet = pItem->GetValue();
2344     }
2345     return nRet;
2346 }
2347 
2348 sal_Bool SwDoc::IsInVerticalText( const SwPosition& rPos, const Point* pPt ) const
2349 {
2350     const short nDir = GetTextDirection( rPos, pPt );
2351     return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
2352 }
2353 
2354 void SwDoc::SetCurrentViewShell( ViewShell* pNew )
2355 {
2356     pCurrentView = pNew;
2357 }
2358 
2359 SwLayouter* SwDoc::GetLayouter()
2360 {
2361     return pLayouter;
2362 }
2363 
2364 const SwLayouter* SwDoc::GetLayouter() const
2365 {
2366     return pLayouter;
2367 }
2368 
2369 void SwDoc::SetLayouter( SwLayouter* pNew )
2370 {
2371     pLayouter = pNew;
2372 }
2373 
2374 const ViewShell *SwDoc::GetCurrentViewShell() const
2375 {
2376     return pCurrentView;
2377 }
2378 
2379 ViewShell *SwDoc::GetCurrentViewShell()
2380 {
2381     return pCurrentView;
2382 }   //swmod 080219 It must be able to communicate to a ViewShell.This is going to be removedd later.
2383 
2384 const SwRootFrm *SwDoc::GetCurrentLayout() const
2385 {
2386     if(GetCurrentViewShell())
2387         return GetCurrentViewShell()->GetLayout();
2388     return 0;
2389 }
2390 
2391 SwRootFrm *SwDoc::GetCurrentLayout()
2392 {
2393     if(GetCurrentViewShell())
2394         return GetCurrentViewShell()->GetLayout();
2395     return 0;
2396 }
2397 
2398 bool SwDoc::HasLayout() const
2399 {
2400     // if there is a view, there is always a layout
2401     return (pCurrentView != 0);
2402 }
2403 
2404 std::set<SwRootFrm*> SwDoc::GetAllLayouts()
2405 {
2406     std::set<SwRootFrm*> aAllLayouts;
2407     ViewShell *pStart = GetCurrentViewShell();
2408     ViewShell *pTemp = pStart;
2409     if ( pTemp )
2410     {
2411         do
2412         {
2413             if (pTemp->GetLayout())
2414             {
2415                 aAllLayouts.insert(pTemp->GetLayout());
2416                 pTemp = (ViewShell*)pTemp->GetNext();
2417             }
2418         } while(pTemp!=pStart);
2419     }
2420 
2421     return aAllLayouts;
2422 }//swmod 070825
2423 
2424 
2425 void SwDoc::ShareLayout(boost::shared_ptr<SwRootFrm>& rPtr)
2426 {
2427     pLayoutPtr = rPtr;
2428 }
2429 
2430