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