xref: /trunk/main/sw/source/core/doc/docfly.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_sw.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <hintids.hxx>
26cdf0e10cSrcweir #include <svl/itemiter.hxx>
27cdf0e10cSrcweir #include <svx/svdobj.hxx>
28cdf0e10cSrcweir #include <svx/svdpage.hxx>
29cdf0e10cSrcweir #include <svx/svdmodel.hxx>
30cdf0e10cSrcweir #include <svx/svdocapt.hxx>
31cdf0e10cSrcweir #include <svx/svdmark.hxx>
323f09c2ceSJürgen Schmidt #include <svx/xlndsit.hxx>
333f09c2ceSJürgen Schmidt #include <svx/xlnstit.hxx>
343f09c2ceSJürgen Schmidt #include <svx/xlnedit.hxx>
353f09c2ceSJürgen Schmidt #include <svx/xflhtit.hxx>
36cdf0e10cSrcweir #include <fmtfsize.hxx>
37cdf0e10cSrcweir #include <fmtornt.hxx>
38cdf0e10cSrcweir #include <fmtsrnd.hxx>
39cdf0e10cSrcweir #include <dcontact.hxx>
40cdf0e10cSrcweir #include <ndgrf.hxx>
41cdf0e10cSrcweir #include <doc.hxx>
42cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
43cdf0e10cSrcweir #include <ndindex.hxx>
44cdf0e10cSrcweir #include <docary.hxx>
45cdf0e10cSrcweir #include <fmtcntnt.hxx>
46cdf0e10cSrcweir #include <fmtanchr.hxx>
47cdf0e10cSrcweir #include <txtflcnt.hxx>
48cdf0e10cSrcweir #include <fmtflcnt.hxx>
49cdf0e10cSrcweir #include <txtfrm.hxx>
50cdf0e10cSrcweir #include <pagefrm.hxx>
51cdf0e10cSrcweir #include <rootfrm.hxx>
52cdf0e10cSrcweir #include <flyfrms.hxx>
53cdf0e10cSrcweir #include <frmtool.hxx>
54cdf0e10cSrcweir #include <frmfmt.hxx>
55cdf0e10cSrcweir #include <ndtxt.hxx>
56cdf0e10cSrcweir #include <pam.hxx>
57cdf0e10cSrcweir #include <tblsel.hxx>
58cdf0e10cSrcweir #include <swundo.hxx>
59cdf0e10cSrcweir #include <swtable.hxx>
60cdf0e10cSrcweir #include <crstate.hxx>
61cdf0e10cSrcweir #include <UndoCore.hxx>
62cdf0e10cSrcweir #include <UndoAttribute.hxx>
63cdf0e10cSrcweir #include <fmtcnct.hxx>
64cdf0e10cSrcweir #include <dflyobj.hxx>
65cdf0e10cSrcweir #include <undoflystrattr.hxx>
66cdf0e10cSrcweir #include <switerator.hxx>
6764b14621SArmin Le Grand #include <svx/xbtmpit.hxx>
6864b14621SArmin Le Grand #include <svx/xflftrit.hxx>
6926ea3662SArmin Le Grand #include <drawdoc.hxx>
7064b14621SArmin Le Grand 
71cdf0e10cSrcweir extern sal_uInt16 GetHtmlMode( const SwDocShell* );
72cdf0e10cSrcweir 
73cdf0e10cSrcweir using namespace ::com::sun::star;
74cdf0e10cSrcweir 
GetFlyCount(FlyCntType eType) const75cdf0e10cSrcweir sal_uInt16 SwDoc::GetFlyCount( FlyCntType eType ) const
76cdf0e10cSrcweir {
77cdf0e10cSrcweir     const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
78cdf0e10cSrcweir     sal_uInt16 nSize = rFmts.Count();
79cdf0e10cSrcweir     sal_uInt16 nCount = 0;
80cdf0e10cSrcweir     const SwNodeIndex* pIdx;
81cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < nSize; i++)
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir         const SwFrmFmt* pFlyFmt = rFmts[ i ];
84cdf0e10cSrcweir         if( RES_FLYFRMFMT == pFlyFmt->Which()
85cdf0e10cSrcweir             && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
86cdf0e10cSrcweir             && pIdx->GetNodes().IsDocNodes()
87cdf0e10cSrcweir             )
88cdf0e10cSrcweir         {
89cdf0e10cSrcweir             const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
90cdf0e10cSrcweir 
91cdf0e10cSrcweir             switch( eType )
92cdf0e10cSrcweir             {
93cdf0e10cSrcweir             case FLYCNTTYPE_FRM:
94cdf0e10cSrcweir                 if(!pNd->IsNoTxtNode())
95cdf0e10cSrcweir                     nCount++;
96cdf0e10cSrcweir                 break;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir             case FLYCNTTYPE_GRF:
99cdf0e10cSrcweir                 if( pNd->IsGrfNode() )
100cdf0e10cSrcweir                     nCount++;
101cdf0e10cSrcweir                 break;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir             case FLYCNTTYPE_OLE:
104cdf0e10cSrcweir                 if(pNd->IsOLENode())
105cdf0e10cSrcweir                     nCount++;
106cdf0e10cSrcweir                 break;
107cdf0e10cSrcweir 
108cdf0e10cSrcweir             default:
109cdf0e10cSrcweir                 nCount++;
110cdf0e10cSrcweir             }
111cdf0e10cSrcweir         }
112cdf0e10cSrcweir     }
113cdf0e10cSrcweir     return nCount;
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir // If you change this, also update SwXFrameEnumeration in unocoll.
GetFlyNum(sal_uInt16 nIdx,FlyCntType eType)117cdf0e10cSrcweir SwFrmFmt* SwDoc::GetFlyNum( sal_uInt16 nIdx, FlyCntType eType )
118cdf0e10cSrcweir {
119cdf0e10cSrcweir     SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
120cdf0e10cSrcweir     SwFrmFmt* pRetFmt = 0;
121cdf0e10cSrcweir     sal_uInt16 nSize = rFmts.Count();
122cdf0e10cSrcweir     const SwNodeIndex* pIdx;
123cdf0e10cSrcweir     sal_uInt16 nCount = 0;
124cdf0e10cSrcweir     for( sal_uInt16 i = 0; !pRetFmt && i < nSize; ++i )
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         SwFrmFmt* pFlyFmt = rFmts[ i ];
127cdf0e10cSrcweir         if( RES_FLYFRMFMT == pFlyFmt->Which()
128cdf0e10cSrcweir             && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() )
129cdf0e10cSrcweir             && pIdx->GetNodes().IsDocNodes()
130cdf0e10cSrcweir             )
131cdf0e10cSrcweir         {
132cdf0e10cSrcweir             const SwNode* pNd = GetNodes()[ pIdx->GetIndex() + 1 ];
133cdf0e10cSrcweir             switch( eType )
134cdf0e10cSrcweir             {
135cdf0e10cSrcweir             case FLYCNTTYPE_FRM:
136cdf0e10cSrcweir                 if( !pNd->IsNoTxtNode() && nIdx == nCount++)
137cdf0e10cSrcweir                     pRetFmt = pFlyFmt;
138cdf0e10cSrcweir                 break;
139cdf0e10cSrcweir             case FLYCNTTYPE_GRF:
140cdf0e10cSrcweir                 if(pNd->IsGrfNode() && nIdx == nCount++ )
141cdf0e10cSrcweir                     pRetFmt = pFlyFmt;
142cdf0e10cSrcweir                 break;
143cdf0e10cSrcweir             case FLYCNTTYPE_OLE:
144cdf0e10cSrcweir                 if(pNd->IsOLENode() && nIdx == nCount++)
145cdf0e10cSrcweir                     pRetFmt = pFlyFmt;
146cdf0e10cSrcweir                 break;
147cdf0e10cSrcweir             default:
148cdf0e10cSrcweir                 if(nIdx == nCount++)
149cdf0e10cSrcweir                     pRetFmt = pFlyFmt;
150cdf0e10cSrcweir             }
151cdf0e10cSrcweir         }
152cdf0e10cSrcweir     }
153cdf0e10cSrcweir     return pRetFmt;
154cdf0e10cSrcweir }
155cdf0e10cSrcweir 
lcl_FindAnchorLayPos(SwDoc & rDoc,const SwFmtAnchor & rAnch,const SwFrmFmt * pFlyFmt)156cdf0e10cSrcweir Point lcl_FindAnchorLayPos( SwDoc& rDoc, const SwFmtAnchor& rAnch,
157cdf0e10cSrcweir                             const SwFrmFmt* pFlyFmt )
158cdf0e10cSrcweir {
159cdf0e10cSrcweir     Point aRet;
160cdf0e10cSrcweir     if( rDoc.GetCurrentViewShell() )    //swmod 071107//swmod 071225
161cdf0e10cSrcweir         switch( rAnch.GetAnchorId() )
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir         case FLY_AS_CHAR:
164cdf0e10cSrcweir             if( pFlyFmt && rAnch.GetCntntAnchor() )
165cdf0e10cSrcweir             {
166cdf0e10cSrcweir                 const SwFrm* pOld = ((SwFlyFrmFmt*)pFlyFmt)->GetFrm( &aRet, sal_False );
167cdf0e10cSrcweir                 if( pOld )
168cdf0e10cSrcweir                     aRet = pOld->Frm().Pos();
169cdf0e10cSrcweir             }
170cdf0e10cSrcweir             break;
171cdf0e10cSrcweir 
172cdf0e10cSrcweir         case FLY_AT_PARA:
173cdf0e10cSrcweir         case FLY_AT_CHAR: // LAYER_IMPL
174cdf0e10cSrcweir             if( rAnch.GetCntntAnchor() )
175cdf0e10cSrcweir             {
176cdf0e10cSrcweir                 const SwPosition *pPos = rAnch.GetCntntAnchor();
177cdf0e10cSrcweir                 const SwCntntNode* pNd = pPos->nNode.GetNode().GetCntntNode();
178cdf0e10cSrcweir                 const SwFrm* pOld = pNd ? pNd->getLayoutFrm( rDoc.GetCurrentLayout(), &aRet, 0, sal_False ) : 0;
179cdf0e10cSrcweir                 if( pOld )
180cdf0e10cSrcweir                     aRet = pOld->Frm().Pos();
181cdf0e10cSrcweir             }
182cdf0e10cSrcweir             break;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir         case FLY_AT_FLY: // LAYER_IMPL
185cdf0e10cSrcweir             if( rAnch.GetCntntAnchor() )
186cdf0e10cSrcweir             {
187cdf0e10cSrcweir                 const SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)rAnch.GetCntntAnchor()->
188cdf0e10cSrcweir                                                 nNode.GetNode().GetFlyFmt();
189cdf0e10cSrcweir                 const SwFrm* pOld = pFmt ? pFmt->GetFrm( &aRet, sal_False ) : 0;
190cdf0e10cSrcweir                 if( pOld )
191cdf0e10cSrcweir                     aRet = pOld->Frm().Pos();
192cdf0e10cSrcweir             }
193cdf0e10cSrcweir             break;
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         case FLY_AT_PAGE:
196cdf0e10cSrcweir             {
197cdf0e10cSrcweir                 sal_uInt16 nPgNum = rAnch.GetPageNum();
198cdf0e10cSrcweir                 const SwPageFrm *pPage = (SwPageFrm*)rDoc.GetCurrentLayout()->Lower();
199cdf0e10cSrcweir                 for( sal_uInt16 i = 1; (i <= nPgNum) && pPage; ++i,
200cdf0e10cSrcweir                                     pPage = (const SwPageFrm*)pPage->GetNext() )
201cdf0e10cSrcweir                     if( i == nPgNum )
202cdf0e10cSrcweir                     {
203cdf0e10cSrcweir                         aRet = pPage->Frm().Pos();
204cdf0e10cSrcweir                         break;
205cdf0e10cSrcweir                     }
206cdf0e10cSrcweir             }
207cdf0e10cSrcweir             break;
208cdf0e10cSrcweir         default:
209cdf0e10cSrcweir             break;
210cdf0e10cSrcweir         }
211cdf0e10cSrcweir     return aRet;
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir #define MAKEFRMS 0
215cdf0e10cSrcweir #define IGNOREANCHOR 1
216cdf0e10cSrcweir #define DONTMAKEFRMS 2
217cdf0e10cSrcweir 
SetFlyFrmAnchor(SwFrmFmt & rFmt,SfxItemSet & rSet,sal_Bool bNewFrms)218cdf0e10cSrcweir sal_Int8 SwDoc::SetFlyFrmAnchor( SwFrmFmt& rFmt, SfxItemSet& rSet, sal_Bool bNewFrms )
219cdf0e10cSrcweir {
220cdf0e10cSrcweir     //Ankerwechsel sind fast immer in alle 'Richtungen' erlaubt.
221cdf0e10cSrcweir     //Ausnahme: Absatz- bzw. Zeichengebundene Rahmen duerfen wenn sie in
222cdf0e10cSrcweir     //Kopf-/Fusszeilen stehen nicht Seitengebunden werden.
223cdf0e10cSrcweir     const SwFmtAnchor &rOldAnch = rFmt.GetAnchor();
224cdf0e10cSrcweir     const RndStdIds nOld = rOldAnch.GetAnchorId();
225cdf0e10cSrcweir 
226cdf0e10cSrcweir     SwFmtAnchor aNewAnch( (SwFmtAnchor&)rSet.Get( RES_ANCHOR ) );
227cdf0e10cSrcweir     RndStdIds nNew = aNewAnch.GetAnchorId();
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     // ist der neue ein gueltiger Anker?
230cdf0e10cSrcweir     if( !aNewAnch.GetCntntAnchor() && (FLY_AT_FLY == nNew ||
231cdf0e10cSrcweir         (FLY_AT_PARA == nNew) || (FLY_AS_CHAR == nNew) ||
232cdf0e10cSrcweir         (FLY_AT_CHAR == nNew) ))
233cdf0e10cSrcweir     {
234cdf0e10cSrcweir         return IGNOREANCHOR;
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     if( nOld == nNew )
238cdf0e10cSrcweir         return DONTMAKEFRMS;
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 
241cdf0e10cSrcweir     Point aOldAnchorPos( ::lcl_FindAnchorLayPos( *this, rOldAnch, &rFmt ));
242cdf0e10cSrcweir     Point aNewAnchorPos( ::lcl_FindAnchorLayPos( *this, aNewAnch, 0 ));
243cdf0e10cSrcweir 
244cdf0e10cSrcweir     //Die alten Frms vernichten. Dabei werden die Views implizit gehidet und
245cdf0e10cSrcweir     //doppeltes hiden waere so eine art Show!
246cdf0e10cSrcweir     rFmt.DelFrms();
247cdf0e10cSrcweir 
248cdf0e10cSrcweir     if ( FLY_AS_CHAR == nOld )
249cdf0e10cSrcweir     {
250cdf0e10cSrcweir         //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
251cdf0e10cSrcweir         //werden. Leider reisst dies neben den Frms auch noch das Format mit
252cdf0e10cSrcweir         //in sein Grab. Um dass zu unterbinden loesen wir vorher die
253cdf0e10cSrcweir         //Verbindung zwischen Attribut und Format.
254cdf0e10cSrcweir         const SwPosition *pPos = rOldAnch.GetCntntAnchor();
255cdf0e10cSrcweir         SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
256cdf0e10cSrcweir         ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
257cdf0e10cSrcweir         const xub_StrLen nIdx = pPos->nContent.GetIndex();
258cdf0e10cSrcweir         SwTxtAttr * const  pHnt =
259cdf0e10cSrcweir             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
260cdf0e10cSrcweir         ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
261cdf0e10cSrcweir                     "Missing FlyInCnt-Hint." );
262cdf0e10cSrcweir         ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == &rFmt,
263cdf0e10cSrcweir                     "Wrong TxtFlyCnt-Hint." );
264cdf0e10cSrcweir         const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
265cdf0e10cSrcweir 
266cdf0e10cSrcweir         //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
267cdf0e10cSrcweir         //werden.
268cdf0e10cSrcweir         pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIdx, nIdx );
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     //Endlich kann das Attribut gesetzt werden. Es muss das erste Attribut
272cdf0e10cSrcweir     //sein; Undo depends on it!
273cdf0e10cSrcweir     rFmt.SetFmtAttr( aNewAnch );
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     //Positionskorrekturen
276cdf0e10cSrcweir     const SfxPoolItem* pItem;
277cdf0e10cSrcweir     switch( nNew )
278cdf0e10cSrcweir     {
279cdf0e10cSrcweir     case FLY_AS_CHAR:
280cdf0e10cSrcweir             //Wenn keine Positionsattribute hereinkommen, dann muss dafuer
281cdf0e10cSrcweir             //gesorgt werden, das keine unerlaubte automatische Ausrichtung
282cdf0e10cSrcweir             //bleibt.
283cdf0e10cSrcweir         {
284cdf0e10cSrcweir             const SwPosition *pPos = aNewAnch.GetCntntAnchor();
285cdf0e10cSrcweir             SwTxtNode *pNd = pPos->nNode.GetNode().GetTxtNode();
286cdf0e10cSrcweir             ASSERT( pNd, "Crsr steht nicht auf TxtNode." );
287cdf0e10cSrcweir 
288cdf0e10cSrcweir             SwFmtFlyCnt aFmt( static_cast<SwFlyFrmFmt*>(&rFmt) );
289cdf0e10cSrcweir             pNd->InsertItem( aFmt, pPos->nContent.GetIndex(), 0 );
290cdf0e10cSrcweir         }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem ))
293cdf0e10cSrcweir         {
294cdf0e10cSrcweir             SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
295cdf0e10cSrcweir             sal_Bool bSet = sal_True;
296cdf0e10cSrcweir             switch( aOldV.GetVertOrient() )
297cdf0e10cSrcweir             {
298cdf0e10cSrcweir             case text::VertOrientation::LINE_TOP:     aOldV.SetVertOrient( text::VertOrientation::TOP );   break;
299cdf0e10cSrcweir             case text::VertOrientation::LINE_CENTER:  aOldV.SetVertOrient( text::VertOrientation::CENTER); break;
300cdf0e10cSrcweir             case text::VertOrientation::LINE_BOTTOM:  aOldV.SetVertOrient( text::VertOrientation::BOTTOM); break;
301cdf0e10cSrcweir             case text::VertOrientation::NONE:         aOldV.SetVertOrient( text::VertOrientation::CENTER); break;
302cdf0e10cSrcweir             default:
303cdf0e10cSrcweir                 bSet = sal_False;
304cdf0e10cSrcweir             }
305cdf0e10cSrcweir             if( bSet )
306cdf0e10cSrcweir                 rSet.Put( aOldV );
307cdf0e10cSrcweir         }
308cdf0e10cSrcweir         break;
309cdf0e10cSrcweir 
310cdf0e10cSrcweir     case FLY_AT_PARA:
311cdf0e10cSrcweir     case FLY_AT_CHAR: // LAYER_IMPL
312cdf0e10cSrcweir     case FLY_AT_FLY: // LAYER_IMPL
313cdf0e10cSrcweir     case FLY_AT_PAGE:
314cdf0e10cSrcweir         {
315cdf0e10cSrcweir             //Wenn keine Positionsattribute hereinschneien korrigieren wir
316cdf0e10cSrcweir             //die Position so, dass die Dokumentkoordinaten des Flys erhalten
317cdf0e10cSrcweir             //bleiben.
318cdf0e10cSrcweir             //Chg: Wenn sich in den Positionsattributen lediglich die
319cdf0e10cSrcweir             //Ausrichtung veraendert (text::RelOrientation::FRAME vs. text::RelOrientation::PRTAREA), dann wird die
320cdf0e10cSrcweir             //Position ebenfalls korrigiert.
321cdf0e10cSrcweir             if( SFX_ITEM_SET != rSet.GetItemState( RES_HORI_ORIENT, sal_False, &pItem ))
322cdf0e10cSrcweir                 pItem = 0;
323cdf0e10cSrcweir 
324cdf0e10cSrcweir             SwFmtHoriOrient aOldH( rFmt.GetHoriOrient() );
325cdf0e10cSrcweir 
326cdf0e10cSrcweir             if( text::HoriOrientation::NONE == aOldH.GetHoriOrient() && ( !pItem ||
327cdf0e10cSrcweir                 aOldH.GetPos() == ((SwFmtHoriOrient*)pItem)->GetPos() ))
328cdf0e10cSrcweir             {
329cdf0e10cSrcweir                 SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldH.GetPos();
330cdf0e10cSrcweir                 nPos += aOldAnchorPos.X() - aNewAnchorPos.X();
331cdf0e10cSrcweir 
332cdf0e10cSrcweir                 if( pItem )
333cdf0e10cSrcweir                 {
334cdf0e10cSrcweir                     SwFmtHoriOrient* pH = (SwFmtHoriOrient*)pItem;
335cdf0e10cSrcweir                     aOldH.SetHoriOrient( pH->GetHoriOrient() );
336cdf0e10cSrcweir                     aOldH.SetRelationOrient( pH->GetRelationOrient() );
337cdf0e10cSrcweir                 }
338cdf0e10cSrcweir                 aOldH.SetPos( nPos );
339cdf0e10cSrcweir                 rSet.Put( aOldH );
340cdf0e10cSrcweir             }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir             if( SFX_ITEM_SET != rSet.GetItemState( RES_VERT_ORIENT, sal_False, &pItem ))
343cdf0e10cSrcweir                 pItem = 0;
344cdf0e10cSrcweir             SwFmtVertOrient aOldV( rFmt.GetVertOrient() );
345cdf0e10cSrcweir 
346cdf0e10cSrcweir             // OD 2004-05-14 #i28922# - correction: compare <aOldV.GetVertOrient()
347cdf0e10cSrcweir             // with <text::VertOrientation::NONE>
348cdf0e10cSrcweir             if( text::VertOrientation::NONE == aOldV.GetVertOrient() && (!pItem ||
349cdf0e10cSrcweir                 aOldV.GetPos() == ((SwFmtVertOrient*)pItem)->GetPos() ) )
350cdf0e10cSrcweir             {
351cdf0e10cSrcweir                 SwTwips nPos = (FLY_AS_CHAR == nOld) ? 0 : aOldV.GetPos();
352cdf0e10cSrcweir                 nPos += aOldAnchorPos.Y() - aNewAnchorPos.Y();
353cdf0e10cSrcweir                 if( pItem )
354cdf0e10cSrcweir                 {
355cdf0e10cSrcweir                     SwFmtVertOrient* pV = (SwFmtVertOrient*)pItem;
356cdf0e10cSrcweir                     aOldV.SetVertOrient( pV->GetVertOrient() );
357cdf0e10cSrcweir                     aOldV.SetRelationOrient( pV->GetRelationOrient() );
358cdf0e10cSrcweir                 }
359cdf0e10cSrcweir                 aOldV.SetPos( nPos );
360cdf0e10cSrcweir                 rSet.Put( aOldV );
361cdf0e10cSrcweir             }
362cdf0e10cSrcweir         }
363cdf0e10cSrcweir         break;
364cdf0e10cSrcweir     default:
365cdf0e10cSrcweir         break;
366cdf0e10cSrcweir     }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir     if( bNewFrms )
369cdf0e10cSrcweir         rFmt.MakeFrms();
370cdf0e10cSrcweir 
371cdf0e10cSrcweir     return MAKEFRMS;
372cdf0e10cSrcweir }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir static bool
lcl_SetFlyFrmAttr(SwDoc & rDoc,sal_Int8 (SwDoc::* pSetFlyFrmAnchor)(SwFrmFmt &,SfxItemSet &,sal_Bool),SwFrmFmt & rFlyFmt,SfxItemSet & rSet)375cdf0e10cSrcweir lcl_SetFlyFrmAttr(SwDoc & rDoc,
376cdf0e10cSrcweir         sal_Int8 (SwDoc::*pSetFlyFrmAnchor)(SwFrmFmt &, SfxItemSet &, sal_Bool),
377cdf0e10cSrcweir         SwFrmFmt & rFlyFmt, SfxItemSet & rSet)
378cdf0e10cSrcweir {
379cdf0e10cSrcweir     // #i32968# Inserting columns in the frame causes MakeFrmFmt to put two
380cdf0e10cSrcweir     // objects of type SwUndoFrmFmt on the undo stack. We don't want them.
381cdf0e10cSrcweir     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
382cdf0e10cSrcweir 
383cdf0e10cSrcweir     //Ist das Ankerattribut dabei? Falls ja ueberlassen wir die Verarbeitung
384cdf0e10cSrcweir     //desselben einer Spezialmethode. Sie Returnt sal_True wenn der Fly neu
385cdf0e10cSrcweir     //erzeugt werden muss (z.B. weil ein Wechsel des FlyTyps vorliegt).
386cdf0e10cSrcweir     sal_Int8 const nMakeFrms =
387cdf0e10cSrcweir         (SFX_ITEM_SET == rSet.GetItemState( RES_ANCHOR, sal_False ))
388cdf0e10cSrcweir              ?  (rDoc.*pSetFlyFrmAnchor)( rFlyFmt, rSet, sal_False )
389cdf0e10cSrcweir              :  DONTMAKEFRMS;
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     const SfxPoolItem* pItem;
392cdf0e10cSrcweir     SfxItemIter aIter( rSet );
393cdf0e10cSrcweir     SfxItemSet aTmpSet( rDoc.GetAttrPool(), aFrmFmtSetRange );
394cdf0e10cSrcweir     sal_uInt16 nWhich = aIter.GetCurItem()->Which();
395cdf0e10cSrcweir     do {
396cdf0e10cSrcweir         switch( nWhich )
397cdf0e10cSrcweir         {
398cdf0e10cSrcweir         case RES_FILL_ORDER:
399cdf0e10cSrcweir         case RES_BREAK:
400cdf0e10cSrcweir         case RES_PAGEDESC:
401cdf0e10cSrcweir         case RES_CNTNT:
402cdf0e10cSrcweir         case RES_FOOTER:
403cdf0e10cSrcweir             OSL_ENSURE(false, ":-) unknown Attribute for Fly.");
404cdf0e10cSrcweir             // kein break;
405cdf0e10cSrcweir         case RES_CHAIN:
406cdf0e10cSrcweir             rSet.ClearItem( nWhich );
407cdf0e10cSrcweir             break;
408cdf0e10cSrcweir         case RES_ANCHOR:
409cdf0e10cSrcweir             if( DONTMAKEFRMS != nMakeFrms )
410cdf0e10cSrcweir                 break;
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         default:
413cdf0e10cSrcweir             if( !IsInvalidItem( aIter.GetCurItem() ) && ( SFX_ITEM_SET !=
414cdf0e10cSrcweir                 rFlyFmt.GetAttrSet().GetItemState( nWhich, sal_True, &pItem ) ||
415cdf0e10cSrcweir                 *pItem != *aIter.GetCurItem() ))
416cdf0e10cSrcweir                 aTmpSet.Put( *aIter.GetCurItem() );
417cdf0e10cSrcweir             break;
418cdf0e10cSrcweir         }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir         if( aIter.IsAtEnd() )
421cdf0e10cSrcweir             break;
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     } while( 0 != ( nWhich = aIter.NextItem()->Which() ) );
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     if( aTmpSet.Count() )
426cdf0e10cSrcweir         rFlyFmt.SetFmtAttr( aTmpSet );
427cdf0e10cSrcweir 
428cdf0e10cSrcweir     if( MAKEFRMS == nMakeFrms )
429cdf0e10cSrcweir         rFlyFmt.MakeFrms();
430cdf0e10cSrcweir 
431cdf0e10cSrcweir     return aTmpSet.Count() || MAKEFRMS == nMakeFrms;
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
CheckForUniqueItemForLineFillNameOrIndex(SfxItemSet & rSet)43464b14621SArmin Le Grand void SwDoc::CheckForUniqueItemForLineFillNameOrIndex(SfxItemSet& rSet)
43564b14621SArmin Le Grand {
43626ea3662SArmin Le Grand     SwDrawModel* pDrawModel = GetOrCreateDrawModel();
43764b14621SArmin Le Grand     SfxItemIter aIter(rSet);
43864b14621SArmin Le Grand 
43964b14621SArmin Le Grand     for(const SfxPoolItem* pItem = aIter.FirstItem(); pItem; pItem = aIter.NextItem())
44064b14621SArmin Le Grand     {
44164b14621SArmin Le Grand         const SfxPoolItem* pResult = pItem;
44264b14621SArmin Le Grand 
44364b14621SArmin Le Grand         switch(pItem->Which())
44464b14621SArmin Le Grand         {
44564b14621SArmin Le Grand             case XATTR_FILLBITMAP:
44664b14621SArmin Le Grand             {
44764b14621SArmin Le Grand                 pResult = static_cast< const XFillBitmapItem* >(pItem)->checkForUniqueItem(pDrawModel);
44864b14621SArmin Le Grand                 break;
44964b14621SArmin Le Grand             }
45064b14621SArmin Le Grand             case XATTR_LINEDASH:
45164b14621SArmin Le Grand             {
45264b14621SArmin Le Grand                 pResult = static_cast< const XLineDashItem* >(pItem)->checkForUniqueItem(pDrawModel);
45364b14621SArmin Le Grand                 break;
45464b14621SArmin Le Grand             }
45564b14621SArmin Le Grand             case XATTR_LINESTART:
45664b14621SArmin Le Grand             {
45764b14621SArmin Le Grand                 pResult = static_cast< const XLineStartItem* >(pItem)->checkForUniqueItem(pDrawModel);
45864b14621SArmin Le Grand                 break;
45964b14621SArmin Le Grand             }
46064b14621SArmin Le Grand             case XATTR_LINEEND:
46164b14621SArmin Le Grand             {
46264b14621SArmin Le Grand                 pResult = static_cast< const XLineEndItem* >(pItem)->checkForUniqueItem(pDrawModel);
46364b14621SArmin Le Grand                 break;
46464b14621SArmin Le Grand             }
46564b14621SArmin Le Grand             case XATTR_FILLGRADIENT:
46664b14621SArmin Le Grand             {
46764b14621SArmin Le Grand                 pResult = static_cast< const XFillGradientItem* >(pItem)->checkForUniqueItem(pDrawModel);
46864b14621SArmin Le Grand                 break;
46964b14621SArmin Le Grand             }
47064b14621SArmin Le Grand             case XATTR_FILLFLOATTRANSPARENCE:
47164b14621SArmin Le Grand             {
47264b14621SArmin Le Grand                 pResult = static_cast< const XFillFloatTransparenceItem* >(pItem)->checkForUniqueItem(pDrawModel);
47364b14621SArmin Le Grand                 break;
47464b14621SArmin Le Grand             }
47564b14621SArmin Le Grand             case XATTR_FILLHATCH:
47664b14621SArmin Le Grand             {
47764b14621SArmin Le Grand                 pResult = static_cast< const XFillHatchItem* >(pItem)->checkForUniqueItem(pDrawModel);
47864b14621SArmin Le Grand                 break;
47964b14621SArmin Le Grand             }
48064b14621SArmin Le Grand         }
48164b14621SArmin Le Grand 
48264b14621SArmin Le Grand         if(pResult != pItem)
48364b14621SArmin Le Grand         {
48464b14621SArmin Le Grand             rSet.Put(*pResult);
48564b14621SArmin Le Grand             delete pResult;
48664b14621SArmin Le Grand         }
48764b14621SArmin Le Grand     }
48864b14621SArmin Le Grand }
48964b14621SArmin Le Grand 
SetFlyFrmAttr(SwFrmFmt & rFlyFmt,SfxItemSet & rSet)490cdf0e10cSrcweir sal_Bool SwDoc::SetFlyFrmAttr( SwFrmFmt& rFlyFmt, SfxItemSet& rSet )
491cdf0e10cSrcweir {
492cdf0e10cSrcweir     if( !rSet.Count() )
493cdf0e10cSrcweir         return sal_False;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     ::std::auto_ptr<SwUndoFmtAttrHelper> pSaveUndo;
496cdf0e10cSrcweir 
497cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
498cdf0e10cSrcweir     {
499cdf0e10cSrcweir         GetIDocumentUndoRedo().ClearRedo(); // AppendUndo far below, so leave it
500cdf0e10cSrcweir         pSaveUndo.reset( new SwUndoFmtAttrHelper( rFlyFmt ) );
501cdf0e10cSrcweir     }
502cdf0e10cSrcweir 
50356b35d86SArmin Le Grand     bool const bRet = lcl_SetFlyFrmAttr(*this, &SwDoc::SetFlyFrmAnchor, rFlyFmt, rSet);
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     if ( pSaveUndo.get() )
506cdf0e10cSrcweir     {
507cdf0e10cSrcweir         if ( pSaveUndo->GetUndo() )
508cdf0e10cSrcweir         {
509cdf0e10cSrcweir             GetIDocumentUndoRedo().AppendUndo( pSaveUndo->ReleaseUndo() );
510cdf0e10cSrcweir         }
511cdf0e10cSrcweir     }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir     SetModified();
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     return bRet;
516cdf0e10cSrcweir }
517cdf0e10cSrcweir 
518cdf0e10cSrcweir // --> OD 2009-07-20 #i73249#
SetFlyFrmTitle(SwFlyFrmFmt & rFlyFrmFmt,const String & sNewTitle)519cdf0e10cSrcweir void SwDoc::SetFlyFrmTitle( SwFlyFrmFmt& rFlyFrmFmt,
520cdf0e10cSrcweir                             const String& sNewTitle )
521cdf0e10cSrcweir {
522cdf0e10cSrcweir     if ( rFlyFrmFmt.GetObjTitle() == sNewTitle )
523cdf0e10cSrcweir     {
524cdf0e10cSrcweir         return;
525cdf0e10cSrcweir     }
526cdf0e10cSrcweir 
527cdf0e10cSrcweir     ::sw::DrawUndoGuard const drawUndoGuard(GetIDocumentUndoRedo());
528cdf0e10cSrcweir 
529cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
530cdf0e10cSrcweir     {
531cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
532cdf0e10cSrcweir                                           UNDO_FLYFRMFMT_TITLE,
533cdf0e10cSrcweir                                           rFlyFrmFmt.GetObjTitle(),
534cdf0e10cSrcweir                                           sNewTitle ) );
535cdf0e10cSrcweir     }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir     rFlyFrmFmt.SetObjTitle( sNewTitle, true );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir     SetModified();
540cdf0e10cSrcweir }
541cdf0e10cSrcweir 
SetFlyFrmDescription(SwFlyFrmFmt & rFlyFrmFmt,const String & sNewDescription)542cdf0e10cSrcweir void SwDoc::SetFlyFrmDescription( SwFlyFrmFmt& rFlyFrmFmt,
543cdf0e10cSrcweir                                   const String& sNewDescription )
544cdf0e10cSrcweir {
545cdf0e10cSrcweir     if ( rFlyFrmFmt.GetObjDescription() == sNewDescription )
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir         return;
548cdf0e10cSrcweir     }
549cdf0e10cSrcweir 
550cdf0e10cSrcweir     ::sw::DrawUndoGuard const drawUndoGuard(GetIDocumentUndoRedo());
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     if (GetIDocumentUndoRedo().DoesUndo())
553cdf0e10cSrcweir     {
554cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo( new SwUndoFlyStrAttr( rFlyFrmFmt,
555cdf0e10cSrcweir                                           UNDO_FLYFRMFMT_DESCRIPTION,
556cdf0e10cSrcweir                                           rFlyFrmFmt.GetObjDescription(),
557cdf0e10cSrcweir                                           sNewDescription ) );
558cdf0e10cSrcweir     }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir     rFlyFrmFmt.SetObjDescription( sNewDescription, true );
561cdf0e10cSrcweir 
562cdf0e10cSrcweir     SetModified();
563cdf0e10cSrcweir }
564cdf0e10cSrcweir // <--
565cdf0e10cSrcweir 
SetFrmFmtToFly(SwFrmFmt & rFmt,SwFrmFmt & rNewFmt,SfxItemSet * pSet,sal_Bool bKeepOrient)566cdf0e10cSrcweir sal_Bool SwDoc::SetFrmFmtToFly( SwFrmFmt& rFmt, SwFrmFmt& rNewFmt,
567cdf0e10cSrcweir                             SfxItemSet* pSet, sal_Bool bKeepOrient )
568cdf0e10cSrcweir {
569cdf0e10cSrcweir     sal_Bool bChgAnchor = sal_False, bFrmSz = sal_False;
570cdf0e10cSrcweir 
571cdf0e10cSrcweir     const SwFmtFrmSize aFrmSz( rFmt.GetFrmSize() );
572cdf0e10cSrcweir     const SwFmtVertOrient aVert( rFmt.GetVertOrient() );
573cdf0e10cSrcweir     const SwFmtHoriOrient aHori( rFmt.GetHoriOrient() );
574cdf0e10cSrcweir 
575cdf0e10cSrcweir     SwUndoSetFlyFmt* pUndo = 0;
576cdf0e10cSrcweir     bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
577cdf0e10cSrcweir     if (bUndo)
578cdf0e10cSrcweir     {
579cdf0e10cSrcweir         pUndo = new SwUndoSetFlyFmt( rFmt, rNewFmt );
580cdf0e10cSrcweir         GetIDocumentUndoRedo().AppendUndo(pUndo);
581cdf0e10cSrcweir     }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir     // #i32968# Inserting columns in the section causes MakeFrmFmt to put
584cdf0e10cSrcweir     // 2 objects of type SwUndoFrmFmt on the undo stack. We don't want them.
585cdf0e10cSrcweir     ::sw::UndoGuard const undoGuard(GetIDocumentUndoRedo());
586cdf0e10cSrcweir 
587cdf0e10cSrcweir     //Erstmal die Spalten setzen, sonst gibts nix als Aerger mit dem
588cdf0e10cSrcweir     //Set/Reset/Abgleich usw.
589cdf0e10cSrcweir     const SfxPoolItem* pItem;
590cdf0e10cSrcweir     if( SFX_ITEM_SET != rNewFmt.GetAttrSet().GetItemState( RES_COL ))
591cdf0e10cSrcweir         rFmt.ResetFmtAttr( RES_COL );
592cdf0e10cSrcweir 
593cdf0e10cSrcweir     if( rFmt.DerivedFrom() != &rNewFmt )
594cdf0e10cSrcweir     {
595cdf0e10cSrcweir         rFmt.SetDerivedFrom( &rNewFmt );
596cdf0e10cSrcweir 
597cdf0e10cSrcweir         // 1. wenn nicht automatisch -> ignorieren, sonst -> wech
598cdf0e10cSrcweir         // 2. wech damit, MB!
599cdf0e10cSrcweir         if( SFX_ITEM_SET == rNewFmt.GetAttrSet().GetItemState( RES_FRM_SIZE, sal_False ))
600cdf0e10cSrcweir         {
601cdf0e10cSrcweir             rFmt.ResetFmtAttr( RES_FRM_SIZE );
602cdf0e10cSrcweir             bFrmSz = sal_True;
603cdf0e10cSrcweir         }
604cdf0e10cSrcweir 
605cdf0e10cSrcweir         const SfxItemSet* pAsk = pSet;
606cdf0e10cSrcweir         if( !pAsk ) pAsk = &rNewFmt.GetAttrSet();
607cdf0e10cSrcweir         if( SFX_ITEM_SET == pAsk->GetItemState( RES_ANCHOR, sal_False, &pItem )
608cdf0e10cSrcweir             && ((SwFmtAnchor*)pItem)->GetAnchorId() !=
609cdf0e10cSrcweir                 rFmt.GetAnchor().GetAnchorId() )
610cdf0e10cSrcweir         {
611cdf0e10cSrcweir             if( pSet )
612cdf0e10cSrcweir                 bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, *pSet, sal_False );
613cdf0e10cSrcweir             else
614cdf0e10cSrcweir             {
615cdf0e10cSrcweir                 //JP 23.04.98: muss den FlyFmt-Range haben, denn im SetFlyFrmAnchor
616cdf0e10cSrcweir                 //              werden Attribute in diesen gesetzt!
617cdf0e10cSrcweir                 SfxItemSet aFlySet( *rNewFmt.GetAttrSet().GetPool(),
618cdf0e10cSrcweir                                     rNewFmt.GetAttrSet().GetRanges() );
619cdf0e10cSrcweir                 aFlySet.Put( *pItem );
620cdf0e10cSrcweir                 bChgAnchor = MAKEFRMS == SetFlyFrmAnchor( rFmt, aFlySet, sal_False);
621cdf0e10cSrcweir             }
622cdf0e10cSrcweir         }
623cdf0e10cSrcweir     }
624cdf0e10cSrcweir 
625cdf0e10cSrcweir     //Hori und Vert nur dann resetten, wenn in der Vorlage eine
626cdf0e10cSrcweir     //automatische Ausrichtung eingestellt ist, anderfalls den alten Wert
627cdf0e10cSrcweir     //wieder hineinstopfen.
628cdf0e10cSrcweir     //JP 09.06.98: beim Update der RahmenVorlage sollte der Fly NICHT
629cdf0e10cSrcweir     //              seine Orientierng verlieren (diese wird nicht geupdatet!)
630cdf0e10cSrcweir     //OS: #96584# text::HoriOrientation::NONE and text::VertOrientation::NONE are allowed now
631cdf0e10cSrcweir     if (!bKeepOrient)
632cdf0e10cSrcweir     {
633cdf0e10cSrcweir         rFmt.ResetFmtAttr(RES_VERT_ORIENT);
634cdf0e10cSrcweir         rFmt.ResetFmtAttr(RES_HORI_ORIENT);
635cdf0e10cSrcweir     }
636cdf0e10cSrcweir 
637cdf0e10cSrcweir     rFmt.ResetFmtAttr( RES_PRINT, RES_SURROUND );
638cdf0e10cSrcweir     rFmt.ResetFmtAttr( RES_LR_SPACE, RES_UL_SPACE );
639cdf0e10cSrcweir     rFmt.ResetFmtAttr( RES_BACKGROUND, RES_COL );
640cdf0e10cSrcweir     rFmt.ResetFmtAttr( RES_URL, RES_EDIT_IN_READONLY );
641cdf0e10cSrcweir 
642cdf0e10cSrcweir     if( !bFrmSz )
643cdf0e10cSrcweir         rFmt.SetFmtAttr( aFrmSz );
644cdf0e10cSrcweir 
645cdf0e10cSrcweir     if( bChgAnchor )
646cdf0e10cSrcweir         rFmt.MakeFrms();
647cdf0e10cSrcweir 
648cdf0e10cSrcweir     if( pUndo )
649cdf0e10cSrcweir         pUndo->DeRegisterFromFormat( rFmt );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir     SetModified();
652cdf0e10cSrcweir 
653cdf0e10cSrcweir     return bChgAnchor;
654cdf0e10cSrcweir }
655cdf0e10cSrcweir 
GetGrfNms(const SwFlyFrmFmt & rFmt,String * pGrfName,String * pFltName) const656cdf0e10cSrcweir void SwDoc::GetGrfNms( const SwFlyFrmFmt& rFmt, String* pGrfName,
657cdf0e10cSrcweir                         String* pFltName ) const
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     SwNodeIndex aIdx( *rFmt.GetCntnt().GetCntntIdx(), 1 );
660cdf0e10cSrcweir     const SwGrfNode* pGrfNd = aIdx.GetNode().GetGrfNode();
661cdf0e10cSrcweir     if( pGrfNd && pGrfNd->IsLinkedFile() )
662cdf0e10cSrcweir         pGrfNd->GetFileFilterNms( pGrfName, pFltName );
663cdf0e10cSrcweir }
664cdf0e10cSrcweir 
ChgAnchor(const SdrMarkList & _rMrkList,RndStdIds _eAnchorType,const sal_Bool _bSameOnly,const sal_Bool _bPosCorr)665cdf0e10cSrcweir sal_Bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList,
666cdf0e10cSrcweir                            RndStdIds _eAnchorType,
667cdf0e10cSrcweir                            const sal_Bool _bSameOnly,
668cdf0e10cSrcweir                            const sal_Bool _bPosCorr )
669cdf0e10cSrcweir {
670cdf0e10cSrcweir     ASSERT( GetCurrentLayout(), "Ohne Layout geht gar nichts" );    //swmod 080218
671cdf0e10cSrcweir 
672cdf0e10cSrcweir     if ( !_rMrkList.GetMarkCount() ||
673cdf0e10cSrcweir          _rMrkList.GetMark( 0 )->GetMarkedSdrObj()->GetUpGroup() )
674cdf0e10cSrcweir     {
675cdf0e10cSrcweir         return false;
676cdf0e10cSrcweir     }
677cdf0e10cSrcweir 
678cdf0e10cSrcweir     GetIDocumentUndoRedo().StartUndo( UNDO_INSATTR, NULL );
679cdf0e10cSrcweir 
680cdf0e10cSrcweir     sal_Bool bUnmark = sal_False;
681cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < _rMrkList.GetMarkCount(); ++i )
682cdf0e10cSrcweir     {
683cdf0e10cSrcweir         SdrObject* pObj = _rMrkList.GetMark( i )->GetMarkedSdrObj();
684cdf0e10cSrcweir         if ( !pObj->ISA(SwVirtFlyDrawObj) )
685cdf0e10cSrcweir         {
686cdf0e10cSrcweir             SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
687cdf0e10cSrcweir 
688cdf0e10cSrcweir             // OD 27.06.2003 #108784# - consider, that drawing object has
689cdf0e10cSrcweir             // no user call. E.g.: a 'virtual' drawing object is disconnected by
690cdf0e10cSrcweir             // the anchor type change of the 'master' drawing object.
691cdf0e10cSrcweir             // Continue with next selected object and assert, if this isn't excepted.
692cdf0e10cSrcweir             if ( !pContact )
693cdf0e10cSrcweir             {
694cdf0e10cSrcweir #ifdef DBG_UTIL
695cdf0e10cSrcweir                 bool bNoUserCallExcepted =
696cdf0e10cSrcweir                         pObj->ISA(SwDrawVirtObj) &&
697cdf0e10cSrcweir                         !static_cast<SwDrawVirtObj*>(pObj)->IsConnected();
698cdf0e10cSrcweir                 ASSERT( bNoUserCallExcepted, "SwDoc::ChgAnchor(..) - no contact at selected drawing object" );
699cdf0e10cSrcweir #endif
700cdf0e10cSrcweir                 continue;
701cdf0e10cSrcweir             }
702cdf0e10cSrcweir 
703cdf0e10cSrcweir             // OD 2004-03-29 #i26791#
704cdf0e10cSrcweir             const SwFrm* pOldAnchorFrm = pContact->GetAnchorFrm( pObj );
705cdf0e10cSrcweir             const SwFrm* pNewAnchorFrm = pOldAnchorFrm;
706cdf0e10cSrcweir 
707cdf0e10cSrcweir             // --> OD 2006-03-01 #i54336#
708cdf0e10cSrcweir             // Instead of only keeping the index position for an as-character
709cdf0e10cSrcweir             // anchored object the complete <SwPosition> is kept, because the
710cdf0e10cSrcweir             // anchor index position could be moved, if the object again is
711cdf0e10cSrcweir             // anchored as character.
712cdf0e10cSrcweir //            xub_StrLen nIndx = STRING_NOTFOUND;
713cdf0e10cSrcweir             const SwPosition* pOldAsCharAnchorPos( 0L );
714cdf0e10cSrcweir             const RndStdIds eOldAnchorType = pContact->GetAnchorId();
715cdf0e10cSrcweir             if ( !_bSameOnly && eOldAnchorType == FLY_AS_CHAR )
716cdf0e10cSrcweir             {
717cdf0e10cSrcweir                 pOldAsCharAnchorPos = new SwPosition( pContact->GetCntntAnchor() );
718cdf0e10cSrcweir             }
719cdf0e10cSrcweir             // <--
720cdf0e10cSrcweir 
721cdf0e10cSrcweir             if ( _bSameOnly )
722cdf0e10cSrcweir                 _eAnchorType = eOldAnchorType;
723cdf0e10cSrcweir 
724cdf0e10cSrcweir             SwFmtAnchor aNewAnch( _eAnchorType );
725cdf0e10cSrcweir             Rectangle aObjRect( pContact->GetAnchoredObj( pObj )->GetObjRect().SVRect() );
726cdf0e10cSrcweir             const Point aPt( aObjRect.TopLeft() );
727cdf0e10cSrcweir 
728cdf0e10cSrcweir             switch ( _eAnchorType )
729cdf0e10cSrcweir             {
730cdf0e10cSrcweir             case FLY_AT_PARA:
731cdf0e10cSrcweir             case FLY_AT_CHAR:
732cdf0e10cSrcweir                 {
733cdf0e10cSrcweir                     const Point aNewPoint = pOldAnchorFrm &&
734cdf0e10cSrcweir                                             ( pOldAnchorFrm->IsVertical() ||
735cdf0e10cSrcweir                                               pOldAnchorFrm->IsRightToLeft() )
736cdf0e10cSrcweir                                             ? aObjRect.TopRight()
737cdf0e10cSrcweir                                             : aPt;
738cdf0e10cSrcweir 
739cdf0e10cSrcweir                     // OD 18.06.2003 #108784# - allow drawing objects in header/footer
740cdf0e10cSrcweir                     pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aNewPoint, false );
741cdf0e10cSrcweir                     if ( pNewAnchorFrm->IsTxtFrm() && ((SwTxtFrm*)pNewAnchorFrm)->IsFollow() )
742cdf0e10cSrcweir                     {
743cdf0e10cSrcweir                         pNewAnchorFrm = ((SwTxtFrm*)pNewAnchorFrm)->FindMaster();
744cdf0e10cSrcweir                     }
745cdf0e10cSrcweir                     if ( pNewAnchorFrm->IsProtected() )
746cdf0e10cSrcweir                     {
747cdf0e10cSrcweir                         pNewAnchorFrm = 0;
748cdf0e10cSrcweir                     }
749cdf0e10cSrcweir                     else
750cdf0e10cSrcweir                     {
751cdf0e10cSrcweir                         SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
752cdf0e10cSrcweir                         aNewAnch.SetType( _eAnchorType );
753cdf0e10cSrcweir                         aNewAnch.SetAnchor( &aPos );
754cdf0e10cSrcweir                     }
755cdf0e10cSrcweir                 }
756cdf0e10cSrcweir                 break;
757cdf0e10cSrcweir 
758cdf0e10cSrcweir             case FLY_AT_FLY: // LAYER_IMPL
759cdf0e10cSrcweir                 {
760cdf0e10cSrcweir                     //Ausgehend von der linken oberen Ecke des Fly den
761cdf0e10cSrcweir                     //dichtesten SwFlyFrm suchen.
762cdf0e10cSrcweir                     SwFrm *pTxtFrm;
763cdf0e10cSrcweir                     {
764cdf0e10cSrcweir                         SwCrsrMoveState aState( MV_SETONLYTEXT );
765cdf0e10cSrcweir                         SwPosition aPos( GetNodes() );
766cdf0e10cSrcweir                         Point aPoint( aPt );
767cdf0e10cSrcweir                         aPoint.X() -= 1;
768cdf0e10cSrcweir                         GetCurrentLayout()->GetCrsrOfst( &aPos, aPoint, &aState );
769cdf0e10cSrcweir                         // OD 20.06.2003 #108784# - consider that drawing objects
770cdf0e10cSrcweir                         // can be in header/footer. Thus, <GetFrm()> by left-top-corner
771cdf0e10cSrcweir                         pTxtFrm = aPos.nNode.GetNode().
772cdf0e10cSrcweir                                         GetCntntNode()->getLayoutFrm( GetCurrentLayout(), &aPt, 0, sal_False );
773cdf0e10cSrcweir                     }
774cdf0e10cSrcweir                     const SwFrm *pTmp = ::FindAnchor( pTxtFrm, aPt );
775cdf0e10cSrcweir                     pNewAnchorFrm = pTmp->FindFlyFrm();
776cdf0e10cSrcweir                     if( pNewAnchorFrm && !pNewAnchorFrm->IsProtected() )
777cdf0e10cSrcweir                     {
778cdf0e10cSrcweir                         const SwFrmFmt *pTmpFmt = ((SwFlyFrm*)pNewAnchorFrm)->GetFmt();
779cdf0e10cSrcweir                         const SwFmtCntnt& rCntnt = pTmpFmt->GetCntnt();
780cdf0e10cSrcweir                         SwPosition aPos( *rCntnt.GetCntntIdx() );
781cdf0e10cSrcweir                         aNewAnch.SetAnchor( &aPos );
782cdf0e10cSrcweir                         break;
783cdf0e10cSrcweir                     }
784cdf0e10cSrcweir 
785cdf0e10cSrcweir                     aNewAnch.SetType( FLY_AT_PAGE );
786cdf0e10cSrcweir                     // no break
787cdf0e10cSrcweir                 }
788cdf0e10cSrcweir             case FLY_AT_PAGE:
789cdf0e10cSrcweir                 {
790cdf0e10cSrcweir                     pNewAnchorFrm = GetCurrentLayout()->Lower();
791cdf0e10cSrcweir                     while ( pNewAnchorFrm && !pNewAnchorFrm->Frm().IsInside( aPt ) )
792cdf0e10cSrcweir                         pNewAnchorFrm = pNewAnchorFrm->GetNext();
793cdf0e10cSrcweir                     if ( !pNewAnchorFrm )
794cdf0e10cSrcweir                         continue;
795cdf0e10cSrcweir 
796cdf0e10cSrcweir                     aNewAnch.SetPageNum( ((SwPageFrm*)pNewAnchorFrm)->GetPhyPageNum());
797cdf0e10cSrcweir                 }
798cdf0e10cSrcweir                 break;
799cdf0e10cSrcweir             case FLY_AS_CHAR:
800cdf0e10cSrcweir                 if( _bSameOnly )    // Positions/Groessenaenderung
801cdf0e10cSrcweir                 {
802cdf0e10cSrcweir                     if( !pOldAnchorFrm )
803cdf0e10cSrcweir                     {
804cdf0e10cSrcweir                         pContact->ConnectToLayout();
805cdf0e10cSrcweir                         pOldAnchorFrm = pContact->GetAnchorFrm();
806cdf0e10cSrcweir                     }
807cdf0e10cSrcweir                     ((SwTxtFrm*)pOldAnchorFrm)->Prepare();
808cdf0e10cSrcweir                 }
809cdf0e10cSrcweir                 else            // Ankerwechsel
810cdf0e10cSrcweir                 {
811cdf0e10cSrcweir                     // OD 18.06.2003 #108784# - allow drawing objects in header/footer
812cdf0e10cSrcweir                     pNewAnchorFrm = ::FindAnchor( pOldAnchorFrm, aPt, false );
813cdf0e10cSrcweir                     if( pNewAnchorFrm->IsProtected() )
814cdf0e10cSrcweir                     {
815cdf0e10cSrcweir                         pNewAnchorFrm = 0;
816cdf0e10cSrcweir                         break;
817cdf0e10cSrcweir                     }
818cdf0e10cSrcweir 
819cdf0e10cSrcweir                     bUnmark = ( 0 != i );
820cdf0e10cSrcweir                     Point aPoint( aPt );
821cdf0e10cSrcweir                     aPoint.X() -= 1;    // nicht im DrawObj landen!!
822cdf0e10cSrcweir                     aNewAnch.SetType( FLY_AS_CHAR );
823cdf0e10cSrcweir                     SwPosition aPos( *((SwCntntFrm*)pNewAnchorFrm)->GetNode() );
824cdf0e10cSrcweir                     if ( pNewAnchorFrm->Frm().IsInside( aPoint ) )
825cdf0e10cSrcweir                     {
826cdf0e10cSrcweir                     // es muss ein TextNode gefunden werden, denn nur dort
827cdf0e10cSrcweir                     // ist ein inhaltsgebundenes DrawObjekt zu verankern
828cdf0e10cSrcweir                         SwCrsrMoveState aState( MV_SETONLYTEXT );
829cdf0e10cSrcweir                         GetCurrentLayout()->GetCrsrOfst( &aPos, aPoint, &aState );  //swmod 080218
830cdf0e10cSrcweir                     }
831cdf0e10cSrcweir                     else
832cdf0e10cSrcweir                     {
833cdf0e10cSrcweir                         SwCntntNode &rCNd = (SwCntntNode&)
834cdf0e10cSrcweir                             *((SwCntntFrm*)pNewAnchorFrm)->GetNode();
835cdf0e10cSrcweir                         if ( pNewAnchorFrm->Frm().Bottom() < aPt.Y() )
836cdf0e10cSrcweir                             rCNd.MakeStartIndex( &aPos.nContent );
837cdf0e10cSrcweir                         else
838cdf0e10cSrcweir                             rCNd.MakeEndIndex( &aPos.nContent );
839cdf0e10cSrcweir                     }
840cdf0e10cSrcweir                     aNewAnch.SetAnchor( &aPos );
841cdf0e10cSrcweir                     SetAttr( aNewAnch, *pContact->GetFmt() );
842cdf0e10cSrcweir                     // OD 2004-04-13 #i26791# - adjust vertical positioning to
843cdf0e10cSrcweir                     // 'center to baseline'
844cdf0e10cSrcweir                     SetAttr( SwFmtVertOrient( 0, text::VertOrientation::CENTER, text::RelOrientation::FRAME ), *pContact->GetFmt() );
845cdf0e10cSrcweir                     SwTxtNode *pNd = aPos.nNode.GetNode().GetTxtNode();
846cdf0e10cSrcweir                     ASSERT( pNd, "Cursor not positioned at TxtNode." );
847cdf0e10cSrcweir 
848cdf0e10cSrcweir                     SwFmtFlyCnt aFmt( pContact->GetFmt() );
849cdf0e10cSrcweir                     pNd->InsertItem( aFmt, aPos.nContent.GetIndex(), 0 );
850cdf0e10cSrcweir                 }
851cdf0e10cSrcweir                 break;
852cdf0e10cSrcweir             default:
853*870262e3SDon Lewis                 ASSERT( sal_False, "unexpected AnchorId." );
854cdf0e10cSrcweir             }
855cdf0e10cSrcweir 
856cdf0e10cSrcweir             if ( (FLY_AS_CHAR != _eAnchorType) &&
857cdf0e10cSrcweir                  pNewAnchorFrm &&
858cdf0e10cSrcweir                  ( !_bSameOnly || pNewAnchorFrm != pOldAnchorFrm ) )
859cdf0e10cSrcweir             {
860cdf0e10cSrcweir                 // OD 2004-04-06 #i26791# - Direct object positioning no longer
861cdf0e10cSrcweir                 // needed. Apply of attributes (method call <SetAttr(..)>) takes
862cdf0e10cSrcweir                 // care of the invalidation of the object position.
863cdf0e10cSrcweir                 SetAttr( aNewAnch, *pContact->GetFmt() );
864cdf0e10cSrcweir                 if ( _bPosCorr )
865cdf0e10cSrcweir                 {
866cdf0e10cSrcweir                     // --> OD 2004-08-24 #i33313# - consider not connected
867cdf0e10cSrcweir                     // 'virtual' drawing objects
868cdf0e10cSrcweir                     if ( pObj->ISA(SwDrawVirtObj) &&
869cdf0e10cSrcweir                          !static_cast<SwDrawVirtObj*>(pObj)->IsConnected() )
870cdf0e10cSrcweir                     {
871cdf0e10cSrcweir                         SwRect aNewObjRect( aObjRect );
872cdf0e10cSrcweir                         static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( 0L ))
873cdf0e10cSrcweir                                         ->AdjustPositioningAttr( pNewAnchorFrm,
874cdf0e10cSrcweir                                                                  &aNewObjRect );
875cdf0e10cSrcweir 
876cdf0e10cSrcweir                     }
877cdf0e10cSrcweir                     else
878cdf0e10cSrcweir                     {
879cdf0e10cSrcweir                         static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ))
880cdf0e10cSrcweir                                     ->AdjustPositioningAttr( pNewAnchorFrm );
881cdf0e10cSrcweir                     }
882cdf0e10cSrcweir                 }
883cdf0e10cSrcweir             }
884cdf0e10cSrcweir 
885cdf0e10cSrcweir             // --> OD 2006-03-01 #i54336#
886cdf0e10cSrcweir             if ( pNewAnchorFrm && pOldAsCharAnchorPos )
887cdf0e10cSrcweir             {
888cdf0e10cSrcweir                 //Bei InCntnt's wird es spannend: Das TxtAttribut muss vernichtet
889cdf0e10cSrcweir                 //werden. Leider reisst dies neben den Frms auch noch das Format mit
890cdf0e10cSrcweir                 //in sein Grab. Um dass zu unterbinden loesen wir vorher die
891cdf0e10cSrcweir                 //Verbindung zwischen Attribut und Format.
892cdf0e10cSrcweir                 const xub_StrLen nIndx( pOldAsCharAnchorPos->nContent.GetIndex() );
893cdf0e10cSrcweir                 SwTxtNode* pTxtNode( pOldAsCharAnchorPos->nNode.GetNode().GetTxtNode() );
894cdf0e10cSrcweir                 ASSERT( pTxtNode, "<SwDoc::ChgAnchor(..)> - missing previous anchor text node for as-character anchored object" );
895cdf0e10cSrcweir                 ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
896cdf0e10cSrcweir                 SwTxtAttr * const pHnt =
897cdf0e10cSrcweir                     pTxtNode->GetTxtAttrForCharAt( nIndx, RES_TXTATR_FLYCNT );
898cdf0e10cSrcweir                 const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt();
899cdf0e10cSrcweir 
900cdf0e10cSrcweir                 //Die Verbindung ist geloest, jetzt muss noch das Attribut vernichtet
901cdf0e10cSrcweir                 //werden.
902cdf0e10cSrcweir                 pTxtNode->DeleteAttributes( RES_TXTATR_FLYCNT, nIndx, nIndx );
903cdf0e10cSrcweir                 delete pOldAsCharAnchorPos;
904cdf0e10cSrcweir             }
905cdf0e10cSrcweir             // <--
906cdf0e10cSrcweir         }
907cdf0e10cSrcweir     }
908cdf0e10cSrcweir 
909cdf0e10cSrcweir     GetIDocumentUndoRedo().EndUndo( UNDO_END, NULL );
910cdf0e10cSrcweir     SetModified();
911cdf0e10cSrcweir 
912cdf0e10cSrcweir     return bUnmark;
913cdf0e10cSrcweir }
914cdf0e10cSrcweir 
915cdf0e10cSrcweir 
Chainable(const SwFrmFmt & rSource,const SwFrmFmt & rDest)916cdf0e10cSrcweir int SwDoc::Chainable( const SwFrmFmt &rSource, const SwFrmFmt &rDest )
917cdf0e10cSrcweir {
918cdf0e10cSrcweir     //Die Source darf noch keinen Follow haben.
919cdf0e10cSrcweir     const SwFmtChain &rOldChain = rSource.GetChain();
920cdf0e10cSrcweir     if ( rOldChain.GetNext() )
921cdf0e10cSrcweir         return SW_CHAIN_SOURCE_CHAINED;
922cdf0e10cSrcweir 
923cdf0e10cSrcweir     //Ziel darf natuerlich nicht gleich Source sein und es
924cdf0e10cSrcweir     //darf keine geschlossene Kette entstehen.
925cdf0e10cSrcweir     const SwFrmFmt *pFmt = &rDest;
926cdf0e10cSrcweir     do {
927cdf0e10cSrcweir         if( pFmt == &rSource )
928cdf0e10cSrcweir             return SW_CHAIN_SELF;
929cdf0e10cSrcweir         pFmt = pFmt->GetChain().GetNext();
930cdf0e10cSrcweir     } while ( pFmt );
931cdf0e10cSrcweir 
932cdf0e10cSrcweir     //Auch eine Verkettung von Innen nach aussen oder von aussen
933cdf0e10cSrcweir     //nach innen ist nicht zulaessig.
934cdf0e10cSrcweir     if( rDest.IsLowerOf( rSource ) || rSource .IsLowerOf( rDest ) )
935cdf0e10cSrcweir         return SW_CHAIN_SELF;
936cdf0e10cSrcweir 
937cdf0e10cSrcweir     //Das Ziel darf noch keinen Master haben.
938cdf0e10cSrcweir     const SwFmtChain &rChain = rDest.GetChain();
939cdf0e10cSrcweir     if( rChain.GetPrev() )
940cdf0e10cSrcweir         return SW_CHAIN_IS_IN_CHAIN;
941cdf0e10cSrcweir 
942cdf0e10cSrcweir     //Das Ziel muss leer sein.
943cdf0e10cSrcweir     const SwNodeIndex* pCntIdx = rDest.GetCntnt().GetCntntIdx();
944cdf0e10cSrcweir     if( !pCntIdx )
945cdf0e10cSrcweir         return SW_CHAIN_NOT_FOUND;
946cdf0e10cSrcweir 
947cdf0e10cSrcweir     SwNodeIndex aNxtIdx( *pCntIdx, 1 );
948cdf0e10cSrcweir     const SwTxtNode* pTxtNd = aNxtIdx.GetNode().GetTxtNode();
949cdf0e10cSrcweir     if( !pTxtNd )
950cdf0e10cSrcweir         return SW_CHAIN_NOT_FOUND;
951cdf0e10cSrcweir 
952cdf0e10cSrcweir     const sal_uLong nFlySttNd = pCntIdx->GetIndex();
953cdf0e10cSrcweir     if( 2 != ( pCntIdx->GetNode().EndOfSectionIndex() - nFlySttNd ) ||
954cdf0e10cSrcweir         pTxtNd->GetTxt().Len() )
955cdf0e10cSrcweir         return SW_CHAIN_NOT_EMPTY;
956cdf0e10cSrcweir 
957cdf0e10cSrcweir     sal_uInt16 nArrLen = GetSpzFrmFmts()->Count();
958cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < nArrLen; ++n )
959cdf0e10cSrcweir     {
960cdf0e10cSrcweir         const SwFmtAnchor& rAnchor = (*GetSpzFrmFmts())[ n ]->GetAnchor();
961cdf0e10cSrcweir         sal_uLong nTstSttNd;
962cdf0e10cSrcweir         // OD 11.12.2003 #i20622# - to-frame anchored objects are allowed.
963cdf0e10cSrcweir         if ( ((rAnchor.GetAnchorId() == FLY_AT_PARA) ||
964cdf0e10cSrcweir               (rAnchor.GetAnchorId() == FLY_AT_CHAR)) &&
965cdf0e10cSrcweir              0 != rAnchor.GetCntntAnchor() &&
966cdf0e10cSrcweir              nFlySttNd <= ( nTstSttNd =
967cdf0e10cSrcweir                         rAnchor.GetCntntAnchor()->nNode.GetIndex() ) &&
968cdf0e10cSrcweir              nTstSttNd < nFlySttNd + 2 )
969cdf0e10cSrcweir         {
970cdf0e10cSrcweir             return SW_CHAIN_NOT_EMPTY;
971cdf0e10cSrcweir         }
972cdf0e10cSrcweir     }
973cdf0e10cSrcweir 
974cdf0e10cSrcweir     //Auf die richtige Area muessen wir auch noch einen Blick werfen.
975cdf0e10cSrcweir     //Beide Flys muessen im selben Bereich (Body, Head/Foot, Fly) sitzen
976cdf0e10cSrcweir     //Wenn die Source nicht der selektierte Rahmen ist, so reicht es
977cdf0e10cSrcweir     //Wenn ein passender gefunden wird (Der Wunsch kann z.B. von der API
978cdf0e10cSrcweir     //kommen).
979cdf0e10cSrcweir 
980cdf0e10cSrcweir     // both in the same fly, header, footer or on the page?
981cdf0e10cSrcweir     const SwFmtAnchor &rSrcAnchor = rSource.GetAnchor(),
982cdf0e10cSrcweir                       &rDstAnchor = rDest.GetAnchor();
983cdf0e10cSrcweir     sal_uLong nEndOfExtras = GetNodes().GetEndOfExtras().GetIndex();
984cdf0e10cSrcweir     sal_Bool bAllowed = sal_False;
985cdf0e10cSrcweir     if ( FLY_AT_PAGE == rSrcAnchor.GetAnchorId() )
986cdf0e10cSrcweir     {
987cdf0e10cSrcweir         if ( (FLY_AT_PAGE == rDstAnchor.GetAnchorId()) ||
988cdf0e10cSrcweir             ( rDstAnchor.GetCntntAnchor() &&
989cdf0e10cSrcweir               rDstAnchor.GetCntntAnchor()->nNode.GetIndex() > nEndOfExtras ))
990cdf0e10cSrcweir             bAllowed = sal_True;
991cdf0e10cSrcweir     }
992cdf0e10cSrcweir     else if( rSrcAnchor.GetCntntAnchor() && rDstAnchor.GetCntntAnchor() )
993cdf0e10cSrcweir     {
994cdf0e10cSrcweir         const SwNodeIndex &rSrcIdx = rSrcAnchor.GetCntntAnchor()->nNode,
995cdf0e10cSrcweir                             &rDstIdx = rDstAnchor.GetCntntAnchor()->nNode;
996cdf0e10cSrcweir         const SwStartNode* pSttNd = 0;
997cdf0e10cSrcweir         if( rSrcIdx == rDstIdx ||
998cdf0e10cSrcweir             ( !pSttNd &&
999cdf0e10cSrcweir                 0 != ( pSttNd = rSrcIdx.GetNode().FindFlyStartNode() ) &&
1000cdf0e10cSrcweir                 pSttNd == rDstIdx.GetNode().FindFlyStartNode() ) ||
1001cdf0e10cSrcweir             ( !pSttNd &&
1002cdf0e10cSrcweir                 0 != ( pSttNd = rSrcIdx.GetNode().FindFooterStartNode() ) &&
1003cdf0e10cSrcweir                 pSttNd == rDstIdx.GetNode().FindFooterStartNode() ) ||
1004cdf0e10cSrcweir             ( !pSttNd &&
1005cdf0e10cSrcweir                 0 != ( pSttNd = rSrcIdx.GetNode().FindHeaderStartNode() ) &&
1006cdf0e10cSrcweir                 pSttNd == rDstIdx.GetNode().FindHeaderStartNode() ) ||
1007cdf0e10cSrcweir             ( !pSttNd && rDstIdx.GetIndex() > nEndOfExtras &&
1008cdf0e10cSrcweir                             rSrcIdx.GetIndex() > nEndOfExtras ))
1009cdf0e10cSrcweir             bAllowed = sal_True;
1010cdf0e10cSrcweir     }
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir     return bAllowed ? SW_CHAIN_OK : SW_CHAIN_WRONG_AREA;
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir 
Chain(SwFrmFmt & rSource,const SwFrmFmt & rDest)1015cdf0e10cSrcweir int SwDoc::Chain( SwFrmFmt &rSource, const SwFrmFmt &rDest )
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir     int nErr = Chainable( rSource, rDest );
1018cdf0e10cSrcweir     if ( !nErr )
1019cdf0e10cSrcweir     {
1020cdf0e10cSrcweir         GetIDocumentUndoRedo().StartUndo( UNDO_CHAINE, NULL );
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir         SwFlyFrmFmt& rDestFmt = (SwFlyFrmFmt&)rDest;
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir         //Follow an den Master haengen.
1025cdf0e10cSrcweir         SwFmtChain aChain = rDestFmt.GetChain();
1026cdf0e10cSrcweir         aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
1027cdf0e10cSrcweir         SetAttr( aChain, rDestFmt );
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir         SfxItemSet aSet( GetAttrPool(), RES_FRM_SIZE, RES_FRM_SIZE,
1030cdf0e10cSrcweir                                         RES_CHAIN,  RES_CHAIN, 0 );
1031cdf0e10cSrcweir 
1032cdf0e10cSrcweir         //Follow an den Master haengen.
1033cdf0e10cSrcweir         aChain.SetPrev( &(SwFlyFrmFmt&)rSource );
1034cdf0e10cSrcweir         SetAttr( aChain, rDestFmt );
1035cdf0e10cSrcweir 
1036cdf0e10cSrcweir         //Master an den Follow haengen und dafuer sorgen, dass der Master
1037cdf0e10cSrcweir         //eine fixierte Hoehe hat.
1038cdf0e10cSrcweir         aChain = rSource.GetChain();
1039cdf0e10cSrcweir         aChain.SetNext( &rDestFmt );
1040cdf0e10cSrcweir         aSet.Put( aChain );
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir         SwFmtFrmSize aSize( rSource.GetFrmSize() );
1043cdf0e10cSrcweir         if ( aSize.GetHeightSizeType() != ATT_FIX_SIZE )
1044cdf0e10cSrcweir         {
1045cdf0e10cSrcweir             SwFlyFrm *pFly = SwIterator<SwFlyFrm,SwFmt>::FirstElement( rSource );
1046cdf0e10cSrcweir             if ( pFly )
1047cdf0e10cSrcweir                 aSize.SetHeight( pFly->Frm().Height() );
1048cdf0e10cSrcweir             aSize.SetHeightSizeType( ATT_FIX_SIZE );
1049cdf0e10cSrcweir             aSet.Put( aSize );
1050cdf0e10cSrcweir         }
1051cdf0e10cSrcweir         SetAttr( aSet, rSource );
1052cdf0e10cSrcweir 
1053cdf0e10cSrcweir         GetIDocumentUndoRedo().EndUndo( UNDO_CHAINE, NULL );
1054cdf0e10cSrcweir     }
1055cdf0e10cSrcweir     return nErr;
1056cdf0e10cSrcweir }
1057cdf0e10cSrcweir 
Unchain(SwFrmFmt & rFmt)1058cdf0e10cSrcweir void SwDoc::Unchain( SwFrmFmt &rFmt )
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir     SwFmtChain aChain( rFmt.GetChain() );
1061cdf0e10cSrcweir     if ( aChain.GetNext() )
1062cdf0e10cSrcweir     {
1063cdf0e10cSrcweir         GetIDocumentUndoRedo().StartUndo( UNDO_UNCHAIN, NULL );
1064cdf0e10cSrcweir         SwFrmFmt *pFollow = aChain.GetNext();
1065cdf0e10cSrcweir         aChain.SetNext( 0 );
1066cdf0e10cSrcweir         SetAttr( aChain, rFmt );
1067cdf0e10cSrcweir         aChain = pFollow->GetChain();
1068cdf0e10cSrcweir         aChain.SetPrev( 0 );
1069cdf0e10cSrcweir         SetAttr( aChain, *pFollow );
1070cdf0e10cSrcweir         GetIDocumentUndoRedo().EndUndo( UNDO_UNCHAIN, NULL );
1071cdf0e10cSrcweir     }
1072cdf0e10cSrcweir }
1073