xref: /trunk/main/sw/source/core/layout/anchoreddrawobject.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir #include <anchoreddrawobject.hxx>
27cdf0e10cSrcweir #include <svx/svdobj.hxx>
28cdf0e10cSrcweir #include <dcontact.hxx>
29cdf0e10cSrcweir #include <rootfrm.hxx>
30cdf0e10cSrcweir #include <pagefrm.hxx>
31cdf0e10cSrcweir #include <cntfrm.hxx>
32cdf0e10cSrcweir #include <doc.hxx>
33cdf0e10cSrcweir #include <tocntntanchoredobjectposition.hxx>
34cdf0e10cSrcweir #include <tolayoutanchoredobjectposition.hxx>
35cdf0e10cSrcweir #include <frmtool.hxx>
36cdf0e10cSrcweir #include <fmtornt.hxx>
37cdf0e10cSrcweir // --> OD 2004-08-12 #i32795#
38cdf0e10cSrcweir #include <txtfrm.hxx>
39cdf0e10cSrcweir // <--
40cdf0e10cSrcweir // --> OD 2004-08-12 #i32795#
41cdf0e10cSrcweir // template class <std::vector>
42cdf0e10cSrcweir #include <vector>
43cdf0e10cSrcweir // <--
44cdf0e10cSrcweir 
45cdf0e10cSrcweir // --> OD 2004-08-10 #i28749#
46cdf0e10cSrcweir #include <com/sun/star/text/PositionLayoutDir.hpp>
47cdf0e10cSrcweir // <--
48cdf0e10cSrcweir // --> OD 2005-03-09 #i44559#
49cdf0e10cSrcweir #include <ndtxt.hxx>
50cdf0e10cSrcweir // <--
51cdf0e10cSrcweir 
52cdf0e10cSrcweir using namespace ::com::sun::star;
53cdf0e10cSrcweir 
54cdf0e10cSrcweir // ============================================================================
55cdf0e10cSrcweir // helper class for correct notification due to the positioning of
56cdf0e10cSrcweir // the anchored drawing object
57cdf0e10cSrcweir // ============================================================================
58cdf0e10cSrcweir class SwPosNotify
59cdf0e10cSrcweir {
60cdf0e10cSrcweir     private:
61cdf0e10cSrcweir         SwAnchoredDrawObject* mpAnchoredDrawObj;
62cdf0e10cSrcweir         SwRect maOldObjRect;
63cdf0e10cSrcweir         SwPageFrm* mpOldPageFrm;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     public:
66cdf0e10cSrcweir         SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj );
67cdf0e10cSrcweir         ~SwPosNotify();
68cdf0e10cSrcweir         // --> OD 2004-08-12 #i32795#
69cdf0e10cSrcweir         Point LastObjPos() const;
70cdf0e10cSrcweir         // <--
71cdf0e10cSrcweir };
72cdf0e10cSrcweir 
SwPosNotify(SwAnchoredDrawObject * _pAnchoredDrawObj)73cdf0e10cSrcweir SwPosNotify::SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj ) :
74cdf0e10cSrcweir     mpAnchoredDrawObj( _pAnchoredDrawObj )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     maOldObjRect = mpAnchoredDrawObj->GetObjRect();
77cdf0e10cSrcweir     // --> OD 2004-10-20 #i35640# - determine correct page frame
78cdf0e10cSrcweir     mpOldPageFrm = mpAnchoredDrawObj->GetPageFrm();
79cdf0e10cSrcweir     // <--
80cdf0e10cSrcweir }
81cdf0e10cSrcweir 
~SwPosNotify()82cdf0e10cSrcweir SwPosNotify::~SwPosNotify()
83cdf0e10cSrcweir {
84cdf0e10cSrcweir     if ( maOldObjRect != mpAnchoredDrawObj->GetObjRect() )
85cdf0e10cSrcweir     {
86cdf0e10cSrcweir         if( maOldObjRect.HasArea() && mpOldPageFrm )
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             mpAnchoredDrawObj->NotifyBackground( mpOldPageFrm, maOldObjRect,
89cdf0e10cSrcweir                                                  PREP_FLY_LEAVE );
90cdf0e10cSrcweir         }
91cdf0e10cSrcweir         SwRect aNewObjRect( mpAnchoredDrawObj->GetObjRect() );
92cdf0e10cSrcweir         if( aNewObjRect.HasArea() )
93cdf0e10cSrcweir         {
94cdf0e10cSrcweir             // --> OD 2004-10-20 #i35640# - determine correct page frame
95cdf0e10cSrcweir             SwPageFrm* pNewPageFrm = mpAnchoredDrawObj->GetPageFrm();
96cdf0e10cSrcweir             // <--
97cdf0e10cSrcweir             if( pNewPageFrm )
98cdf0e10cSrcweir                 mpAnchoredDrawObj->NotifyBackground( pNewPageFrm, aNewObjRect,
99cdf0e10cSrcweir                                                      PREP_FLY_ARRIVE );
100cdf0e10cSrcweir         }
101cdf0e10cSrcweir 
102cdf0e10cSrcweir         ::ClrContourCache( mpAnchoredDrawObj->GetDrawObj() );
103cdf0e10cSrcweir 
104cdf0e10cSrcweir         // --> OD 2004-10-20 #i35640# - additional notify anchor text frame
105cdf0e10cSrcweir         // Needed for negative positioned drawing objects
106cdf0e10cSrcweir         // --> OD 2005-03-01 #i43255# - refine condition to avoid unneeded
107cdf0e10cSrcweir         // invalidations: anchored object had to be on the page of its anchor
108cdf0e10cSrcweir         // text frame.
109cdf0e10cSrcweir         if ( mpAnchoredDrawObj->GetAnchorFrm()->IsTxtFrm() &&
110cdf0e10cSrcweir              mpOldPageFrm == mpAnchoredDrawObj->GetAnchorFrm()->FindPageFrm() )
111cdf0e10cSrcweir         {
112cdf0e10cSrcweir             mpAnchoredDrawObj->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
113cdf0e10cSrcweir         }
114cdf0e10cSrcweir         // <--
115cdf0e10cSrcweir 
116cdf0e10cSrcweir         // indicate a restart of the layout process
117cdf0e10cSrcweir         mpAnchoredDrawObj->SetRestartLayoutProcess( true );
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir     else
120cdf0e10cSrcweir     {
121cdf0e10cSrcweir         // lock position
122cdf0e10cSrcweir         mpAnchoredDrawObj->LockPosition();
123cdf0e10cSrcweir 
124cdf0e10cSrcweir         if ( !mpAnchoredDrawObj->ConsiderForTextWrap() )
125cdf0e10cSrcweir         {
126cdf0e10cSrcweir             // indicate that object has to be considered for text wrap
127cdf0e10cSrcweir             mpAnchoredDrawObj->SetConsiderForTextWrap( true );
128cdf0e10cSrcweir             // invalidate 'background' in order to allow its 'background'
129cdf0e10cSrcweir             // to wrap around it.
130cdf0e10cSrcweir             mpAnchoredDrawObj->NotifyBackground( mpAnchoredDrawObj->GetPageFrm(),
131cdf0e10cSrcweir                                     mpAnchoredDrawObj->GetObjRectWithSpaces(),
132cdf0e10cSrcweir                                     PREP_FLY_ARRIVE );
133cdf0e10cSrcweir             // invalidate position of anchor frame in order to force
134cdf0e10cSrcweir             // a re-format of the anchor frame, which also causes a
135cdf0e10cSrcweir             // re-format of the invalid previous frames of the anchor frame.
136cdf0e10cSrcweir             mpAnchoredDrawObj->AnchorFrm()->InvalidatePos();
137cdf0e10cSrcweir         }
138cdf0e10cSrcweir     }
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir // --> OD 2004-08-12 #i32795#
LastObjPos() const142cdf0e10cSrcweir Point SwPosNotify::LastObjPos() const
143cdf0e10cSrcweir {
144cdf0e10cSrcweir     return maOldObjRect.Pos();
145cdf0e10cSrcweir }
146cdf0e10cSrcweir //<--
147cdf0e10cSrcweir 
148cdf0e10cSrcweir // ============================================================================
149cdf0e10cSrcweir // OD 2004-08-12 #i32795#
150cdf0e10cSrcweir // helper class for oscillation control on object positioning
151cdf0e10cSrcweir // ============================================================================
152cdf0e10cSrcweir class SwObjPosOscillationControl
153cdf0e10cSrcweir {
154cdf0e10cSrcweir     private:
155cdf0e10cSrcweir         sal_uInt8 mnPosStackSize;
156cdf0e10cSrcweir 
157cdf0e10cSrcweir         const SwAnchoredDrawObject* mpAnchoredDrawObj;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir         std::vector<Point*> maObjPositions;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir     public:
162cdf0e10cSrcweir         SwObjPosOscillationControl( const SwAnchoredDrawObject& _rAnchoredDrawObj );
163cdf0e10cSrcweir         ~SwObjPosOscillationControl();
164cdf0e10cSrcweir 
165cdf0e10cSrcweir         bool OscillationDetected();
166cdf0e10cSrcweir };
167cdf0e10cSrcweir 
SwObjPosOscillationControl(const SwAnchoredDrawObject & _rAnchoredDrawObj)168cdf0e10cSrcweir SwObjPosOscillationControl::SwObjPosOscillationControl(
169cdf0e10cSrcweir                                 const SwAnchoredDrawObject& _rAnchoredDrawObj )
170cdf0e10cSrcweir     : mnPosStackSize( 20 ),
171cdf0e10cSrcweir       mpAnchoredDrawObj( &_rAnchoredDrawObj )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir }
174cdf0e10cSrcweir 
~SwObjPosOscillationControl()175cdf0e10cSrcweir SwObjPosOscillationControl::~SwObjPosOscillationControl()
176cdf0e10cSrcweir {
177cdf0e10cSrcweir     while ( !maObjPositions.empty() )
178cdf0e10cSrcweir     {
179cdf0e10cSrcweir         Point* pPos = maObjPositions.back();
180cdf0e10cSrcweir         delete pPos;
181cdf0e10cSrcweir 
182cdf0e10cSrcweir         maObjPositions.pop_back();
183cdf0e10cSrcweir     }
184cdf0e10cSrcweir }
185cdf0e10cSrcweir 
OscillationDetected()186cdf0e10cSrcweir bool SwObjPosOscillationControl::OscillationDetected()
187cdf0e10cSrcweir {
188cdf0e10cSrcweir     bool bOscillationDetected = false;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir     if ( maObjPositions.size() == mnPosStackSize )
191cdf0e10cSrcweir     {
192cdf0e10cSrcweir         // position stack is full -> oscillation
193cdf0e10cSrcweir         bOscillationDetected = true;
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir     else
196cdf0e10cSrcweir     {
197cdf0e10cSrcweir         Point* pNewObjPos = new Point( mpAnchoredDrawObj->GetObjRect().Pos() );
198cdf0e10cSrcweir         for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
199cdf0e10cSrcweir               aObjPosIter != maObjPositions.end();
200cdf0e10cSrcweir               ++aObjPosIter )
201cdf0e10cSrcweir         {
202cdf0e10cSrcweir             if ( *(pNewObjPos) == *(*aObjPosIter) )
203cdf0e10cSrcweir             {
204*86e1cf34SPedro Giffuni                 // position already occurred -> oscillation
205cdf0e10cSrcweir                 bOscillationDetected = true;
206cdf0e10cSrcweir                 delete pNewObjPos;
207cdf0e10cSrcweir                 break;
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir         }
210cdf0e10cSrcweir         if ( !bOscillationDetected )
211cdf0e10cSrcweir         {
212cdf0e10cSrcweir             maObjPositions.push_back( pNewObjPos );
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir     }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir     return bOscillationDetected;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir // ============================================================================
220cdf0e10cSrcweir // implementation of class <SwAnchoredDrawObject>
221cdf0e10cSrcweir // ============================================================================
222cdf0e10cSrcweir TYPEINIT1(SwAnchoredDrawObject,SwAnchoredObject);
223cdf0e10cSrcweir 
SwAnchoredDrawObject()224cdf0e10cSrcweir SwAnchoredDrawObject::SwAnchoredDrawObject() :
225cdf0e10cSrcweir     SwAnchoredObject(),
226cdf0e10cSrcweir     mbValidPos( false ),
227cdf0e10cSrcweir     // --> OD 2004-09-29 #i34748#
228cdf0e10cSrcweir     mpLastObjRect( 0L ),
229cdf0e10cSrcweir     // <--
230cdf0e10cSrcweir     mbNotYetAttachedToAnchorFrame( true ),
231cdf0e10cSrcweir     // --> OD 2004-08-09 #i28749#
232cdf0e10cSrcweir     mbNotYetPositioned( true ),
233cdf0e10cSrcweir     // <--
234cdf0e10cSrcweir     // --> OD 2006-03-17 #i62875#
235cdf0e10cSrcweir     mbCaptureAfterLayoutDirChange( false )
236cdf0e10cSrcweir     // <--
237cdf0e10cSrcweir {
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
~SwAnchoredDrawObject()240cdf0e10cSrcweir SwAnchoredDrawObject::~SwAnchoredDrawObject()
241cdf0e10cSrcweir {
242cdf0e10cSrcweir     // --> OD 2004-11-03 - follow-up of #i34748#
243cdf0e10cSrcweir     delete mpLastObjRect;
244cdf0e10cSrcweir     // <--
245cdf0e10cSrcweir }
246cdf0e10cSrcweir 
247cdf0e10cSrcweir // --> OD 2006-03-17 #i62875#
UpdateLayoutDir()248cdf0e10cSrcweir void SwAnchoredDrawObject::UpdateLayoutDir()
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     SwFrmFmt::tLayoutDir nOldLayoutDir( GetFrmFmt().GetLayoutDir() );
251cdf0e10cSrcweir 
252cdf0e10cSrcweir     SwAnchoredObject::UpdateLayoutDir();
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     if ( !NotYetPositioned() &&
255cdf0e10cSrcweir          GetFrmFmt().GetLayoutDir() != nOldLayoutDir &&
256cdf0e10cSrcweir          GetFrmFmt().GetDoc()->get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
257cdf0e10cSrcweir          !IsOutsidePage() )
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir         mbCaptureAfterLayoutDirChange = true;
260cdf0e10cSrcweir     }
261cdf0e10cSrcweir }
262cdf0e10cSrcweir // <--
263cdf0e10cSrcweir 
264cdf0e10cSrcweir // --> OD 2006-03-17 #i62875#
IsOutsidePage() const265cdf0e10cSrcweir bool SwAnchoredDrawObject::IsOutsidePage() const
266cdf0e10cSrcweir {
267cdf0e10cSrcweir     bool bOutsidePage( false );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     if ( !NotYetPositioned() && GetPageFrm() )
270cdf0e10cSrcweir     {
271cdf0e10cSrcweir         SwRect aTmpRect( GetObjRect() );
272cdf0e10cSrcweir         bOutsidePage =
273cdf0e10cSrcweir             ( aTmpRect.Intersection( GetPageFrm()->Frm() ) != GetObjRect() );
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     return bOutsidePage;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir // <--
279cdf0e10cSrcweir 
280cdf0e10cSrcweir // =============================================================================
281cdf0e10cSrcweir // OD 2004-03-25 #i26791# - implementation of pure virtual method declared in
282cdf0e10cSrcweir // base class <SwAnchoredObject>
283cdf0e10cSrcweir // =============================================================================
MakeObjPos()284cdf0e10cSrcweir void SwAnchoredDrawObject::MakeObjPos()
285cdf0e10cSrcweir {
286cdf0e10cSrcweir     if ( IsPositioningInProgress() )
287cdf0e10cSrcweir     {
288cdf0e10cSrcweir         // nothind to do - positioning already in progress
289cdf0e10cSrcweir         return;
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     if ( mbValidPos )
293cdf0e10cSrcweir     {
294cdf0e10cSrcweir         // nothing to do - position is valid
295cdf0e10cSrcweir         return;
296cdf0e10cSrcweir     }
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     // --> OD 2004-08-09 #i28749# - anchored drawing object has to be attached
299cdf0e10cSrcweir     // to anchor frame
300cdf0e10cSrcweir     if ( mbNotYetAttachedToAnchorFrame )
301cdf0e10cSrcweir     {
302cdf0e10cSrcweir         ASSERT( false,
303cdf0e10cSrcweir                 "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
304cdf0e10cSrcweir         return;
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir 
307cdf0e10cSrcweir     SwDrawContact* pDrawContact =
308cdf0e10cSrcweir                         static_cast<SwDrawContact*>(::GetUserCall( GetDrawObj() ));
309cdf0e10cSrcweir 
310cdf0e10cSrcweir     // --> OD 2004-08-09 #i28749# - if anchored drawing object hasn't been yet
311cdf0e10cSrcweir     // positioned, convert its positioning attributes, if its positioning
312cdf0e10cSrcweir     // attributes are given in horizontal left-to-right layout.
313cdf0e10cSrcweir     // --> OD 2004-10-25 #i36010# - Note: horizontal left-to-right layout is made
314cdf0e10cSrcweir     // the default layout direction for <SwDrawFrmFmt> instances. Thus, it has
315cdf0e10cSrcweir     // to be adjusted manually, if no adjustment of the positioning attributes
316cdf0e10cSrcweir     // have to be performed here.
317cdf0e10cSrcweir     // --> OD 2004-11-17 #i35635# - additionally move drawing object to the
318cdf0e10cSrcweir     // visible layer.
319cdf0e10cSrcweir     if ( mbNotYetPositioned )
320cdf0e10cSrcweir     {
321cdf0e10cSrcweir         // --> OD 2004-11-17 #i35635#
322cdf0e10cSrcweir         pDrawContact->MoveObjToVisibleLayer( DrawObj() );
323cdf0e10cSrcweir         // <--
324cdf0e10cSrcweir         // --> OD 2004-09-29 #117975# - perform conversion of positioning
325cdf0e10cSrcweir         // attributes only for 'master' drawing objects
326cdf0e10cSrcweir         // --> OD 2005-03-11 #i44334#, #i44681# - check, if positioning
327cdf0e10cSrcweir         // attributes already have been set.
328cdf0e10cSrcweir         if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
329cdf0e10cSrcweir              !static_cast<SwDrawFrmFmt&>(GetFrmFmt()).IsPosAttrSet() )
330cdf0e10cSrcweir         {
331cdf0e10cSrcweir             _SetPositioningAttr();
332cdf0e10cSrcweir         }
333cdf0e10cSrcweir         // <--
334cdf0e10cSrcweir         // --> OD 2006-05-24 #b6418964#
335cdf0e10cSrcweir         // - reset internal flag after all needed actions are performed to
336cdf0e10cSrcweir         //   avoid callbacks from drawing layer
337cdf0e10cSrcweir         mbNotYetPositioned = false;
338cdf0e10cSrcweir         // <--
339cdf0e10cSrcweir     }
340cdf0e10cSrcweir     // <--
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     // indicate that positioning is in progress
343cdf0e10cSrcweir     {
344cdf0e10cSrcweir         SwObjPositioningInProgress aObjPosInProgress( *this );
345cdf0e10cSrcweir 
346cdf0e10cSrcweir         // determine relative position of drawing object and set it
347cdf0e10cSrcweir         switch ( pDrawContact->GetAnchorId() )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             case FLY_AS_CHAR:
350cdf0e10cSrcweir             {
351cdf0e10cSrcweir                 // indicate that position will be valid after positioning is performed
352cdf0e10cSrcweir                 mbValidPos = true;
353cdf0e10cSrcweir                 // nothing to do, because as-character anchored objects are positioned
354cdf0e10cSrcweir                 // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
355cdf0e10cSrcweir             }
356cdf0e10cSrcweir             break;
357cdf0e10cSrcweir             case FLY_AT_PARA:
358cdf0e10cSrcweir             case FLY_AT_CHAR:
359cdf0e10cSrcweir             {
360cdf0e10cSrcweir                 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
361cdf0e10cSrcweir                 // helper method <_MakeObjPosAnchoredAtPara()>
362cdf0e10cSrcweir                 _MakeObjPosAnchoredAtPara();
363cdf0e10cSrcweir             }
364cdf0e10cSrcweir             break;
365cdf0e10cSrcweir             case FLY_AT_PAGE:
366cdf0e10cSrcweir             case FLY_AT_FLY:
367cdf0e10cSrcweir             {
368cdf0e10cSrcweir                 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
369cdf0e10cSrcweir                 // helper method <_MakeObjPosAnchoredAtLayout()>
370cdf0e10cSrcweir                 _MakeObjPosAnchoredAtLayout();
371cdf0e10cSrcweir             }
372cdf0e10cSrcweir             break;
373cdf0e10cSrcweir             default:
374cdf0e10cSrcweir             {
375cdf0e10cSrcweir                 ASSERT( false, "<SwAnchoredDrawObject::MakeObjPos()> - unknown anchor type - please inform OD." );
376cdf0e10cSrcweir             }
377cdf0e10cSrcweir         }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir         // keep, current object rectangle
380cdf0e10cSrcweir         // --> OD 2004-09-29 #i34748# - use new method <SetLastObjRect(..)>
381cdf0e10cSrcweir         SetLastObjRect( GetObjRect().SVRect() );
382cdf0e10cSrcweir         // <--
383cdf0e10cSrcweir 
384cdf0e10cSrcweir         // Assure for 'master' drawing object, that it's registered at the correct page.
385cdf0e10cSrcweir         // Perform check not for as-character anchored drawing objects and only if
386cdf0e10cSrcweir         // the anchor frame is valid.
387cdf0e10cSrcweir         if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
388cdf0e10cSrcweir              !pDrawContact->ObjAnchoredAsChar() &&
389cdf0e10cSrcweir              GetAnchorFrm()->IsValid() )
390cdf0e10cSrcweir         {
391cdf0e10cSrcweir             pDrawContact->ChkPage();
392cdf0e10cSrcweir         }
393cdf0e10cSrcweir     }
394cdf0e10cSrcweir 
395cdf0e10cSrcweir     // --> OD 2006-03-17 #i62875#
396cdf0e10cSrcweir     if ( mbCaptureAfterLayoutDirChange &&
397cdf0e10cSrcweir          GetPageFrm() )
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         SwRect aPageRect( GetPageFrm()->Frm() );
400cdf0e10cSrcweir         SwRect aObjRect( GetObjRect() );
401cdf0e10cSrcweir         if ( aObjRect.Right() >= aPageRect.Right() + 10 )
402cdf0e10cSrcweir         {
403cdf0e10cSrcweir             Size aSize( aPageRect.Right() - aObjRect.Right(), 0 );
404cdf0e10cSrcweir             DrawObj()->Move( aSize );
405cdf0e10cSrcweir             aObjRect = GetObjRect();
406cdf0e10cSrcweir         }
407cdf0e10cSrcweir 
408cdf0e10cSrcweir         if ( aObjRect.Left() + 10 <= aPageRect.Left() )
409cdf0e10cSrcweir         {
410cdf0e10cSrcweir             Size aSize( aPageRect.Left() - aObjRect.Left(), 0 );
411cdf0e10cSrcweir             DrawObj()->Move( aSize );
412cdf0e10cSrcweir         }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir         mbCaptureAfterLayoutDirChange = false;
415cdf0e10cSrcweir     }
416cdf0e10cSrcweir     // <--
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir /** method for the intrinsic positioning of a at-paragraph|at-character
420cdf0e10cSrcweir     anchored drawing object
421cdf0e10cSrcweir 
422cdf0e10cSrcweir     OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
423cdf0e10cSrcweir 
424cdf0e10cSrcweir     @author OD
425cdf0e10cSrcweir */
_MakeObjPosAnchoredAtPara()426cdf0e10cSrcweir void SwAnchoredDrawObject::_MakeObjPosAnchoredAtPara()
427cdf0e10cSrcweir {
428cdf0e10cSrcweir     // --> OD 2004-08-12 #i32795# - adopt positioning algorithm from Writer
429cdf0e10cSrcweir     // fly frames, which are anchored at paragraph|at character
430cdf0e10cSrcweir 
431cdf0e10cSrcweir     // Determine, if anchor frame can/has to be formatted.
432cdf0e10cSrcweir     // If yes, after each object positioning the anchor frame is formatted.
433cdf0e10cSrcweir     // If after the anchor frame format the object position isn't valid, the
434cdf0e10cSrcweir     // object is positioned again.
435cdf0e10cSrcweir     // --> OD 2005-02-22 #i43255# - refine condition: anchor frame format not
436cdf0e10cSrcweir     // allowed, if another anchored object, has to be consider its wrap influence
437cdf0e10cSrcweir     // --> OD 2005-06-07 #i50356# - format anchor frame containing the anchor
438cdf0e10cSrcweir     // position. E.g., for at-character anchored object this can be the follow
439cdf0e10cSrcweir     // frame of the anchor frame, which contains the anchor character.
440cdf0e10cSrcweir     const bool bFormatAnchor =
441cdf0e10cSrcweir             !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
442cdf0e10cSrcweir             !ConsiderObjWrapInfluenceOnObjPos() &&
443cdf0e10cSrcweir             !ConsiderObjWrapInfluenceOfOtherObjs();
444cdf0e10cSrcweir     // <--
445cdf0e10cSrcweir 
446cdf0e10cSrcweir     if ( bFormatAnchor )
447cdf0e10cSrcweir     {
448cdf0e10cSrcweir         // --> OD 2005-06-07 #i50356#
449cdf0e10cSrcweir         GetAnchorFrmContainingAnchPos()->Calc();
450cdf0e10cSrcweir         // <--
451cdf0e10cSrcweir     }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     bool bOscillationDetected = false;
454cdf0e10cSrcweir     SwObjPosOscillationControl aObjPosOscCtrl( *this );
455cdf0e10cSrcweir     // --> OD 2004-08-25 #i3317# - boolean, to apply temporarly the
456cdf0e10cSrcweir     // 'straightforward positioning process' for the frame due to its
457cdf0e10cSrcweir     // overlapping with a previous column.
458cdf0e10cSrcweir     bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
459cdf0e10cSrcweir     // <--
460cdf0e10cSrcweir     do {
461cdf0e10cSrcweir         // indicate that position will be valid after positioning is performed
462cdf0e10cSrcweir         mbValidPos = true;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir         // --> OD 2004-10-20 #i35640# - correct scope for <SwPosNotify> instance
465cdf0e10cSrcweir         {
466cdf0e10cSrcweir             // create instance of <SwPosNotify> for correct notification
467cdf0e10cSrcweir             SwPosNotify aPosNotify( this );
468cdf0e10cSrcweir 
469cdf0e10cSrcweir             // determine and set position
470cdf0e10cSrcweir             objectpositioning::SwToCntntAnchoredObjectPosition
471cdf0e10cSrcweir                     aObjPositioning( *DrawObj() );
472cdf0e10cSrcweir             aObjPositioning.CalcPosition();
473cdf0e10cSrcweir 
474cdf0e10cSrcweir             // get further needed results of the positioning algorithm
475cdf0e10cSrcweir             SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
476cdf0e10cSrcweir             _SetDrawObjAnchor();
477cdf0e10cSrcweir 
478cdf0e10cSrcweir             // check for object position oscillation, if position has changed.
479cdf0e10cSrcweir             if ( GetObjRect().Pos() != aPosNotify.LastObjPos() )
480cdf0e10cSrcweir             {
481cdf0e10cSrcweir                 bOscillationDetected = aObjPosOscCtrl.OscillationDetected();
482cdf0e10cSrcweir             }
483cdf0e10cSrcweir         }
484cdf0e10cSrcweir         // <--
485cdf0e10cSrcweir         // format anchor frame, if requested.
486cdf0e10cSrcweir         // Note: the format of the anchor frame can cause the object position
487cdf0e10cSrcweir         // to be invalid.
488cdf0e10cSrcweir         if ( bFormatAnchor )
489cdf0e10cSrcweir         {
490cdf0e10cSrcweir             // --> OD 2005-06-07 #i50356#
491cdf0e10cSrcweir             GetAnchorFrmContainingAnchPos()->Calc();
492cdf0e10cSrcweir             // <--
493cdf0e10cSrcweir         }
494cdf0e10cSrcweir 
495cdf0e10cSrcweir         // --> OD 2004-08-25 #i3317#
496cdf0e10cSrcweir         if ( !ConsiderObjWrapInfluenceOnObjPos() &&
497cdf0e10cSrcweir              OverlapsPrevColumn() )
498cdf0e10cSrcweir         {
499cdf0e10cSrcweir             bConsiderWrapInfluenceDueToOverlapPrevCol = true;
500cdf0e10cSrcweir         }
501cdf0e10cSrcweir         // <--
502cdf0e10cSrcweir     } while ( !mbValidPos && !bOscillationDetected &&
503cdf0e10cSrcweir               !bConsiderWrapInfluenceDueToOverlapPrevCol );
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     // --> OD 2004-08-25 #i3317# - consider a detected oscillation and overlapping
506cdf0e10cSrcweir     // with previous column.
507cdf0e10cSrcweir     // temporarly consider the anchored objects wrapping style influence
508cdf0e10cSrcweir     if ( bOscillationDetected || bConsiderWrapInfluenceDueToOverlapPrevCol )
509cdf0e10cSrcweir     {
510cdf0e10cSrcweir         SetTmpConsiderWrapInfluence( true );
511cdf0e10cSrcweir         SetRestartLayoutProcess( true );
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir     // <--
514cdf0e10cSrcweir }
515cdf0e10cSrcweir 
516cdf0e10cSrcweir /** method for the intrinsic positioning of a at-page|at-frame anchored
517cdf0e10cSrcweir     drawing object
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
520cdf0e10cSrcweir 
521cdf0e10cSrcweir     @author OD
522cdf0e10cSrcweir */
_MakeObjPosAnchoredAtLayout()523cdf0e10cSrcweir void SwAnchoredDrawObject::_MakeObjPosAnchoredAtLayout()
524cdf0e10cSrcweir {
525cdf0e10cSrcweir     // indicate that position will be valid after positioning is performed
526cdf0e10cSrcweir     mbValidPos = true;
527cdf0e10cSrcweir 
528cdf0e10cSrcweir     // create instance of <SwPosNotify> for correct notification
529cdf0e10cSrcweir     SwPosNotify aPosNotify( this );
530cdf0e10cSrcweir 
531cdf0e10cSrcweir     // determine position
532cdf0e10cSrcweir     objectpositioning::SwToLayoutAnchoredObjectPosition
533cdf0e10cSrcweir             aObjPositioning( *DrawObj() );
534cdf0e10cSrcweir     aObjPositioning.CalcPosition();
535cdf0e10cSrcweir 
536cdf0e10cSrcweir     // set position
537cdf0e10cSrcweir 
538cdf0e10cSrcweir     // --> OD 2004-07-29 #i31698#
539cdf0e10cSrcweir     // --> OD 2004-10-18 #i34995# - setting anchor position needed for filters,
540cdf0e10cSrcweir     // especially for the xml-filter to the OpenOffice.org file format
541cdf0e10cSrcweir     {
542cdf0e10cSrcweir         const Point aNewAnchorPos =
543cdf0e10cSrcweir                     GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
544cdf0e10cSrcweir         DrawObj()->SetAnchorPos( aNewAnchorPos );
545cdf0e10cSrcweir         // --> OD 2006-10-05 #i70122# - missing invalidation
546cdf0e10cSrcweir         InvalidateObjRectWithSpaces();
547cdf0e10cSrcweir         // <--
548cdf0e10cSrcweir     }
549cdf0e10cSrcweir     // <--
550cdf0e10cSrcweir     SetCurrRelPos( aObjPositioning.GetRelPos() );
551cdf0e10cSrcweir     const SwFrm* pAnchorFrm = GetAnchorFrm();
552cdf0e10cSrcweir     SWRECTFN( pAnchorFrm );
553cdf0e10cSrcweir     const Point aAnchPos( (pAnchorFrm->Frm().*fnRect->fnGetPos)() );
554cdf0e10cSrcweir     SetObjLeft( aAnchPos.X() + GetCurrRelPos().X() );
555cdf0e10cSrcweir     SetObjTop( aAnchPos.Y() + GetCurrRelPos().Y() );
556cdf0e10cSrcweir     // <--
557cdf0e10cSrcweir }
558cdf0e10cSrcweir 
_SetDrawObjAnchor()559cdf0e10cSrcweir void SwAnchoredDrawObject::_SetDrawObjAnchor()
560cdf0e10cSrcweir {
561cdf0e10cSrcweir     // new anchor position
562cdf0e10cSrcweir     // --> OD 2004-07-29 #i31698# -
563cdf0e10cSrcweir     Point aNewAnchorPos =
564cdf0e10cSrcweir                 GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
565cdf0e10cSrcweir     Point aCurrAnchorPos = GetDrawObj()->GetAnchorPos();
566cdf0e10cSrcweir     if ( aNewAnchorPos != aCurrAnchorPos )
567cdf0e10cSrcweir     {
568cdf0e10cSrcweir         // determine movement to be applied after setting the new anchor position
569cdf0e10cSrcweir         Size aMove( aCurrAnchorPos.X() - aNewAnchorPos.X(),
570cdf0e10cSrcweir                     aCurrAnchorPos.Y() - aNewAnchorPos.Y() );
571cdf0e10cSrcweir         // set new anchor position
572cdf0e10cSrcweir         DrawObj()->SetAnchorPos( aNewAnchorPos );
573cdf0e10cSrcweir         // correct object position, caused by setting new anchor position
574cdf0e10cSrcweir         DrawObj()->Move( aMove );
575cdf0e10cSrcweir         // --> OD 2006-10-05 #i70122# - missing invalidation
576cdf0e10cSrcweir         InvalidateObjRectWithSpaces();
577cdf0e10cSrcweir         // <--
578cdf0e10cSrcweir     }
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir /** method to invalidate the given page frame
582cdf0e10cSrcweir 
583cdf0e10cSrcweir     OD 2004-07-02 #i28701#
584cdf0e10cSrcweir 
585cdf0e10cSrcweir     @author OD
586cdf0e10cSrcweir */
_InvalidatePage(SwPageFrm * _pPageFrm)587cdf0e10cSrcweir void SwAnchoredDrawObject::_InvalidatePage( SwPageFrm* _pPageFrm )
588cdf0e10cSrcweir {
589cdf0e10cSrcweir     if ( _pPageFrm && !_pPageFrm->GetFmt()->GetDoc()->IsInDtor() )
590cdf0e10cSrcweir     {
591cdf0e10cSrcweir         if ( _pPageFrm->GetUpper() )
592cdf0e10cSrcweir         {
593cdf0e10cSrcweir             // --> OD 2004-11-11 #i35007# - correct invalidation for as-character
594cdf0e10cSrcweir             // anchored objects.
595cdf0e10cSrcweir             if ( GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR )
596cdf0e10cSrcweir             {
597cdf0e10cSrcweir                 _pPageFrm->InvalidateFlyInCnt();
598cdf0e10cSrcweir             }
599cdf0e10cSrcweir             else
600cdf0e10cSrcweir             {
601cdf0e10cSrcweir                 _pPageFrm->InvalidateFlyLayout();
602cdf0e10cSrcweir             }
603cdf0e10cSrcweir             // <--
604cdf0e10cSrcweir 
605cdf0e10cSrcweir             SwRootFrm* pRootFrm = static_cast<SwRootFrm*>(_pPageFrm->GetUpper());
606cdf0e10cSrcweir             pRootFrm->DisallowTurbo();
607cdf0e10cSrcweir             if ( pRootFrm->GetTurbo() )
608cdf0e10cSrcweir             {
609cdf0e10cSrcweir                 const SwCntntFrm* pTmpFrm = pRootFrm->GetTurbo();
610cdf0e10cSrcweir                 pRootFrm->ResetTurbo();
611cdf0e10cSrcweir                 pTmpFrm->InvalidatePage();
612cdf0e10cSrcweir             }
613cdf0e10cSrcweir             pRootFrm->SetIdleFlags();
614cdf0e10cSrcweir         }
615cdf0e10cSrcweir     }
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
InvalidateObjPos()618cdf0e10cSrcweir void SwAnchoredDrawObject::InvalidateObjPos()
619cdf0e10cSrcweir {
620cdf0e10cSrcweir     // --> OD 2004-07-01 #i28701# - check, if invalidation is allowed
621cdf0e10cSrcweir     if ( mbValidPos &&
622cdf0e10cSrcweir          InvalidationOfPosAllowed() )
623cdf0e10cSrcweir     {
624cdf0e10cSrcweir         mbValidPos = false;
625cdf0e10cSrcweir         // --> OD 2006-08-10 #i68520#
626cdf0e10cSrcweir         InvalidateObjRectWithSpaces();
627cdf0e10cSrcweir         // <--
628cdf0e10cSrcweir 
629cdf0e10cSrcweir         // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
630cdf0e10cSrcweir         if ( GetAnchorFrm() )
631cdf0e10cSrcweir         {
632cdf0e10cSrcweir             // --> OD 2004-11-22 #118547# - notify anchor frame of as-character
633cdf0e10cSrcweir             // anchored object, because its positioned by the format of its anchor frame.
634cdf0e10cSrcweir             // --> OD 2005-03-09 #i44559# - assure, that text hint is already
635cdf0e10cSrcweir             // existing in the text frame
636cdf0e10cSrcweir             if ( GetAnchorFrm()->ISA(SwTxtFrm) &&
637cdf0e10cSrcweir                  (GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
638cdf0e10cSrcweir             {
639cdf0e10cSrcweir                 SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
640cdf0e10cSrcweir                 if ( pAnchorTxtFrm->GetTxtNode()->GetpSwpHints() &&
641cdf0e10cSrcweir                      pAnchorTxtFrm->CalcFlyPos( &GetFrmFmt() ) != STRING_LEN )
642cdf0e10cSrcweir                 {
643cdf0e10cSrcweir                     AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, &GetFrmFmt() );
644cdf0e10cSrcweir                 }
645cdf0e10cSrcweir             }
646cdf0e10cSrcweir             // <--
647cdf0e10cSrcweir 
648cdf0e10cSrcweir             SwPageFrm* pPageFrm = AnchorFrm()->FindPageFrm();
649cdf0e10cSrcweir             _InvalidatePage( pPageFrm );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir             // --> OD 2004-08-12 #i32270# - also invalidate page frame, at which the
652cdf0e10cSrcweir             // drawing object is registered at.
653cdf0e10cSrcweir             SwPageFrm* pPageFrmRegisteredAt = GetPageFrm();
654cdf0e10cSrcweir             if ( pPageFrmRegisteredAt &&
655cdf0e10cSrcweir                  pPageFrmRegisteredAt != pPageFrm )
656cdf0e10cSrcweir             {
657cdf0e10cSrcweir                 _InvalidatePage( pPageFrmRegisteredAt );
658cdf0e10cSrcweir             }
659cdf0e10cSrcweir             // <--
660cdf0e10cSrcweir             // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
661cdf0e10cSrcweir             // is replaced by method <FindPageFrmOfAnchor()>. It's return value
662cdf0e10cSrcweir             // have to be checked.
663cdf0e10cSrcweir             SwPageFrm* pPageFrmOfAnchor = FindPageFrmOfAnchor();
664cdf0e10cSrcweir             if ( pPageFrmOfAnchor &&
665cdf0e10cSrcweir                  pPageFrmOfAnchor != pPageFrm &&
666cdf0e10cSrcweir                  pPageFrmOfAnchor != pPageFrmRegisteredAt )
667cdf0e10cSrcweir             // <--
668cdf0e10cSrcweir             {
669cdf0e10cSrcweir                 _InvalidatePage( pPageFrmOfAnchor );
670cdf0e10cSrcweir             }
671cdf0e10cSrcweir         }
672cdf0e10cSrcweir         // <--
673cdf0e10cSrcweir     }
674cdf0e10cSrcweir }
675cdf0e10cSrcweir 
GetFrmFmt()676cdf0e10cSrcweir SwFrmFmt& SwAnchoredDrawObject::GetFrmFmt()
677cdf0e10cSrcweir {
678cdf0e10cSrcweir     ASSERT( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt(),
679cdf0e10cSrcweir             "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
680cdf0e10cSrcweir     return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt());
681cdf0e10cSrcweir }
GetFrmFmt() const682cdf0e10cSrcweir const SwFrmFmt& SwAnchoredDrawObject::GetFrmFmt() const
683cdf0e10cSrcweir {
684cdf0e10cSrcweir     ASSERT( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt(),
685cdf0e10cSrcweir             "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
686cdf0e10cSrcweir     return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt());
687cdf0e10cSrcweir }
688cdf0e10cSrcweir 
GetObjRect() const689cdf0e10cSrcweir const SwRect SwAnchoredDrawObject::GetObjRect() const
690cdf0e10cSrcweir {
691cdf0e10cSrcweir     // use geometry of drawing object
692cdf0e10cSrcweir     //return GetDrawObj()->GetCurrentBoundRect();
693cdf0e10cSrcweir     return GetDrawObj()->GetSnapRect();
694cdf0e10cSrcweir }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir // --> OD 2006-10-05 #i70122#
GetObjBoundRect() const697cdf0e10cSrcweir const SwRect SwAnchoredDrawObject::GetObjBoundRect() const
698cdf0e10cSrcweir {
699cdf0e10cSrcweir     return GetDrawObj()->GetCurrentBoundRect();
700cdf0e10cSrcweir }
701cdf0e10cSrcweir // <--
702cdf0e10cSrcweir 
703cdf0e10cSrcweir // --> OD 2006-08-10 #i68520#
_SetObjTop(const SwTwips _nTop)704cdf0e10cSrcweir bool SwAnchoredDrawObject::_SetObjTop( const SwTwips _nTop )
705cdf0e10cSrcweir {
706cdf0e10cSrcweir     SwTwips nDiff = _nTop - GetObjRect().Top();
707cdf0e10cSrcweir     DrawObj()->Move( Size( 0, nDiff ) );
708cdf0e10cSrcweir 
709cdf0e10cSrcweir     return nDiff != 0;
710cdf0e10cSrcweir }
_SetObjLeft(const SwTwips _nLeft)711cdf0e10cSrcweir bool SwAnchoredDrawObject::_SetObjLeft( const SwTwips _nLeft )
712cdf0e10cSrcweir {
713cdf0e10cSrcweir     SwTwips nDiff = _nLeft - GetObjRect().Left();
714cdf0e10cSrcweir     DrawObj()->Move( Size( nDiff, 0 ) );
715cdf0e10cSrcweir 
716cdf0e10cSrcweir     return nDiff != 0;
717cdf0e10cSrcweir }
718cdf0e10cSrcweir // <--
719cdf0e10cSrcweir 
720cdf0e10cSrcweir /** adjust positioning and alignment attributes for new anchor frame
721cdf0e10cSrcweir 
722cdf0e10cSrcweir     OD 2004-08-24 #i33313# - add second optional parameter <_pNewObjRect>
723cdf0e10cSrcweir 
724cdf0e10cSrcweir     @author OD
725cdf0e10cSrcweir */
AdjustPositioningAttr(const SwFrm * _pNewAnchorFrm,const SwRect * _pNewObjRect)726cdf0e10cSrcweir void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrm* _pNewAnchorFrm,
727cdf0e10cSrcweir                                                   const SwRect* _pNewObjRect )
728cdf0e10cSrcweir {
729cdf0e10cSrcweir     SwTwips nHoriRelPos = 0;
730cdf0e10cSrcweir     SwTwips nVertRelPos = 0;
731cdf0e10cSrcweir     const Point aAnchorPos = _pNewAnchorFrm->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
732cdf0e10cSrcweir     // --> OD 2004-08-24 #i33313#
733cdf0e10cSrcweir     const SwRect aObjRect( _pNewObjRect ? *_pNewObjRect : GetObjRect() );
734cdf0e10cSrcweir     // <--
735cdf0e10cSrcweir     const bool bVert = _pNewAnchorFrm->IsVertical();
736cdf0e10cSrcweir     const bool bR2L = _pNewAnchorFrm->IsRightToLeft();
737cdf0e10cSrcweir     if ( bVert )
738cdf0e10cSrcweir     {
739cdf0e10cSrcweir         nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
740cdf0e10cSrcweir         nVertRelPos = aAnchorPos.X() - aObjRect.Right();
741cdf0e10cSrcweir     }
742cdf0e10cSrcweir     else if ( bR2L )
743cdf0e10cSrcweir     {
744cdf0e10cSrcweir         nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
745cdf0e10cSrcweir         nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
746cdf0e10cSrcweir     }
747cdf0e10cSrcweir     else
748cdf0e10cSrcweir     {
749cdf0e10cSrcweir         nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
750cdf0e10cSrcweir         nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
751cdf0e10cSrcweir     }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir     GetFrmFmt().SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
754cdf0e10cSrcweir     GetFrmFmt().SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
755cdf0e10cSrcweir }
756cdf0e10cSrcweir 
757cdf0e10cSrcweir // --> OD 2004-09-29 #i34748# - change return type
GetLastObjRect() const758cdf0e10cSrcweir const Rectangle* SwAnchoredDrawObject::GetLastObjRect() const
759cdf0e10cSrcweir {
760cdf0e10cSrcweir     return mpLastObjRect;
761cdf0e10cSrcweir }
762cdf0e10cSrcweir // <--
763cdf0e10cSrcweir 
764cdf0e10cSrcweir // --> OD 2004-09-29 #i34748# - change return type.
765cdf0e10cSrcweir // If member <mpLastObjRect> is NULL, create one.
SetLastObjRect(const Rectangle & _rNewLastRect)766cdf0e10cSrcweir void SwAnchoredDrawObject::SetLastObjRect( const Rectangle& _rNewLastRect )
767cdf0e10cSrcweir {
768cdf0e10cSrcweir     if ( !mpLastObjRect )
769cdf0e10cSrcweir     {
770cdf0e10cSrcweir         mpLastObjRect = new Rectangle;
771cdf0e10cSrcweir     }
772cdf0e10cSrcweir     *(mpLastObjRect) = _rNewLastRect;
773cdf0e10cSrcweir }
774cdf0e10cSrcweir // <--
775cdf0e10cSrcweir 
ObjectAttachedToAnchorFrame()776cdf0e10cSrcweir void SwAnchoredDrawObject::ObjectAttachedToAnchorFrame()
777cdf0e10cSrcweir {
778cdf0e10cSrcweir     // --> OD 2004-07-27 #i31698#
779cdf0e10cSrcweir     SwAnchoredObject::ObjectAttachedToAnchorFrame();
780cdf0e10cSrcweir     // <--
781cdf0e10cSrcweir 
782cdf0e10cSrcweir     if ( mbNotYetAttachedToAnchorFrame )
783cdf0e10cSrcweir     {
784cdf0e10cSrcweir         mbNotYetAttachedToAnchorFrame = false;
785cdf0e10cSrcweir     }
786cdf0e10cSrcweir }
787cdf0e10cSrcweir 
788cdf0e10cSrcweir /** method to set positioning attributes
789cdf0e10cSrcweir 
790cdf0e10cSrcweir     OD 2004-10-20 #i35798#
791cdf0e10cSrcweir     During load the positioning attributes aren't set.
792cdf0e10cSrcweir     Thus, the positioning attributes are set by the current object geometry.
793cdf0e10cSrcweir     This method is also used for the conversion for drawing objects
794cdf0e10cSrcweir     (not anchored as-character) imported from OpenOffice.org file format
795cdf0e10cSrcweir     once and directly before the first positioning.
796cdf0e10cSrcweir 
797cdf0e10cSrcweir     @author OD
798cdf0e10cSrcweir */
_SetPositioningAttr()799cdf0e10cSrcweir void SwAnchoredDrawObject::_SetPositioningAttr()
800cdf0e10cSrcweir {
801cdf0e10cSrcweir     SwDrawContact* pDrawContact =
802cdf0e10cSrcweir                         static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
803cdf0e10cSrcweir 
804cdf0e10cSrcweir     if ( !pDrawContact->ObjAnchoredAsChar() )
805cdf0e10cSrcweir     {
806cdf0e10cSrcweir         SwRect aObjRect( GetObjRect() );
807cdf0e10cSrcweir 
808cdf0e10cSrcweir         SwTwips nHoriPos = aObjRect.Left();
809cdf0e10cSrcweir         SwTwips nVertPos = aObjRect.Top();
810cdf0e10cSrcweir         // --> OD 2005-03-10 #i44334#, #i44681#
811cdf0e10cSrcweir         // perform conversion only if position is in horizontal-left-to-right-layout.
812cdf0e10cSrcweir         if ( GetFrmFmt().GetPositionLayoutDir() ==
813cdf0e10cSrcweir                 text::PositionLayoutDir::PositionInHoriL2R )
814cdf0e10cSrcweir         {
815cdf0e10cSrcweir             SwFrmFmt::tLayoutDir eLayoutDir = GetFrmFmt().GetLayoutDir();
816cdf0e10cSrcweir             switch ( eLayoutDir )
817cdf0e10cSrcweir             {
818cdf0e10cSrcweir                 case SwFrmFmt::HORI_L2R:
819cdf0e10cSrcweir                 {
820cdf0e10cSrcweir                     // nothing to do
821cdf0e10cSrcweir                 }
822cdf0e10cSrcweir                 break;
823cdf0e10cSrcweir                 case SwFrmFmt::HORI_R2L:
824cdf0e10cSrcweir                 {
825cdf0e10cSrcweir                     nHoriPos = -aObjRect.Left() - aObjRect.Width();
826cdf0e10cSrcweir                 }
827cdf0e10cSrcweir                 break;
828cdf0e10cSrcweir                 case SwFrmFmt::VERT_R2L:
829cdf0e10cSrcweir                 {
830cdf0e10cSrcweir                     nHoriPos = aObjRect.Top();
831cdf0e10cSrcweir                     nVertPos = -aObjRect.Left() - aObjRect.Width();
832cdf0e10cSrcweir                 }
833cdf0e10cSrcweir                 break;
834cdf0e10cSrcweir                 default:
835cdf0e10cSrcweir                 {
836cdf0e10cSrcweir                     ASSERT( false,
837cdf0e10cSrcweir                             "<SwAnchoredDrawObject::_SetPositioningAttr()> - unsupported layout direction" );
838cdf0e10cSrcweir                 }
839cdf0e10cSrcweir             }
840cdf0e10cSrcweir         }
841cdf0e10cSrcweir         // <--
842cdf0e10cSrcweir 
843cdf0e10cSrcweir         // --> OD 2006-11-10 #i71182#
844cdf0e10cSrcweir         // only change position - do not lose other attributes
845cdf0e10cSrcweir         SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() );
846cdf0e10cSrcweir         aHori.SetPos( nHoriPos );
847cdf0e10cSrcweir         GetFrmFmt().SetFmtAttr( aHori );
848cdf0e10cSrcweir 
849cdf0e10cSrcweir         SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() );
850cdf0e10cSrcweir         // --> OD 2007-01-03 #i73079# - vertical position already correct
851cdf0e10cSrcweir //        if ( aVert.GetRelationOrient() == text::RelOrientation::CHAR ||
852cdf0e10cSrcweir //             aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
853cdf0e10cSrcweir //        {
854cdf0e10cSrcweir //            nVertPos = -nVertPos;
855cdf0e10cSrcweir //        }
856cdf0e10cSrcweir         // <--
857cdf0e10cSrcweir         aVert.SetPos( nVertPos );
858cdf0e10cSrcweir         GetFrmFmt().SetFmtAttr( aVert );
859cdf0e10cSrcweir         // <--
860cdf0e10cSrcweir 
861cdf0e10cSrcweir         // --> OD 2004-10-25 #i36010# - set layout direction of the position
862cdf0e10cSrcweir         GetFrmFmt().SetPositionLayoutDir(
863cdf0e10cSrcweir             text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
864cdf0e10cSrcweir         // <--
865cdf0e10cSrcweir     }
866cdf0e10cSrcweir     // --> OD 2007-11-29 #i65798# - also for as-character anchored objects
867cdf0e10cSrcweir     // --> OD 2005-05-10 #i45952# - indicate that position
868cdf0e10cSrcweir     // attributes are set now.
869cdf0e10cSrcweir     static_cast<SwDrawFrmFmt&>(GetFrmFmt()).PosAttrSet();
870cdf0e10cSrcweir     // <--
871cdf0e10cSrcweir }
872cdf0e10cSrcweir 
NotifyBackground(SwPageFrm * _pPageFrm,const SwRect & _rRect,PrepareHint _eHint)873cdf0e10cSrcweir void SwAnchoredDrawObject::NotifyBackground( SwPageFrm* _pPageFrm,
874cdf0e10cSrcweir                                              const SwRect& _rRect,
875cdf0e10cSrcweir                                              PrepareHint _eHint )
876cdf0e10cSrcweir {
877cdf0e10cSrcweir     ::Notify_Background( GetDrawObj(), _pPageFrm, _rRect, _eHint, sal_True );
878cdf0e10cSrcweir }
879cdf0e10cSrcweir 
880cdf0e10cSrcweir /** method to assure that anchored object is registered at the correct
881cdf0e10cSrcweir     page frame
882cdf0e10cSrcweir 
883cdf0e10cSrcweir     OD 2004-07-02 #i28701#
884cdf0e10cSrcweir 
885cdf0e10cSrcweir     @author OD
886cdf0e10cSrcweir */
RegisterAtCorrectPage()887cdf0e10cSrcweir void SwAnchoredDrawObject::RegisterAtCorrectPage()
888cdf0e10cSrcweir {
889cdf0e10cSrcweir     SwPageFrm* pPageFrm( 0L );
890cdf0e10cSrcweir     if ( GetVertPosOrientFrm() )
891cdf0e10cSrcweir     {
892cdf0e10cSrcweir         pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
893cdf0e10cSrcweir     }
894cdf0e10cSrcweir     if ( pPageFrm && GetPageFrm() != pPageFrm )
895cdf0e10cSrcweir     {
896cdf0e10cSrcweir         if ( GetPageFrm() )
897cdf0e10cSrcweir             GetPageFrm()->RemoveDrawObjFromPage( *this );
898cdf0e10cSrcweir         pPageFrm->AppendDrawObjToPage( *this );
899cdf0e10cSrcweir     }
900cdf0e10cSrcweir }
901cdf0e10cSrcweir 
902cdf0e10cSrcweir // =============================================================================
903