xref: /AOO41X/main/sw/source/core/doc/docfly.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
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