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