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