xref: /AOO41X/main/sw/source/core/doc/doclay.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 void SwDoc::GetAllFlyFmts( SwPosFlyFrms& rPosFlyFmts,
1088                            const SwPaM* pCmpRange, sal_Bool bDrawAlso ) const
1089 {
1090     SwPosFlyFrm *pFPos = 0;
1091     SwFrmFmt *pFly;
1092 
1093     // erstmal alle Absatzgebundenen einsammeln
1094     for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n )
1095     {
1096         pFly = (*GetSpzFrmFmts())[ n ];
1097         bool bDrawFmt = bDrawAlso ? RES_DRAWFRMFMT == pFly->Which() : false;
1098         bool bFlyFmt = RES_FLYFRMFMT == pFly->Which();
1099         if( bFlyFmt || bDrawFmt )
1100         {
1101             const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1102             SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1103             if (pAPos &&
1104                 ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1105                  (FLY_AT_FLY  == rAnchor.GetAnchorId()) ||
1106                  (FLY_AT_CHAR == rAnchor.GetAnchorId())))
1107             {
1108                 if( pCmpRange &&
1109                     !TstFlyRange( pCmpRange, pAPos, rAnchor.GetAnchorId() ))
1110                         continue;       // kein gueltiger FlyFrame
1111                 pFPos = new SwPosFlyFrm( pAPos->nNode, pFly, rPosFlyFmts.Count() );
1112                 rPosFlyFmts.Insert( pFPos );
1113             }
1114         }
1115     }
1116 
1117     // kein Layout oder nur ein Teil, dann wars das
1118     // Seitenbezogen Flys nur, wenn vollstaendig "gewuenscht" wird !
1119     if( !GetCurrentViewShell() || pCmpRange )   //swmod 071108//swmod 071225
1120         return;
1121 
1122     pFPos = 0;
1123     SwPageFrm *pPage = (SwPageFrm*)GetCurrentLayout()->GetLower();  //swmod 080218
1124     while( pPage )
1125     {
1126         if( pPage->GetSortedObjs() )
1127         {
1128             SwSortedObjs &rObjs = *pPage->GetSortedObjs();
1129             for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
1130             {
1131                 SwAnchoredObject* pAnchoredObj = rObjs[i];
1132                 if ( pAnchoredObj->ISA(SwFlyFrm) )
1133                     pFly = &(pAnchoredObj->GetFrmFmt());
1134                 else if ( bDrawAlso )
1135                     pFly = &(pAnchoredObj->GetFrmFmt());
1136                 else
1137                     continue;
1138 
1139                 const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1140                 if ((FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1141                     (FLY_AT_FLY  != rAnchor.GetAnchorId()) &&
1142                     (FLY_AT_CHAR != rAnchor.GetAnchorId()))
1143                 {
1144                     const SwCntntFrm * pCntntFrm = pPage->FindFirstBodyCntnt();
1145                     if ( !pCntntFrm )
1146                     {
1147                         //Oops! Eine leere Seite. Damit der Rahmen nicht ganz
1148                         //verlorengeht (RTF) suchen wir schnell den letzen
1149                         //Cntnt der vor der Seite steht.
1150                         SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev();
1151                         while ( !pCntntFrm && pPrv )
1152                         {
1153                             pCntntFrm = pPrv->FindFirstBodyCntnt();
1154                             pPrv = (SwPageFrm*)pPrv->GetPrev();
1155                         }
1156                     }
1157                     if ( pCntntFrm )
1158                     {
1159                         SwNodeIndex aIdx( *pCntntFrm->GetNode() );
1160                         pFPos = new SwPosFlyFrm( aIdx, pFly, rPosFlyFmts.Count() );
1161                     }
1162                 }
1163                 if ( pFPos )
1164                 {
1165                     rPosFlyFmts.Insert( pFPos );
1166                     pFPos = 0;
1167                 }
1168             }
1169         }
1170         pPage = (SwPageFrm*)pPage->GetNext();
1171     }
1172 }
1173 
1174 /*************************************************************************
1175 |*
1176 |*  SwDoc::InsertLabel()
1177 |*
1178 |*  Ersterstellung      MA 11. Feb. 94
1179 |*  Letzte Aenderung    MA 12. Nov. 97
1180 |*
1181 |*************************************************************************/
1182 
1183 /* #i6447# changed behaviour if lcl_CpyAttr:
1184 
1185    If the old item set contains the item to set (no inheritance) copy the item
1186    into the new set.
1187 
1188    If the old item set contains the item by inheritance and the new set
1189    contains the item, too:
1190       If the two items differ copy the item from the old set to the new set.
1191 
1192    Otherwise the new set will not be changed.
1193 */
1194 
1195 void lcl_CpyAttr( SfxItemSet &rNewSet, const SfxItemSet &rOldSet, sal_uInt16 nWhich )
1196 {
1197     const SfxPoolItem *pOldItem = NULL, *pNewItem = NULL;
1198 
1199     rOldSet.GetItemState( nWhich, sal_False, &pOldItem);
1200     if (pOldItem != NULL)
1201         rNewSet.Put( *pOldItem );
1202     else
1203     {
1204         pOldItem = rOldSet.GetItem( nWhich, sal_True);
1205         if (pOldItem != NULL)
1206         {
1207             pNewItem = rNewSet.GetItem( nWhich, sal_True);
1208             if (pNewItem != NULL)
1209             {
1210                 if (*pOldItem != *pNewItem)
1211                     rNewSet.Put( *pOldItem );
1212             }
1213             else {
1214                 ASSERT(0, "What am I doing here?");
1215             }
1216         }
1217         else {
1218             ASSERT(0, "What am I doing here?");
1219         }
1220     }
1221 
1222 }
1223 
1224 
1225 static SwFlyFrmFmt *
1226 lcl_InsertLabel(SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1227         SwUndoInsertLabel *const pUndo,
1228         SwLabelType const eType, String const& rTxt, String const& rSeparator,
1229             const String& rNumberingSeparator,
1230             const sal_Bool bBefore, const sal_uInt16 nId, const sal_uLong nNdIdx,
1231             const String& rCharacterStyle,
1232             const sal_Bool bCpyBrd )
1233 {
1234     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1235 
1236     sal_Bool bTable = sal_False;    //Um etwas Code zu sparen.
1237 
1238     //Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt werden
1239     //muss
1240     OSL_ENSURE( nId == USHRT_MAX  || nId < rDoc.GetFldTypes()->Count(),
1241             "FldType index out of bounds." );
1242     SwFieldType *pType = (nId != USHRT_MAX) ? (*rDoc.GetFldTypes())[nId] : NULL;
1243     OSL_ENSURE(!pType || pType->Which() == RES_SETEXPFLD, "wrong Id for Label");
1244 
1245     SwTxtFmtColl * pColl = NULL;
1246     if( pType )
1247     {
1248         for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; )
1249         {
1250             if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() )
1251             {
1252                 pColl = (*pTxtFmtCollTbl)[i];
1253                 break;
1254             }
1255         }
1256         DBG_ASSERT( pColl, "no text collection found" );
1257     }
1258 
1259     if( !pColl )
1260     {
1261         pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1262     }
1263 
1264     SwTxtNode *pNew = NULL;
1265     SwFlyFrmFmt* pNewFmt = NULL;
1266 
1267     switch ( eType )
1268     {
1269         case LTYPE_TABLE:
1270             bTable = sal_True;
1271             /* Kein Break hier */
1272         case LTYPE_FLY:
1273             //Am Anfang/Ende der Fly-Section den entsprechenden Node mit Feld
1274             //einfuegen (Frame wird automatisch erzeugt).
1275             {
1276                 SwStartNode *pSttNd = rDoc.GetNodes()[nNdIdx]->GetStartNode();
1277                 ASSERT( pSttNd, "Kein StartNode in InsertLabel." );
1278                 sal_uLong nNode;
1279                 if( bBefore )
1280                 {
1281                     nNode = pSttNd->GetIndex();
1282                     if( !bTable )
1283                         ++nNode;
1284                 }
1285                 else
1286                 {
1287                     nNode = pSttNd->EndOfSectionIndex();
1288                     if( bTable )
1289                         ++nNode;
1290                 }
1291 
1292                 if( pUndo )
1293                     pUndo->SetNodePos( nNode );
1294 
1295                 //Node fuer Beschriftungsabsatz erzeugen.
1296                 SwNodeIndex aIdx( rDoc.GetNodes(), nNode );
1297                 pNew = rDoc.GetNodes().MakeTxtNode( aIdx, pColl );
1298             }
1299             break;
1300 
1301         case LTYPE_OBJECT:
1302             {
1303                 //Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden
1304                 // Node mit Feld in den neuen Rahmen, den alten Rahmen mit
1305                 // dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen,
1306                 // Frames erzeugen.
1307 
1308                 //Erstmal das Format zum Fly besorgen und das Layout entkoppeln.
1309                 SwFrmFmt *pOldFmt = rDoc.GetNodes()[nNdIdx]->GetFlyFmt();
1310                 ASSERT( pOldFmt, "Format des Fly nicht gefunden." );
1311                 // --> OD #i115719#
1312                 // <title> and <description> attributes are lost when calling <DelFrms()>.
1313                 // Thus, keep them and restore them after the calling <MakeFrms()>
1314                 const bool bIsSwFlyFrmFmtInstance( dynamic_cast<SwFlyFrmFmt*>(pOldFmt) != 0 );
1315                 const String sTitle( bIsSwFlyFrmFmtInstance
1316                                      ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjTitle()
1317                                      : String() );
1318                 const String sDescription( bIsSwFlyFrmFmtInstance
1319                                            ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjDescription()
1320                                            : String() );
1321                 // <--
1322                 pOldFmt->DelFrms();
1323 
1324                 pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1325                                 rDoc.GetFrmFmtFromPool(RES_POOLFRM_FRAME) );
1326 
1327                 /* #i6447#: Only the selected items are copied from the old
1328                    format. */
1329                 SfxItemSet* pNewSet = pNewFmt->GetAttrSet().Clone( sal_True );
1330 
1331 
1332                 //Diejenigen Attribute uebertragen die auch gesetzt sind,
1333                 //andere sollen weiterhin aus den Vorlagen gueltig werden.
1334                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PRINT );
1335                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_OPAQUE );
1336                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PROTECT );
1337                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1338                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_VERT_ORIENT );
1339                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_HORI_ORIENT );
1340                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_LR_SPACE );
1341                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_UL_SPACE );
1342                 lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_BACKGROUND );
1343                 if( bCpyBrd )
1344                 {
1345                     // JP 07.07.99: Bug 67029 - if at Grafik no BoxItem but
1346                     //              in the new Format is any, then set the
1347                     //              default item in the new Set. Because
1348                     //              the Size of the Grafik have never been
1349                     //              changed!
1350                     const SfxPoolItem *pItem;
1351                     if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1352                             GetItemState( RES_BOX, sal_True, &pItem ))
1353                         pNewSet->Put( *pItem );
1354                     else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1355                             GetItemState( RES_BOX, sal_True ))
1356                         pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1357 
1358                     if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1359                             GetItemState( RES_SHADOW, sal_True, &pItem ))
1360                         pNewSet->Put( *pItem );
1361                     else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1362                             GetItemState( RES_SHADOW, sal_True ))
1363                         pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1364                 }
1365                 else
1366                 {
1367                     //Die Attribute hart setzen, weil sie sonst aus der
1368                     // Vorlage kommen koenten und dann passt die
1369                     // Grossenberechnung nicht mehr.
1370                     pNewSet->Put( SvxBoxItem(RES_BOX) );
1371                     pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1372 
1373                 }
1374 
1375                 //Anker immer uebertragen, ist sowieso ein hartes Attribut.
1376                 pNewSet->Put( pOldFmt->GetAnchor() );
1377 
1378                 //In der Hoehe soll der neue Varabel sein!
1379                 SwFmtFrmSize aFrmSize( pOldFmt->GetFrmSize() );
1380                 aFrmSize.SetHeightSizeType( ATT_MIN_SIZE );
1381                 pNewSet->Put( aFrmSize );
1382 
1383                 SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection(
1384                             SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1385                             SwFlyStartNode, pColl );
1386                 pNewSet->Put( SwFmtCntnt( pSttNd ));
1387 
1388                 pNewFmt->SetFmtAttr( *pNewSet );
1389 
1390                 //Bei InCntnt's wird es spannend: Das TxtAttribut muss
1391                 //vernichtet werden. Leider reisst dies neben den Frms auch
1392                 //noch das Format mit in sein Grab. Um dass zu unterbinden
1393                 //loesen wir vorher die Verbindung zwischen Attribut und Format.
1394 
1395                 const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1396                 if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1397                 {
1398                     const SwPosition *pPos = rAnchor.GetCntntAnchor();
1399                     SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1400                     ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1401                     const xub_StrLen nIdx = pPos->nContent.GetIndex();
1402                     SwTxtAttr * const pHnt =
1403                         pTxtNode->GetTxtAttrForCharAt(nIdx, RES_TXTATR_FLYCNT);
1404 
1405                     ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1406                                 "Missing FlyInCnt-Hint." );
1407                     ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pOldFmt,
1408                                 "Wrong TxtFlyCnt-Hint." );
1409 
1410                     const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(
1411                             pNewFmt );
1412                 }
1413 
1414 
1415                 //Der Alte soll keinen Umlauf haben, und er soll oben/mittig
1416                 //ausgerichtet sein.
1417                 //Ausserdem soll die Breite 100% betragen und bei Aenderungen
1418                 //Die Hoehe mit anpassen.
1419                 pNewSet->ClearItem();
1420 
1421                 pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1422                 pNewSet->Put( SvxOpaqueItem( RES_OPAQUE, sal_True ) );
1423                 pNewSet->Put( SwFmtVertOrient( text::VertOrientation::TOP ) );
1424                 pNewSet->Put( SwFmtHoriOrient( text::HoriOrientation::CENTER ) );
1425 
1426                 aFrmSize = pOldFmt->GetFrmSize();
1427                 aFrmSize.SetWidthPercent( 100 );
1428                 aFrmSize.SetHeightPercent( 255 );
1429                 pNewSet->Put( aFrmSize );
1430 
1431                 //Die Attribute setzen wir hart, weil sie sonst aus der Vorlage
1432                 //kommen koenten und dann passt die Grossenberechnung nicht mehr.
1433                 if( bCpyBrd )
1434                 {
1435                     pNewSet->Put( SvxBoxItem(RES_BOX) );
1436                     pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1437                 }
1438                 pNewSet->Put( SvxLRSpaceItem(RES_LR_SPACE) );
1439                 pNewSet->Put( SvxULSpaceItem(RES_UL_SPACE) );
1440 
1441                 //Der Alte ist absatzgebunden, und zwar am Absatz im neuen.
1442                 SwFmtAnchor aAnch( FLY_AT_PARA );
1443                 SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1444                 pNew = aAnchIdx.GetNode().GetTxtNode();
1445                 SwPosition aPos( aAnchIdx );
1446                 aAnch.SetAnchor( &aPos );
1447                 pNewSet->Put( aAnch );
1448 
1449                 if( pUndo )
1450                     pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1451                 else
1452                     pOldFmt->SetFmtAttr( *pNewSet );
1453 
1454                 delete pNewSet;
1455 
1456                 //Nun nur noch die Flys erzeugen lassen. Das ueberlassen
1457                 //wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig).
1458                 pNewFmt->MakeFrms();
1459                 // --> OD #i115719#
1460                 if ( bIsSwFlyFrmFmtInstance )
1461                 {
1462                     static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjTitle( sTitle );
1463                     static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjDescription( sDescription );
1464                 }
1465                 // <--
1466             }
1467             break;
1468 
1469         default:
1470             OSL_ENSURE(false, "unknown LabelType?");
1471     }
1472     ASSERT( pNew, "No Label inserted" );
1473     if( pNew )
1474     {
1475         //#i61007# order of captions
1476         sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1477         //String aufbereiten
1478         String aTxt;
1479         if( bOrderNumberingFirst )
1480         {
1481             aTxt = rNumberingSeparator;
1482         }
1483         if( pType)
1484         {
1485             aTxt += pType->GetName();
1486             if( !bOrderNumberingFirst )
1487                 aTxt += ' ';
1488         }
1489         xub_StrLen nIdx = aTxt.Len();
1490         if( rTxt.Len() > 0 )
1491         {
1492             aTxt += rSeparator;
1493         }
1494         xub_StrLen nSepIdx = aTxt.Len();
1495         aTxt += rTxt;
1496 
1497         //String einfuegen
1498         SwIndex aIdx( pNew, 0 );
1499         pNew->InsertText( aTxt, aIdx );
1500 
1501         //
1502         //Feld einfuegen
1503         if(pType)
1504         {
1505             SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC);
1506             if( bOrderNumberingFirst )
1507                 nIdx = 0;
1508             SwFmtFld aFmt( aFld );
1509             pNew->InsertItem( aFmt, nIdx, nIdx );
1510             if(rCharacterStyle.Len())
1511             {
1512                 SwCharFmt* pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1513                 if( !pCharFmt )
1514                 {
1515                     const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName(rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
1516                     pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1517                 }
1518                 if (pCharFmt)
1519                 {
1520                     SwFmtCharFmt aCharFmt( pCharFmt );
1521                     pNew->InsertItem( aCharFmt, 0,
1522                         nSepIdx + 1, nsSetAttrMode::SETATTR_DONTEXPAND );
1523                 }
1524             }
1525         }
1526 
1527         if ( bTable )
1528         {
1529             if ( bBefore )
1530             {
1531                 if ( !pNew->GetSwAttrSet().GetKeep().GetValue()  )
1532                     pNew->SetAttr( SvxFmtKeepItem( sal_True, RES_KEEP ) );
1533             }
1534             else
1535             {
1536                 SwTableNode *const pNd =
1537                     rDoc.GetNodes()[nNdIdx]->GetStartNode()->GetTableNode();
1538                 SwTable &rTbl = pNd->GetTable();
1539                 if ( !rTbl.GetFrmFmt()->GetKeep().GetValue() )
1540                     rTbl.GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem( sal_True, RES_KEEP ) );
1541                 if ( pUndo )
1542                     pUndo->SetUndoKeep();
1543             }
1544         }
1545         rDoc.SetModified();
1546     }
1547 
1548     return pNewFmt;
1549 }
1550 
1551 SwFlyFrmFmt *
1552 SwDoc::InsertLabel(
1553         SwLabelType const eType, String const& rTxt, String const& rSeparator,
1554         String const& rNumberingSeparator,
1555         sal_Bool const bBefore, sal_uInt16 const nId, sal_uLong const nNdIdx,
1556         String const& rCharacterStyle,
1557         sal_Bool const bCpyBrd )
1558 {
1559     SwUndoInsertLabel * pUndo(0);
1560     if (GetIDocumentUndoRedo().DoesUndo())
1561     {
1562         pUndo = new SwUndoInsertLabel(
1563                         eType, rTxt, rSeparator, rNumberingSeparator,
1564                         bBefore, nId, rCharacterStyle, bCpyBrd );
1565     }
1566 
1567     SwFlyFrmFmt *const pNewFmt = lcl_InsertLabel(*this, pTxtFmtCollTbl, pUndo,
1568             eType, rTxt, rSeparator, rNumberingSeparator, bBefore,
1569             nId, nNdIdx, rCharacterStyle, bCpyBrd);
1570 
1571     if (pUndo)
1572     {
1573         GetIDocumentUndoRedo().AppendUndo(pUndo);
1574     }
1575     else
1576     {
1577         GetIDocumentUndoRedo().DelAllUndoObj();
1578     }
1579 
1580     return pNewFmt;
1581 }
1582 
1583 
1584 /*************************************************************************
1585 |*
1586 |*  SwDoc::InsertDrawLabel()
1587 |*
1588 |*  Ersterstellung      MIB 7. Dez. 98
1589 |*  Letzte Aenderung    MIB 7. Dez. 98
1590 |*
1591 |*************************************************************************/
1592 
1593 static SwFlyFrmFmt *
1594 lcl_InsertDrawLabel( SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1595         SwUndoInsertLabel *const pUndo, SwDrawFrmFmt *const pOldFmt,
1596         String const& rTxt,
1597                                      const String& rSeparator,
1598                                      const String& rNumberSeparator,
1599                                      const sal_uInt16 nId,
1600                                      const String& rCharacterStyle,
1601                                      SdrObject& rSdrObj )
1602 {
1603     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1604     ::sw::DrawUndoGuard const drawUndoGuard(rDoc.GetIDocumentUndoRedo());
1605 
1606     // Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt
1607     // werden muss
1608     OSL_ENSURE( nId == USHRT_MAX  || nId < rDoc.GetFldTypes()->Count(),
1609             "FldType index out of bounds" );
1610     SwFieldType *pType = nId != USHRT_MAX ? (*rDoc.GetFldTypes())[nId] : 0;
1611     OSL_ENSURE( !pType || pType->Which() == RES_SETEXPFLD, "Wrong label id" );
1612 
1613     SwTxtFmtColl *pColl = NULL;
1614     if( pType )
1615     {
1616         for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; )
1617         {
1618             if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() )
1619             {
1620                 pColl = (*pTxtFmtCollTbl)[i];
1621                 break;
1622             }
1623         }
1624         DBG_ASSERT( pColl, "no text collection found" );
1625     }
1626 
1627     if( !pColl )
1628     {
1629         pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1630     }
1631 
1632     SwTxtNode* pNew = NULL;
1633     SwFlyFrmFmt* pNewFmt = NULL;
1634 
1635     // Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden
1636     // Node mit Feld in den neuen Rahmen, den alten Rahmen mit
1637     // dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen,
1638     // Frames erzeugen.
1639 
1640     // OD 27.11.2003 #112045# - Keep layer ID of drawing object before removing
1641     // its frames.
1642     // Note: The layer ID is passed to the undo and have to be the correct value.
1643     //       Removing the frames of the drawing object changes its layer.
1644     const SdrLayerID nLayerId = rSdrObj.GetLayer();
1645 
1646     pOldFmt->DelFrms();
1647 
1648     //Bei InCntnt's wird es spannend: Das TxtAttribut muss
1649     //vernichtet werden. Leider reisst dies neben den Frms auch
1650     //noch das Format mit in sein Grab. Um dass zu unterbinden
1651     //loesen wir vorher die Verbindung zwischen Attribut und Format.
1652     SfxItemSet* pNewSet = pOldFmt->GetAttrSet().Clone( sal_False );
1653 
1654     // Ggf. Groesse und Position des Rahmens schuetzen
1655     if ( rSdrObj.IsMoveProtect() || rSdrObj.IsResizeProtect() )
1656     {
1657         SvxProtectItem aProtect(RES_PROTECT);
1658         aProtect.SetCntntProtect( sal_False );
1659         aProtect.SetPosProtect( rSdrObj.IsMoveProtect() );
1660         aProtect.SetSizeProtect( rSdrObj.IsResizeProtect() );
1661         pNewSet->Put( aProtect );
1662     }
1663 
1664     // Umlauf uebernehmen
1665     lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1666 
1667     // Den Rahmen ggf. in den Hintergrund schicken.
1668     // OD 02.07.2003 #108784# - consider 'invisible' hell layer.
1669     if ( rDoc.GetHellId() != nLayerId &&
1670          rDoc.GetInvisibleHellId() != nLayerId )
1671     {
1672         SvxOpaqueItem aOpaque( RES_OPAQUE );
1673         aOpaque.SetValue( sal_True );
1674         pNewSet->Put( aOpaque );
1675     }
1676 
1677     // Position uebernehmen
1678     // OD 2004-04-15 #i26791# - use directly the positioning attributes of
1679     // the drawing object.
1680     pNewSet->Put( pOldFmt->GetHoriOrient() );
1681     pNewSet->Put( pOldFmt->GetVertOrient() );
1682 
1683     pNewSet->Put( pOldFmt->GetAnchor() );
1684 
1685     //In der Hoehe soll der neue Varabel sein!
1686     Size aSz( rSdrObj.GetCurrentBoundRect().GetSize() );
1687     SwFmtFrmSize aFrmSize( ATT_MIN_SIZE, aSz.Width(), aSz.Height() );
1688     pNewSet->Put( aFrmSize );
1689 
1690     // Abstaende auf den neuen Rahmen uebertragen. Eine Umrandung
1691     // gibt es beu Zeichen-Objekten nicht, also muss sie geloescht
1692     // werden.
1693     // MA: Falsch sie wird nicht gesetzt, denn die aus der Vorlage
1694     // soll ruhig wirksam werden
1695     pNewSet->Put( pOldFmt->GetLRSpace() );
1696     pNewSet->Put( pOldFmt->GetULSpace() );
1697 
1698     SwStartNode* pSttNd =
1699         rDoc.GetNodes().MakeTextSection(
1700             SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1701                                     SwFlyStartNode, pColl );
1702 
1703     pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1704                  rDoc.GetFrmFmtFromPool( RES_POOLFRM_FRAME ) );
1705 
1706     // JP 28.10.99: Bug 69487 - set border and shadow to default if the
1707     //              template contains any.
1708     if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( RES_BOX, sal_True ))
1709         pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1710 
1711     if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(RES_SHADOW,sal_True))
1712         pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1713 
1714     pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
1715     pNewFmt->SetFmtAttr( *pNewSet );
1716 
1717     const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1718     if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1719     {
1720         const SwPosition *pPos = rAnchor.GetCntntAnchor();
1721         SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1722         ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1723         const xub_StrLen nIdx = pPos->nContent.GetIndex();
1724         SwTxtAttr * const pHnt =
1725             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
1726 
1727 #ifdef DBG_UTIL
1728         ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1729                     "Missing FlyInCnt-Hint." );
1730         ASSERT( pHnt && ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).
1731                     GetFrmFmt() == (SwFrmFmt*)pOldFmt,
1732                     "Wrong TxtFlyCnt-Hint." );
1733 #endif
1734         const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt( pNewFmt );
1735     }
1736 
1737 
1738     //Der Alte soll keinen Umlauf haben, und er soll oben/mittig
1739     //ausgerichtet sein.
1740     pNewSet->ClearItem();
1741 
1742     pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1743     if (nLayerId == rDoc.GetHellId())
1744     {
1745         rSdrObj.SetLayer( rDoc.GetHeavenId() );
1746     }
1747     // OD 02.07.2003 #108784# - consider drawing objects in 'invisible' hell layer
1748     else if (nLayerId == rDoc.GetInvisibleHellId())
1749     {
1750         rSdrObj.SetLayer( rDoc.GetInvisibleHeavenId() );
1751     }
1752     pNewSet->Put( SvxLRSpaceItem( RES_LR_SPACE ) );
1753     pNewSet->Put( SvxULSpaceItem( RES_UL_SPACE ) );
1754 
1755     // OD 2004-04-15 #i26791# - set position of the drawing object, which is labeled.
1756     pNewSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ) );
1757     pNewSet->Put( SwFmtHoriOrient( 0, text::HoriOrientation::CENTER, text::RelOrientation::FRAME ) );
1758 
1759     //Der Alte ist absatzgebunden, und zwar am Absatz im neuen.
1760     SwFmtAnchor aAnch( FLY_AT_PARA );
1761     SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1762     pNew = aAnchIdx.GetNode().GetTxtNode();
1763     SwPosition aPos( aAnchIdx );
1764     aAnch.SetAnchor( &aPos );
1765     pNewSet->Put( aAnch );
1766 
1767     if( pUndo )
1768     {
1769         pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1770         // OD 2004-04-15 #i26791# - position no longer needed
1771         pUndo->SetDrawObj( nLayerId );
1772     }
1773     else
1774         pOldFmt->SetFmtAttr( *pNewSet );
1775 
1776     delete pNewSet;
1777 
1778     //Nun nur noch die Flys erzeugen lassen. Das ueberlassen
1779     //wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig).
1780     pNewFmt->MakeFrms();
1781 
1782     ASSERT( pNew, "No Label inserted" );
1783 
1784     if( pNew )
1785     {
1786         //#i61007# order of captions
1787         sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1788 
1789         // prepare string
1790         String aTxt;
1791         if( bOrderNumberingFirst )
1792         {
1793             aTxt = rNumberSeparator;
1794         }
1795         if ( pType )
1796         {
1797             aTxt += pType->GetName();
1798             if( !bOrderNumberingFirst )
1799                 aTxt += ' ';
1800         }
1801         xub_StrLen nIdx = aTxt.Len();
1802         aTxt += rSeparator;
1803         xub_StrLen nSepIdx = aTxt.Len();
1804         aTxt += rTxt;
1805 
1806         // insert text
1807         SwIndex aIdx( pNew, 0 );
1808         pNew->InsertText( aTxt, aIdx );
1809 
1810         // insert field
1811         if ( pType )
1812         {
1813             SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC );
1814             if( bOrderNumberingFirst )
1815                 nIdx = 0;
1816             SwFmtFld aFmt( aFld );
1817             pNew->InsertItem( aFmt, nIdx, nIdx );
1818             if ( rCharacterStyle.Len() )
1819             {
1820                 SwCharFmt * pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1821                 if ( !pCharFmt )
1822                 {
1823                     const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName( rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1824                     pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1825                 }
1826                 if ( pCharFmt )
1827                 {
1828                     SwFmtCharFmt aCharFmt( pCharFmt );
1829                     pNew->InsertItem( aCharFmt, 0, nSepIdx + 1,
1830                             nsSetAttrMode::SETATTR_DONTEXPAND );
1831                 }
1832             }
1833         }
1834     }
1835 
1836     return pNewFmt;
1837 }
1838 
1839 SwFlyFrmFmt* SwDoc::InsertDrawLabel(
1840         String const& rTxt,
1841         String const& rSeparator,
1842         String const& rNumberSeparator,
1843         sal_uInt16 const nId,
1844         String const& rCharacterStyle,
1845         SdrObject& rSdrObj )
1846 {
1847     SwDrawContact *const pContact =
1848         static_cast<SwDrawContact*>(GetUserCall( &rSdrObj ));
1849     OSL_ENSURE( RES_DRAWFRMFMT == pContact->GetFmt()->Which(),
1850             "InsertDrawLabel(): not a DrawFrmFmt" );
1851     if (!pContact)
1852         return 0;
1853 
1854     SwDrawFrmFmt* pOldFmt = (SwDrawFrmFmt *)pContact->GetFmt();
1855     if (!pOldFmt)
1856         return 0;
1857 
1858     SwUndoInsertLabel * pUndo = 0;
1859     if (GetIDocumentUndoRedo().DoesUndo())
1860     {
1861         GetIDocumentUndoRedo().ClearRedo();
1862         pUndo = new SwUndoInsertLabel(
1863             LTYPE_DRAW, rTxt, rSeparator, rNumberSeparator, sal_False,
1864             nId, rCharacterStyle, sal_False );
1865     }
1866 
1867     SwFlyFrmFmt *const pNewFmt = lcl_InsertDrawLabel(
1868         *this, pTxtFmtCollTbl, pUndo, pOldFmt,
1869         rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, rSdrObj);
1870 
1871     if (pUndo)
1872     {
1873         GetIDocumentUndoRedo().AppendUndo( pUndo );
1874     }
1875     else
1876     {
1877         GetIDocumentUndoRedo().DelAllUndoObj();
1878     }
1879 
1880     return pNewFmt;
1881 }
1882 
1883 
1884 /*************************************************************************
1885 |*
1886 |*  IDocumentTimerAccess-methods
1887 |*
1888 |*************************************************************************/
1889 
1890 void SwDoc::StartIdling()
1891 {
1892     mbStartIdleTimer = sal_True;
1893     if( !mIdleBlockCount )
1894         aIdleTimer.Start();
1895 }
1896 
1897 void SwDoc::StopIdling()
1898 {
1899     mbStartIdleTimer = sal_False;
1900     aIdleTimer.Stop();
1901 }
1902 
1903 void SwDoc::BlockIdling()
1904 {
1905     aIdleTimer.Stop();
1906     ++mIdleBlockCount;
1907 }
1908 
1909 void SwDoc::UnblockIdling()
1910 {
1911     --mIdleBlockCount;
1912     if( !mIdleBlockCount && mbStartIdleTimer && !aIdleTimer.IsActive() )
1913         aIdleTimer.Start();
1914 }
1915 
1916 
1917 /*************************************************************************
1918 |*
1919 |*  SwDoc::DoIdleJobs()
1920 |*
1921 |*  Ersterstellung      OK 30.03.94
1922 |*  Letzte Aenderung    MA 09. Jun. 95
1923 |*
1924 |*************************************************************************/
1925 
1926 IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
1927 {
1928 #ifdef TIMELOG
1929     static ::rtl::Logfile* pModLogFile = 0;
1930     if( !pModLogFile )
1931         pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
1932 #endif
1933 
1934     SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
1935     if( pTmpRoot &&
1936         !SfxProgress::GetActiveProgress( pDocShell ) )
1937     {
1938         ViewShell *pSh, *pStartSh;
1939         pSh = pStartSh = GetCurrentViewShell();
1940         do {
1941             if( pSh->ActionPend() )
1942             {
1943                 if( pTimer )
1944                     pTimer->Start();
1945                 return 0;
1946             }
1947             pSh = (ViewShell*)pSh->GetNext();
1948         } while( pSh != pStartSh );
1949 
1950         if( pTmpRoot->IsNeedGrammarCheck() )
1951         {
1952             sal_Bool bIsOnlineSpell = pSh->GetViewOptions()->IsOnlineSpell();
1953             sal_Bool bIsAutoGrammar = sal_False;
1954             SvtLinguConfig().GetProperty( ::rtl::OUString::createFromAscii(
1955                         UPN_IS_GRAMMAR_AUTO ) ) >>= bIsAutoGrammar;
1956 
1957             if (bIsOnlineSpell && bIsAutoGrammar)
1958                 StartGrammarChecking( *this );
1959         }
1960         SwFldUpdateFlags nFldUpdFlag;
1961         std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080320
1962         std::set<SwRootFrm*>::iterator pLayIter = aAllLayouts.begin();
1963         for ( ;pLayIter != aAllLayouts.end();pLayIter++ )
1964         {
1965             if ((*pLayIter)->IsIdleFormat())
1966             {
1967                 (*pLayIter)->GetCurrShell()->LayoutIdle();
1968                 break;
1969             }
1970         }
1971         bool bAllValid = pLayIter == aAllLayouts.end() ? 1 : 0;
1972         if( bAllValid && ( AUTOUPD_FIELD_ONLY ==
1973                  ( nFldUpdFlag = getFieldUpdateFlags(true) )
1974                     || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) &&
1975                 GetUpdtFlds().IsFieldsDirty() &&
1976                 !GetUpdtFlds().IsInUpdateFlds() &&
1977                 !IsExpFldsLocked()
1978                 // das umschalten der Feldname fuehrt zu keinem Update der
1979                 // Felder, also der "Hintergrund-Update" immer erfolgen
1980                 /* && !pStartSh->GetViewOptions()->IsFldName()*/ )
1981         {
1982             // chaos::Action-Klammerung!
1983             GetUpdtFlds().SetInUpdateFlds( sal_True );
1984 
1985             pTmpRoot->StartAllAction();
1986 
1987             // no jump on update of fields #i85168#
1988             const sal_Bool bOldLockView = pStartSh->IsViewLocked();
1989             pStartSh->LockView( sal_True );
1990 
1991             GetSysFldType( RES_CHAPTERFLD )->ModifyNotification( 0, 0 );    // KapitelFld
1992             UpdateExpFlds( 0, sal_False );      // Expression-Felder Updaten
1993             UpdateTblFlds(NULL);                // Tabellen
1994             UpdateRefFlds(NULL);                // Referenzen
1995 
1996             pTmpRoot->EndAllAction();
1997 
1998             pStartSh->LockView( bOldLockView );
1999 
2000             GetUpdtFlds().SetInUpdateFlds( sal_False );
2001             GetUpdtFlds().SetFieldsDirty( sal_False );
2002         }
2003     }   //swmod 080219
2004 #ifdef TIMELOG
2005     if( pModLogFile && 1 != (long)pModLogFile )
2006         delete pModLogFile, ((long&)pModLogFile) = 1;
2007 #endif
2008     if( pTimer )
2009         pTimer->Start();
2010     return 0;
2011 }
2012 
2013 IMPL_STATIC_LINK( SwDoc, BackgroundDone, SvxBrushItem*, EMPTYARG )
2014 {
2015     ViewShell *pSh, *pStartSh;
2016     pSh = pStartSh = pThis->GetCurrentViewShell();  //swmod 071108//swmod 071225
2017     if( pStartSh )
2018         do {
2019             if( pSh->GetWin() )
2020             {
2021                 //Fuer Repaint mir virtuellen Device sorgen.
2022                 pSh->LockPaint();
2023                 pSh->UnlockPaint( sal_True );
2024             }
2025             pSh = (ViewShell*)pSh->GetNext();
2026         } while( pSh != pStartSh );
2027     return 0;
2028 }
2029 
2030 static String lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId )
2031 {
2032     ResId aId( nDefStrId, *pSwResMgr );
2033     String aName( aId );
2034     xub_StrLen nNmLen = aName.Len();
2035 
2036     const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
2037 
2038     sal_uInt16 nNum, nTmp, nFlagSize = ( rFmts.Count() / 8 ) +2;
2039     sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
2040     sal_uInt16 n;
2041 
2042     memset( pSetFlags, 0, nFlagSize );
2043 
2044     for( n = 0; n < rFmts.Count(); ++n )
2045     {
2046         const SwFrmFmt* pFlyFmt = rFmts[ n ];
2047         if( RES_FLYFRMFMT == pFlyFmt->Which() &&
2048             pFlyFmt->GetName().Match( aName ) == nNmLen )
2049         {
2050             // Nummer bestimmen und das Flag setzen
2051             nNum = static_cast< sal_uInt16 >( pFlyFmt->GetName().Copy( nNmLen ).ToInt32() );
2052             if( nNum-- && nNum < rFmts.Count() )
2053                 pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
2054         }
2055     }
2056 
2057     // alle Nummern entsprechend geflag, also bestimme die richtige Nummer
2058     nNum = rFmts.Count();
2059     for( n = 0; n < nFlagSize; ++n )
2060         if( 0xff != ( nTmp = pSetFlags[ n ] ))
2061         {
2062             // also die Nummer bestimmen
2063             nNum = n * 8;
2064             while( nTmp & 1 )
2065                 ++nNum, nTmp >>= 1;
2066             break;
2067         }
2068 
2069     delete [] pSetFlags;
2070     return aName += String::CreateFromInt32( ++nNum );
2071 }
2072 
2073 String SwDoc::GetUniqueGrfName() const
2074 {
2075     return lcl_GetUniqueFlyName( this, STR_GRAPHIC_DEFNAME );
2076 }
2077 
2078 String SwDoc::GetUniqueOLEName() const
2079 {
2080     return lcl_GetUniqueFlyName( this, STR_OBJECT_DEFNAME );
2081 }
2082 
2083 String SwDoc::GetUniqueFrameName() const
2084 {
2085     return lcl_GetUniqueFlyName( this, STR_FRAME_DEFNAME );
2086 }
2087 
2088 const SwFlyFrmFmt* SwDoc::FindFlyByName( const String& rName, sal_Int8 nNdTyp ) const
2089 {
2090     const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
2091     for( sal_uInt16 n = rFmts.Count(); n; )
2092     {
2093         const SwFrmFmt* pFlyFmt = rFmts[ --n ];
2094         const SwNodeIndex* pIdx;
2095         if( RES_FLYFRMFMT == pFlyFmt->Which() && pFlyFmt->GetName() == rName &&
2096             0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) &&
2097             pIdx->GetNode().GetNodes().IsDocNodes() )
2098         {
2099             if( nNdTyp )
2100             {
2101                 // dann noch auf den richtigen Node-Typ abfragen
2102                 const SwNode* pNd = GetNodes()[ pIdx->GetIndex()+1 ];
2103                 if( nNdTyp == ND_TEXTNODE
2104                         ? !pNd->IsNoTxtNode()
2105                         : nNdTyp == pNd->GetNodeType() )
2106                     return (SwFlyFrmFmt*)pFlyFmt;
2107             }
2108             else
2109                 return (SwFlyFrmFmt*)pFlyFmt;
2110         }
2111     }
2112     return 0;
2113 }
2114 
2115 void SwDoc::SetFlyName( SwFlyFrmFmt& rFmt, const String& rName )
2116 {
2117     String sName( rName );
2118     if( !rName.Len() || FindFlyByName( rName ) )
2119     {
2120         sal_uInt16 nTyp = STR_FRAME_DEFNAME;
2121         const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx();
2122         if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() )
2123             switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2124             {
2125             case ND_GRFNODE:    nTyp = STR_GRAPHIC_DEFNAME; break;
2126             case ND_OLENODE:    nTyp = STR_OBJECT_DEFNAME;  break;
2127             }
2128         sName = lcl_GetUniqueFlyName( this, nTyp );
2129     }
2130     rFmt.SetName( sName, sal_True );
2131     SetModified();
2132 }
2133 
2134 void SwDoc::SetAllUniqueFlyNames()
2135 {
2136     sal_uInt16 n, nFlyNum = 0, nGrfNum = 0, nOLENum = 0;
2137 
2138     ResId nFrmId( STR_FRAME_DEFNAME, *pSwResMgr ),
2139           nGrfId( STR_GRAPHIC_DEFNAME, *pSwResMgr ),
2140           nOLEId( STR_OBJECT_DEFNAME, *pSwResMgr );
2141     String sFlyNm( nFrmId );
2142     String sGrfNm( nGrfId );
2143     String sOLENm( nOLEId );
2144 
2145     if( 255 < ( n = GetSpzFrmFmts()->Count() ))
2146         n = 255;
2147     SwSpzFrmFmts aArr( (sal_Int8)n, 10 );
2148     SwFrmFmtPtr pFlyFmt;
2149     sal_Bool bLoadedFlag = sal_True;            // noch etwas fuers Layout
2150 
2151     for( n = GetSpzFrmFmts()->Count(); n; )
2152     {
2153         if( RES_FLYFRMFMT == (pFlyFmt = (*GetSpzFrmFmts())[ --n ])->Which() )
2154         {
2155             sal_uInt16 *pNum = 0;
2156             xub_StrLen nLen;
2157             const String& rNm = pFlyFmt->GetName();
2158             if( rNm.Len() )
2159             {
2160                 if( rNm.Match( sGrfNm ) == ( nLen = sGrfNm.Len() ))
2161                     pNum = &nGrfNum;
2162                 else if( rNm.Match( sFlyNm ) == ( nLen = sFlyNm.Len() ))
2163                     pNum = &nFlyNum;
2164                 else if( rNm.Match( sOLENm ) == ( nLen = sOLENm.Len() ))
2165                     pNum = &nOLENum;
2166 
2167                 if ( pNum && *pNum < ( nLen = static_cast< xub_StrLen >( rNm.Copy( nLen ).ToInt32() ) ) )
2168                     *pNum = nLen;
2169             }
2170             else
2171                 // das wollen wir nachher setzen
2172                 aArr.Insert( pFlyFmt, aArr.Count() );
2173 
2174         }
2175         if( bLoadedFlag )
2176         {
2177             const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
2178             if (((FLY_AT_PAGE == rAnchor.GetAnchorId()) &&
2179                  rAnchor.GetCntntAnchor()) ||
2180                 // oder werden DrawObjecte rel. zu irgendetwas ausgerichtet?
2181                 ( RES_DRAWFRMFMT == pFlyFmt->Which() && (
2182                     SFX_ITEM_SET == pFlyFmt->GetItemState(
2183                                         RES_VERT_ORIENT )||
2184                     SFX_ITEM_SET == pFlyFmt->GetItemState(
2185                                         RES_HORI_ORIENT ))) )
2186             {
2187                 bLoadedFlag = sal_False;
2188             }
2189         }
2190     }
2191 
2192     const SwNodeIndex* pIdx;
2193 
2194     for( n = aArr.Count(); n; )
2195         if( 0 != ( pIdx = ( pFlyFmt = aArr[ --n ])->GetCntnt().GetCntntIdx() )
2196             && pIdx->GetNode().GetNodes().IsDocNodes() )
2197         {
2198             sal_uInt16 nNum;
2199             String sNm;
2200             switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2201             {
2202             case ND_GRFNODE:
2203                 sNm = sGrfNm;
2204                 nNum = ++nGrfNum;
2205                 break;
2206             case ND_OLENODE:
2207                 sNm = sOLENm;
2208                 nNum = ++nOLENum;
2209                 break;
2210             default:
2211                 sNm = sFlyNm;
2212                 nNum = ++nFlyNum;
2213                 break;
2214             }
2215             pFlyFmt->SetName( sNm += String::CreateFromInt32( nNum ));
2216         }
2217     aArr.Remove( 0, aArr.Count() );
2218 
2219     if( GetFtnIdxs().Count() )
2220     {
2221         SwTxtFtn::SetUniqueSeqRefNo( *this );
2222         // --> FME 2005-08-02 #i52775# Chapter footnotes did not
2223         // get updated correctly. Calling UpdateAllFtn() instead of
2224         // UpdateFtn() solves this problem, but I do not dare to
2225         // call UpdateAllFtn() in all cases: Safety first.
2226         if ( FTNNUM_CHAPTER == GetFtnInfo().eNum )
2227         {
2228             GetFtnIdxs().UpdateAllFtn();
2229         }
2230         // <--
2231         else
2232         {
2233             SwNodeIndex aTmp( GetNodes() );
2234             GetFtnIdxs().UpdateFtn( aTmp );
2235         }
2236     }
2237 
2238     // neues Document und keine seitengebundenen Rahmen/DrawObjecte gefunden,
2239     // die an einem Node verankert sind.
2240     if( bLoadedFlag )
2241         SetLoaded( sal_True );
2242 }
2243 
2244 sal_Bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
2245 {
2246     // gibt es ein Layout, dann ueber das laufen!!
2247     //  (Das kann dann auch Fly in Fly in Kopfzeile !)
2248     // MIB 9.2.98: Wird auch vom sw3io benutzt, um festzustellen, ob sich
2249     // ein Redline-Objekt in einer Kopf- oder Fusszeile befindet. Da
2250     // Redlines auch an Start- und Endnodes haengen, muss der Index nicht
2251     // unbedingt der eines Content-Nodes sein.
2252     SwNode* pNd = &rIdx.GetNode();
2253     if( pNd->IsCntntNode() && pCurrentView )//swmod 071029//swmod 071225
2254     {
2255         const SwFrm *pFrm = pNd->GetCntntNode()->getLayoutFrm( GetCurrentLayout() );
2256         if( pFrm )
2257         {
2258             const SwFrm *pUp = pFrm->GetUpper();
2259             while ( pUp && !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
2260             {
2261                 if ( pUp->IsFlyFrm() )
2262                     pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
2263                 pUp = pUp->GetUpper();
2264             }
2265             if ( pUp )
2266                 return sal_True;
2267 
2268             return sal_False;
2269         }
2270     }
2271 
2272 
2273     const SwNode* pFlyNd = pNd->FindFlyStartNode();
2274     while( pFlyNd )
2275     {
2276         // dann ueber den Anker nach oben "hangeln"
2277         sal_uInt16 n;
2278         for( n = 0; n < GetSpzFrmFmts()->Count(); ++n )
2279         {
2280             const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[ n ];
2281             const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
2282             if( pIdx && pFlyNd == &pIdx->GetNode() )
2283             {
2284                 const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
2285                 if ((FLY_AT_PAGE == rAnchor.GetAnchorId()) ||
2286                     !rAnchor.GetCntntAnchor() )
2287                 {
2288                     return sal_False;
2289                 }
2290 
2291                 pNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
2292                 pFlyNd = pNd->FindFlyStartNode();
2293                 break;
2294             }
2295         }
2296         if( n >= GetSpzFrmFmts()->Count() )
2297         {
2298             ASSERT( mbInReading, "Fly-Section aber kein Format gefunden" );
2299             return sal_False;
2300         }
2301     }
2302 
2303     return 0 != pNd->FindHeaderStartNode() ||
2304             0 != pNd->FindFooterStartNode();
2305 }
2306 
2307 short SwDoc::GetTextDirection( const SwPosition& rPos,
2308                                const Point* pPt ) const
2309 {
2310     short nRet = -1;
2311 
2312     SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
2313 
2314     // --> OD 2005-02-21 #i42921# - use new method <SwCntntNode::GetTextDirection(..)>
2315     if ( pNd )
2316     {
2317         nRet = pNd->GetTextDirection( rPos, pPt );
2318     }
2319     if ( nRet == -1 )
2320     // <--
2321     {
2322         const SvxFrameDirectionItem* pItem = 0;
2323         if( pNd )
2324         {
2325             // in a flyframe? Then look at that for the correct attribute
2326             const SwFrmFmt* pFlyFmt = pNd->GetFlyFmt();
2327             while( pFlyFmt )
2328             {
2329                 pItem = &pFlyFmt->GetFrmDir();
2330                 if( FRMDIR_ENVIRONMENT == pItem->GetValue() )
2331                 {
2332                     pItem = 0;
2333                     const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
2334                     if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
2335                         pAnchor->GetCntntAnchor())
2336                     {
2337                         pFlyFmt = pAnchor->GetCntntAnchor()->nNode.
2338                                             GetNode().GetFlyFmt();
2339                     }
2340                     else
2341                         pFlyFmt = 0;
2342                 }
2343                 else
2344                     pFlyFmt = 0;
2345             }
2346 
2347             if( !pItem )
2348             {
2349                 const SwPageDesc* pPgDsc = pNd->FindPageDesc( sal_False );
2350                 if( pPgDsc )
2351                     pItem = &pPgDsc->GetMaster().GetFrmDir();
2352             }
2353         }
2354         if( !pItem )
2355             pItem = (SvxFrameDirectionItem*)&GetAttrPool().GetDefaultItem(
2356                                                             RES_FRAMEDIR );
2357         nRet = pItem->GetValue();
2358     }
2359     return nRet;
2360 }
2361 
2362 sal_Bool SwDoc::IsInVerticalText( const SwPosition& rPos, const Point* pPt ) const
2363 {
2364     const short nDir = GetTextDirection( rPos, pPt );
2365     return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
2366 }
2367 
2368 void SwDoc::SetCurrentViewShell( ViewShell* pNew )
2369 {
2370     pCurrentView = pNew;
2371 }
2372 
2373 SwLayouter* SwDoc::GetLayouter()
2374 {
2375     return pLayouter;
2376 }
2377 
2378 const SwLayouter* SwDoc::GetLayouter() const
2379 {
2380     return pLayouter;
2381 }
2382 
2383 void SwDoc::SetLayouter( SwLayouter* pNew )
2384 {
2385     pLayouter = pNew;
2386 }
2387 
2388 const ViewShell *SwDoc::GetCurrentViewShell() const
2389 {
2390     return pCurrentView;
2391 }
2392 
2393 ViewShell *SwDoc::GetCurrentViewShell()
2394 {
2395     return pCurrentView;
2396 }   //swmod 080219 It must be able to communicate to a ViewShell.This is going to be removedd later.
2397 
2398 const SwRootFrm *SwDoc::GetCurrentLayout() const
2399 {
2400     if(GetCurrentViewShell())
2401         return GetCurrentViewShell()->GetLayout();
2402     return 0;
2403 }
2404 
2405 SwRootFrm *SwDoc::GetCurrentLayout()
2406 {
2407     if(GetCurrentViewShell())
2408         return GetCurrentViewShell()->GetLayout();
2409     return 0;
2410 }
2411 
2412 bool SwDoc::HasLayout() const
2413 {
2414     // if there is a view, there is always a layout
2415     return (pCurrentView != 0);
2416 }
2417 
2418 std::set<SwRootFrm*> SwDoc::GetAllLayouts()
2419 {
2420     std::set<SwRootFrm*> aAllLayouts;
2421     ViewShell *pStart = GetCurrentViewShell();
2422     ViewShell *pTemp = pStart;
2423     if ( pTemp )
2424     {
2425         do
2426         {
2427             if (pTemp->GetLayout())
2428             {
2429                 aAllLayouts.insert(pTemp->GetLayout());
2430                 pTemp = (ViewShell*)pTemp->GetNext();
2431             }
2432         } while(pTemp!=pStart);
2433     }
2434 
2435     return aAllLayouts;
2436 }//swmod 070825
2437 
2438 
2439 void SwDoc::ShareLayout(boost::shared_ptr<SwRootFrm>& rPtr)
2440 {
2441     pLayoutPtr = rPtr;
2442 }
2443 
2444