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