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