1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <anchoredobject.hxx>
27 #include <pam.hxx>
28 #include <frame.hxx>
29 #include <txtfrm.hxx>
30 #include <frmfmt.hxx>
31 #include <fmtanchr.hxx>
32 #include <fmtornt.hxx>
33 // --> OD 2004-06-29 #i28701#
34 #include <doc.hxx>
35 #include <fmtsrnd.hxx>
36 #include <svx/svdobj.hxx>
37 #include <dcontact.hxx>
38 #include <editeng/ulspitem.hxx>
39 #include <editeng/lrspitem.hxx>
40 #include <sortedobjs.hxx>
41 #include <pagefrm.hxx>
42 // <--
43 #include <frmatr.hxx>
44 // --> OD 2004-08-25 #i3317#
45 #include <colfrm.hxx>
46 // <--
47 // --> OD 2004-10-22 #i35911#
48 #include <layouter.hxx>
49 
50 
51 using namespace ::com::sun::star;
52 
53 
54 // <--
55 // ============================================================================
56 // --> OD 2004-06-30 #i28701# -
57 // implementation of helper class <SwObjPositioningInProgress>
58 // ============================================================================
SwObjPositioningInProgress(SdrObject & _rSdrObj)59 SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) :
60     mpAnchoredObj( 0L ),
61     // --> OD 2005-08-09 #i52904#
62     mbOldObjPositioningInProgress( false )
63     // <--
64 {
65     mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj );
66     // --> OD 2005-08-09 #i52904#
67     mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
68     // <--
69     mpAnchoredObj->SetPositioningInProgress( true );
70 }
SwObjPositioningInProgress(SwAnchoredObject & _rAnchoredObj)71 SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) :
72     mpAnchoredObj( &_rAnchoredObj ),
73     // --> OD 2005-08-09 #i52904#
74     mbOldObjPositioningInProgress( false )
75     // <--
76 {
77     // --> OD 2005-08-09 #i52904#
78     mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
79     // <--
80     mpAnchoredObj->SetPositioningInProgress( true );
81 }
82 
~SwObjPositioningInProgress()83 SwObjPositioningInProgress::~SwObjPositioningInProgress()
84 {
85     if ( mpAnchoredObj )
86     {
87         // --> OD 2005-08-09 #i52904#
88         mpAnchoredObj->SetPositioningInProgress( mbOldObjPositioningInProgress );
89         // <--
90     }
91 }
92 
93 // ============================================================================
94 
95 TYPEINIT0(SwAnchoredObject);
96 
SwAnchoredObject()97 SwAnchoredObject::SwAnchoredObject() :
98     mpDrawObj( 0L ),
99     mpAnchorFrm( 0L ),
100     // --> OD 2004-06-30 #i28701#
101     mpPageFrm( 0L ),
102     // <--
103     maRelPos(),
104     maLastCharRect(),
105     mnLastTopOfLine( 0L ),
106     mpVertPosOrientFrm( 0L ),
107     // --> OD 2004-06-29 #i28701#
108     mbPositioningInProgress( false ),
109     mbConsiderForTextWrap( false ),
110     mbPositionLocked( false ),
111     // --> OD 2005-01-10 #i40147#
112     mbKeepPositionLockedForSection( false ),
113     // <--
114     mbRestartLayoutProcess( false ),
115     // <--
116     // --> OD 2004-10-22 #i35911#
117     mbClearedEnvironment( false ),
118     // <--
119     // --> OD 2004-08-25 #i3317#
120     mbTmpConsiderWrapInfluence( false ),
121     // <--
122     // --> OD 2006-08-10 #i68520#
123     maObjRectWithSpaces(),
124     mbObjRectWithSpacesValid( false ),
125     maLastObjRect()
126     // <--
127 {
128 }
129 
~SwAnchoredObject()130 SwAnchoredObject::~SwAnchoredObject()
131 {
132 }
133 
134 // =============================================================================
135 // accessors for member <mpDrawObj>
136 // =============================================================================
SetDrawObj(SdrObject & _rDrawObj)137 void SwAnchoredObject::SetDrawObj( SdrObject& _rDrawObj )
138 {
139     mpDrawObj = &_rDrawObj;
140 }
141 
GetDrawObj() const142 const SdrObject* SwAnchoredObject::GetDrawObj() const
143 {
144     return mpDrawObj;
145 }
146 
DrawObj()147 SdrObject* SwAnchoredObject::DrawObj()
148 {
149     return mpDrawObj;
150 }
151 
152 // =============================================================================
153 // accessors for member <mpAnchorFrm>
154 // =============================================================================
GetAnchorFrm() const155 const SwFrm* SwAnchoredObject::GetAnchorFrm() const
156 {
157     return mpAnchorFrm;
158 }
159 
AnchorFrm()160 SwFrm* SwAnchoredObject::AnchorFrm()
161 {
162     return mpAnchorFrm;
163 }
164 
ChgAnchorFrm(SwFrm * _pNewAnchorFrm)165 void SwAnchoredObject::ChgAnchorFrm( SwFrm* _pNewAnchorFrm )
166 {
167     mpAnchorFrm = _pNewAnchorFrm;
168 
169     if ( mpAnchorFrm )
170     {
171         ObjectAttachedToAnchorFrame();
172     }
173 }
174 
175 /** determine anchor frame containing the anchor position
176 
177     OD 2004-10-08 #i26945#
178     the anchor frame, which is determined, is <mpAnchorFrm>
179     for an at-page, at-frame or at-paragraph anchored object
180     and the anchor character frame for an at-character and as-character
181     anchored object.
182 
183     @author OD
184 */
GetAnchorFrmContainingAnchPos()185 SwFrm* SwAnchoredObject::GetAnchorFrmContainingAnchPos()
186 {
187     SwFrm* pAnchorFrmContainingAnchPos = FindAnchorCharFrm();
188     if ( !pAnchorFrmContainingAnchPos )
189     {
190         pAnchorFrmContainingAnchPos = AnchorFrm();
191     }
192 
193     return pAnchorFrmContainingAnchPos;
194 }
195 
196 // =============================================================================
197 // OD 2004-06-30 #i28701# accessors for member <mpPageFrm>
198 // =============================================================================
GetPageFrm()199 SwPageFrm* SwAnchoredObject::GetPageFrm()
200 {
201     return mpPageFrm;
202 }
203 
GetPageFrm() const204 const SwPageFrm* SwAnchoredObject::GetPageFrm() const
205 {
206     return mpPageFrm;
207 }
208 
SetPageFrm(SwPageFrm * _pNewPageFrm)209 void SwAnchoredObject::SetPageFrm( SwPageFrm* _pNewPageFrm )
210 {
211     // --> OD 2006-01-02 #125977#
212     if ( mpPageFrm != _pNewPageFrm )
213     {
214         // clear member, which denotes the layout frame at which the vertical
215         // position is oriented at, if it doesn't fit to the new page frame.
216         if ( GetVertPosOrientFrm() &&
217              ( !_pNewPageFrm ||
218                _pNewPageFrm != GetVertPosOrientFrm()->FindPageFrm() ) )
219         {
220             ClearVertPosOrientFrm();
221         }
222 
223         // assign new page frame
224         mpPageFrm = _pNewPageFrm;
225     }
226     // <--
227 }
228 
229 // =============================================================================
230 // accessors for member <maLastCharRect>
231 // =============================================================================
GetLastCharRect() const232 const SwRect& SwAnchoredObject::GetLastCharRect() const
233 {
234     return maLastCharRect;
235 }
236 
GetRelCharX(const SwFrm * pFrm) const237 SwTwips SwAnchoredObject::GetRelCharX( const SwFrm* pFrm ) const
238 {
239     return maLastCharRect.Left() - pFrm->Frm().Left();
240 }
241 
GetRelCharY(const SwFrm * pFrm) const242 SwTwips SwAnchoredObject::GetRelCharY( const SwFrm* pFrm ) const
243 {
244     return maLastCharRect.Bottom() - pFrm->Frm().Top();
245 }
246 
AddLastCharY(long nDiff)247 void SwAnchoredObject::AddLastCharY( long nDiff )
248 {
249     maLastCharRect.Pos().Y() += nDiff;
250 }
251 
ResetLastCharRectHeight()252 void SwAnchoredObject::ResetLastCharRectHeight()
253 {
254     maLastCharRect.Height( 0 );
255 }
256 // =============================================================================
257 // accessors for member <mpVertPosOrientFrm>
258 // =============================================================================
SetVertPosOrientFrm(const SwLayoutFrm & _rVertPosOrientFrm)259 void SwAnchoredObject::SetVertPosOrientFrm( const SwLayoutFrm& _rVertPosOrientFrm )
260 {
261     mpVertPosOrientFrm = &_rVertPosOrientFrm;
262 
263     // --> OD 2004-07-02 #i28701# - take over functionality of deleted method
264     // <SwFlyAtCntFrm::AssertPage()>: assure for at-paragraph and at-character
265     // an anchored object, that it is registered at the correct page frame
266     RegisterAtCorrectPage();
267 }
268 
269 // =============================================================================
270 // accessors for member <mnLastTopOfLine>
271 // =============================================================================
GetLastTopOfLine() const272 SwTwips SwAnchoredObject::GetLastTopOfLine() const
273 {
274     return mnLastTopOfLine;
275 }
276 
277 // OD 2004-05-18 #i28701# - follow-up of #i22341#
AddLastTopOfLineY(SwTwips _nDiff)278 void SwAnchoredObject::AddLastTopOfLineY( SwTwips _nDiff )
279 {
280     mnLastTopOfLine += _nDiff;
281 }
282 
283 /** check anchor character rectangle and top of line
284 
285     OD 2004-03-24 #i26791
286     For to-character anchored Writer fly frames the members <maLastCharRect>
287     and <maLastTopOfLine> are updated. These are checked for change and
288     depending on the applied positioning, it's decided, if the Writer fly
289     frame has to be invalidated.
290     OD 2004-07-15 #117380#
291     add parameter <_bCheckForParaPorInf>, default value <true>
292 
293     @author OD
294 */
CheckCharRectAndTopOfLine(const bool _bCheckForParaPorInf)295 void SwAnchoredObject::CheckCharRectAndTopOfLine(
296                                         const bool _bCheckForParaPorInf )
297 {
298     if ( GetAnchorFrm() &&
299          GetAnchorFrm()->IsTxtFrm() )
300     {
301         const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor();
302         if ( (rAnch.GetAnchorId() == FLY_AT_CHAR) &&
303              rAnch.GetCntntAnchor() )
304         {
305             // --> OD 2004-07-14 #117380# - if requested, assure that anchor frame,
306             // which contains the anchor character, has a paragraph portion information.
307             // The paragraph portion information is needed to determine the
308             // anchor character rectangle respectively the top of the line.
309             // Thus, a format of this frame is avoided to determine the
310             // paragraph portion information.
311             // --> OD 2004-10-04 #i26945# - use new method <FindAnchorCharFrm()>
312             const SwTxtFrm& aAnchorCharFrm = *(FindAnchorCharFrm());
313             // <--
314             if ( !_bCheckForParaPorInf || aAnchorCharFrm.HasPara() )
315             {
316                 _CheckCharRect( rAnch, aAnchorCharFrm );
317                 _CheckTopOfLine( rAnch, aAnchorCharFrm );
318             }
319             // <--
320         }
321     }
322 }
323 
324 /** check anchor character rectangle
325 
326     OD 11.11.2003 #i22341#
327     helper method for method <CheckCharRectAndTopOfLine()>
328     For to-character anchored Writer fly frames the member <maLastCharRect>
329     is updated. This is checked for change and depending on the applied
330     positioning, it's decided, if the Writer fly frame has to be invalidated.
331     OD 2004-07-14 #117380#
332     improvement - add second parameter <_rAnchorCharFrm>
333 
334     @author OD
335 */
_CheckCharRect(const SwFmtAnchor & _rAnch,const SwTxtFrm & _rAnchorCharFrm)336 void SwAnchoredObject::_CheckCharRect( const SwFmtAnchor& _rAnch,
337                                        const SwTxtFrm& _rAnchorCharFrm )
338 {
339     // determine rectangle of anchor character. If not exist, abort operation
340     SwRect aCharRect;
341     if ( !_rAnchorCharFrm.GetAutoPos( aCharRect, *_rAnch.GetCntntAnchor() ) )
342     {
343         return;
344     }
345     // check, if anchor character rectangle has changed
346     if ( aCharRect != maLastCharRect )
347     {
348         // check positioning and alignment for invalidation of position
349         {
350             SWRECTFN( (&_rAnchorCharFrm) );
351             // determine positioning and alignment
352             SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() );
353             SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() );
354             // check for anchor character rectangle changes for certain
355             // positionings and alignments
356             // OD 07.10.2003 #110978# - add condition to invalidate position,
357             // if vertical aligned at frame/page area and vertical position
358             // of anchor character has changed.
359             const sal_Int16 eVertRelOrient = aVert.GetRelationOrient();
360             if ( ( aHori.GetRelationOrient() == text::RelOrientation::CHAR &&
361                    (aCharRect.*fnRect->fnGetLeft)() !=
362                         (maLastCharRect.*fnRect->fnGetLeft)() ) ||
363                  ( eVertRelOrient == text::RelOrientation::CHAR &&
364                    ( (aCharRect.*fnRect->fnGetTop)() !=
365                         (maLastCharRect.*fnRect->fnGetTop)() ||
366                      (aCharRect.*fnRect->fnGetHeight)() !=
367                         (maLastCharRect.*fnRect->fnGetHeight)() ) ) ||
368                  ( ( ( eVertRelOrient == text::RelOrientation::FRAME ) ||
369                      ( eVertRelOrient == text::RelOrientation::PRINT_AREA ) ||
370                      ( eVertRelOrient == text::RelOrientation::PAGE_FRAME ) ||
371                      ( eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA ) ) &&
372                    ( (aCharRect.*fnRect->fnGetTop)() !=
373                         (maLastCharRect.*fnRect->fnGetTop)() ) ) )
374             {
375                 // --> OD 2004-10-08 #i26945#, #i35911# - unlock position of
376                 // anchored object, if it isn't registered at the page,
377                 // where its anchor character frame is on.
378                 if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() )
379                 {
380                     UnlockPosition();
381                 }
382                 // <--
383                 InvalidateObjPos();
384             }
385         }
386         // keep new anchor character rectangle
387         maLastCharRect = aCharRect;
388     }
389 }
390 
391 /** check top of line
392 
393     OD 11.11.2003 #i22341#
394     helper method for method <CheckCharRectAndTopOfLine()>
395     For to-character anchored Writer fly frames the member <mnLastTopOfLine>
396     is updated. This is checked for change and depending on the applied
397     positioning, it's decided, if the Writer fly frame has to be invalidated.
398     OD 2004-07-14 #117380#
399     improvement - add second parameter <_rAnchorCharFrm>
400 
401     @author OD
402 */
_CheckTopOfLine(const SwFmtAnchor & _rAnch,const SwTxtFrm & _rAnchorCharFrm)403 void SwAnchoredObject::_CheckTopOfLine( const SwFmtAnchor& _rAnch,
404                                         const SwTxtFrm& _rAnchorCharFrm )
405 {
406     SwTwips nTopOfLine = 0L;
407     if ( _rAnchorCharFrm.GetTopOfLine( nTopOfLine, *_rAnch.GetCntntAnchor() ) )
408     {
409         if ( nTopOfLine != mnLastTopOfLine )
410         {
411             // check alignment for invalidation of position
412             if ( GetFrmFmt().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE )
413             {
414                 // --> OD 2004-10-08 #i26945#, #i35911# - unlock position of
415                 // anchored object, if it isn't registered at the page,
416                 // where its anchor character frame is on.
417                 if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() )
418                 {
419                     UnlockPosition();
420                 }
421                 // <--
422                 InvalidateObjPos();
423             }
424             // keep new top of line value
425             mnLastTopOfLine = nTopOfLine;
426         }
427     }
428 }
429 
ClearCharRectAndTopOfLine()430 void SwAnchoredObject::ClearCharRectAndTopOfLine()
431 {
432     maLastCharRect.Clear();
433     mnLastTopOfLine = 0;
434 }
435 
GetCurrRelPos() const436 const Point SwAnchoredObject::GetCurrRelPos() const
437 {
438     return maRelPos;
439 }
SetCurrRelPos(Point _aRelPos)440 void SwAnchoredObject::SetCurrRelPos( Point _aRelPos )
441 {
442     maRelPos = _aRelPos;
443 }
444 
ObjectAttachedToAnchorFrame()445 void SwAnchoredObject::ObjectAttachedToAnchorFrame()
446 {
447     // default behaviour:
448     // update layout direction, the anchored object is assigned to
449     UpdateLayoutDir();
450 }
451 
452 /** method update layout direction the layout direction, the anchored
453     object is in
454 
455     OD 2004-07-27 #i31698#
456     method has typically to be called, if the anchored object gets its
457     anchor frame assigned.
458 
459     @author OD
460 */
UpdateLayoutDir()461 void SwAnchoredObject::UpdateLayoutDir()
462 {
463     SwFrmFmt::tLayoutDir nLayoutDir = SwFrmFmt::HORI_L2R;
464     const SwFrm* pAnchorFrm = GetAnchorFrm();
465     if ( pAnchorFrm )
466     {
467         const bool bVert = pAnchorFrm->IsVertical();
468         const bool bR2L = pAnchorFrm->IsRightToLeft();
469         if ( bVert )
470         {
471             nLayoutDir = SwFrmFmt::VERT_R2L;
472         }
473         else if ( bR2L )
474         {
475             nLayoutDir = SwFrmFmt::HORI_R2L;
476         }
477     }
478     GetFrmFmt().SetLayoutDir( nLayoutDir );
479 }
480 
481 /** method to perform necessary invalidations for the positioning of
482     objects, for whose the wrapping style influence has to be considered
483     on the object positioning.
484 
485     OD 2004-06-30 #i28701#
486 
487     @author OD
488 */
InvalidateObjPosForConsiderWrapInfluence(const bool _bNotifyBackgrd)489 void SwAnchoredObject::InvalidateObjPosForConsiderWrapInfluence(
490                                                     const bool _bNotifyBackgrd )
491 {
492     if ( ConsiderObjWrapInfluenceOnObjPos() )
493     {
494         // indicate that object has not to be considered for text wrap
495         SetConsiderForTextWrap( false );
496         // unlock position
497         UnlockPosition();
498         // invalidate position
499         InvalidateObjPos();
500         // invalidate 'background', if requested
501         if ( _bNotifyBackgrd )
502         {
503             NotifyBackground( GetPageFrm(), GetObjRectWithSpaces(), PREP_FLY_LEAVE );
504         }
505     }
506 }
507 
508 /** method to determine, if wrapping style influence of the anchored
509     object has to be considered on the object positioning
510 
511     OD 2004-06-30 #i28701#
512     Note: result of this method also decides, if the booleans for the
513     layout process are of relevance.
514 
515     @author OD
516 */
ConsiderObjWrapInfluenceOnObjPos() const517 bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const
518 {
519     bool bRet( false );
520 
521     const SwFrmFmt& rObjFmt = GetFrmFmt();
522 
523     // --> OD 2004-08-25 #i3317# - add condition <IsTmpConsiderWrapInfluence()>
524     // --> OD 2005-09-29 #i55204#
525     // - correction: wrapping style influence has been considered, if condition
526     //   <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type
527     //   or its wrapping style.
528     if ( IsTmpConsiderWrapInfluence() )
529     {
530         bRet = true;
531     }
532     else if ( rObjFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
533     // <--
534     {
535         const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor();
536         if ( ((rAnchor.GetAnchorId() == FLY_AT_CHAR) ||
537               (rAnchor.GetAnchorId() == FLY_AT_PARA)) &&
538              rObjFmt.GetSurround().GetSurround() != SURROUND_THROUGHT )
539         {
540             // --> OD 2004-09-23 #i34520# - text also wraps around anchored
541             // objects in the layer Hell - see the text formatting.
542             // Thus, it hasn't to be checked here.
543             bRet = true;
544             // <--
545         }
546     }
547 
548     return bRet;
549 }
550 
551 /** method to determine, if other anchored objects, also attached at
552     to the anchor frame, have to consider its wrap influence.
553 
554     // --> OD 2005-02-22 #i43255#
555 
556     @author OD
557 */
ConsiderObjWrapInfluenceOfOtherObjs() const558 bool SwAnchoredObject::ConsiderObjWrapInfluenceOfOtherObjs() const
559 {
560     bool bRet( false );
561 
562     const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
563     if ( pObjs->Count() > 1 )
564     {
565         sal_uInt32 i = 0;
566         for ( ; i < pObjs->Count(); ++i )
567         {
568             SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
569             if ( pAnchoredObj != this &&
570                  pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
571             {
572                 bRet = true;
573                 break;
574             }
575         }
576     }
577 
578     return bRet;
579 }
580 
581 // =============================================================================
582 // --> OD 2004-06-29 #i28701# - accessors to booleans for layout process
583 // =============================================================================
ConsiderForTextWrap() const584 bool SwAnchoredObject::ConsiderForTextWrap() const
585 {
586     if ( ConsiderObjWrapInfluenceOnObjPos() )
587         return mbConsiderForTextWrap;
588     else
589         return true;
590 }
591 
SetConsiderForTextWrap(const bool _bConsiderForTextWrap)592 void SwAnchoredObject::SetConsiderForTextWrap( const bool _bConsiderForTextWrap )
593 {
594     mbConsiderForTextWrap = _bConsiderForTextWrap;
595 }
596 
PositionLocked() const597 bool SwAnchoredObject::PositionLocked() const
598 {
599     if ( ConsiderObjWrapInfluenceOnObjPos() )
600         return mbPositionLocked;
601     else
602         return false;
603 }
604 
RestartLayoutProcess() const605 bool SwAnchoredObject::RestartLayoutProcess() const
606 {
607     if ( ConsiderObjWrapInfluenceOnObjPos() )
608         return mbRestartLayoutProcess;
609     else
610         return false;
611 }
612 
SetRestartLayoutProcess(const bool _bRestartLayoutProcess)613 void SwAnchoredObject::SetRestartLayoutProcess( const bool _bRestartLayoutProcess )
614 {
615     mbRestartLayoutProcess = _bRestartLayoutProcess;
616 }
617 
618 // --> OD 2004-10-22 #i35911#
ClearedEnvironment() const619 bool SwAnchoredObject::ClearedEnvironment() const
620 {
621     if ( ConsiderObjWrapInfluenceOnObjPos() )
622         return mbClearedEnvironment;
623     else
624         return false;
625 }
SetClearedEnvironment(const bool _bClearedEnvironment)626 void SwAnchoredObject::SetClearedEnvironment( const bool _bClearedEnvironment )
627 {
628     mbClearedEnvironment = _bClearedEnvironment;
629 }
630 // <--
631 
632 /** method to determine, if due to anchored object size and wrapping
633     style, its layout environment is cleared.
634 
635     OD 2004-10-22 #i35911#
636 
637     @author OD
638 */
HasClearedEnvironment() const639 bool SwAnchoredObject::HasClearedEnvironment() const
640 {
641     bool bHasClearedEnvironment( false );
642 
643     // --> OD 2005-03-03 #i43913# - layout frame, vertical position is orient at, has to be set.
644     ASSERT( GetVertPosOrientFrm(),
645             "<SwAnchoredObject::HasClearedEnvironment()> - layout frame missing, at which the vertical position is oriented at." );
646     if ( GetVertPosOrientFrm() &&
647          GetAnchorFrm()->IsTxtFrm() &&
648          !static_cast<const SwTxtFrm*>(GetAnchorFrm())->IsFollow() &&
649          static_cast<const SwTxtFrm*>(GetAnchorFrm())->FindPageFrm()->GetPhyPageNum() >=
650                 GetPageFrm()->GetPhyPageNum() )
651     // <--
652     {
653         const SwFrm* pTmpFrm = GetVertPosOrientFrm()->Lower();
654         while ( pTmpFrm && pTmpFrm->IsLayoutFrm() && !pTmpFrm->IsTabFrm() )
655         {
656             pTmpFrm = static_cast<const SwLayoutFrm*>(pTmpFrm)->Lower();
657         }
658         if ( !pTmpFrm )
659         {
660             bHasClearedEnvironment = true;
661         }
662         else if ( pTmpFrm->IsTxtFrm() && !pTmpFrm->GetNext() )
663         {
664             const SwTxtFrm* pTmpTxtFrm = static_cast<const SwTxtFrm*>(pTmpFrm);
665             if ( pTmpTxtFrm->IsUndersized() ||
666                  ( pTmpTxtFrm->GetFollow() &&
667                    pTmpTxtFrm->GetFollow()->GetOfst() == 0 ) )
668             {
669                 bHasClearedEnvironment = true;
670             }
671         }
672     }
673 
674     return bHasClearedEnvironment;
675 }
676 
677 /** method to add spacing to object area
678 
679     OD 2004-06-30 #i28701#
680     OD 2006-08-10 #i68520# - return constant reference and use cache
681 
682     @author OD
683 */
GetObjRectWithSpaces() const684 const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const
685 {
686     if ( mbObjRectWithSpacesValid &&
687          maLastObjRect != GetObjRect() )
688     {
689         ASSERT( false,
690                 "<SwAnchoredObject::GetObjRectWithSpaces> - cache for object rectangle inclusive spaces marked as valid, but it couldn't be. Missing invalidation of cache. Please inform OD." );
691         InvalidateObjRectWithSpaces();
692     }
693     if ( !mbObjRectWithSpacesValid )
694     {
695         // --> OD 2006-10-05 #i70122# - correction:
696         // use bounding rectangle of anchored objects.
697 //        maObjRectWithSpaces = GetObjRect();
698         maObjRectWithSpaces = GetObjBoundRect();
699         // <--
700         const SwFrmFmt& rFmt = GetFrmFmt();
701         const SvxULSpaceItem& rUL = rFmt.GetULSpace();
702         const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
703         {
704             maObjRectWithSpaces.Top ( Max( maObjRectWithSpaces.Top() - long(rUL.GetUpper()), 0L ));
705             maObjRectWithSpaces.Left( Max( maObjRectWithSpaces.Left()- long(rLR.GetLeft()),  0L ));
706             maObjRectWithSpaces.SSize().Height() += rUL.GetLower();
707             maObjRectWithSpaces.SSize().Width()  += rLR.GetRight();
708         }
709 
710         mbObjRectWithSpacesValid = true;
711         maLastObjRect = GetObjRect();
712     }
713 
714     return maObjRectWithSpaces;
715 }
716 
717 // --> OD 2006-08-10 #i68520#
SetObjTop(const SwTwips _nTop)718 void SwAnchoredObject::SetObjTop( const SwTwips _nTop)
719 {
720     const bool bTopChanged( _SetObjTop( _nTop ) );
721     if ( bTopChanged )
722     {
723         mbObjRectWithSpacesValid = false;
724     }
725 }
726 
SetObjLeft(const SwTwips _nLeft)727 void SwAnchoredObject::SetObjLeft( const SwTwips _nLeft)
728 {
729     const bool bLeftChanged( _SetObjLeft( _nLeft ) );
730     if ( bLeftChanged )
731     {
732         mbObjRectWithSpacesValid = false;
733     }
734 }
735 // <--
736 
737 /** method to update anchored object in the <SwSortedObjs> lists
738 
739     OD 2004-07-01 #i28701#
740     If document compatibility option 'Consider wrapping style influence
741     on object positioning' is ON, additionally all anchored objects
742     at the anchor frame and all following anchored objects on the page
743     frame are invalidated.
744 
745     @author OD
746 */
UpdateObjInSortedList()747 void SwAnchoredObject::UpdateObjInSortedList()
748 {
749     if ( GetAnchorFrm() )
750     {
751         if ( GetFrmFmt().getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
752         {
753             // invalidate position of all anchored objects at anchor frame
754             if ( GetAnchorFrm()->GetDrawObjs() )
755             {
756                 const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
757                 // determine start index
758                 sal_uInt32 i = 0;
759                 for ( ; i < pObjs->Count(); ++i )
760                 {
761                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
762                     if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
763                         pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
764                     else
765                         pAnchoredObj->InvalidateObjPos();
766                 }
767             }
768             // invalidate all following anchored objects on the page frame
769             if ( GetPageFrm() && GetPageFrm()->GetSortedObjs() )
770             {
771                 const SwSortedObjs* pObjs = GetPageFrm()->GetSortedObjs();
772                 // determine start index
773                 sal_uInt32 i = pObjs->ListPosOf( *this ) + 1;
774                 for ( ; i < pObjs->Count(); ++i )
775                 {
776                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
777                     if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
778                         pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
779                     else
780                         pAnchoredObj->InvalidateObjPos();
781                 }
782             }
783         }
784         // update its position in the sorted object list of its anchor frame
785         AnchorFrm()->GetDrawObjs()->Update( *this );
786         // update its position in the sorted object list of its page frame
787         // note: as-character anchored object aren't registered at a page frame
788         if ( GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR )
789         {
790             GetPageFrm()->GetSortedObjs()->Update( *this );
791         }
792     }
793 }
794 
795 /** method to determine, if invalidation of position is allowed
796 
797     OD 2004-07-01 #i28701#
798 
799     @author OD
800 */
InvalidationOfPosAllowed() const801 bool SwAnchoredObject::InvalidationOfPosAllowed() const
802 {
803     // --> OD 2004-11-03 #114798# - Check, if page frame layout is in progress,
804     // isn't needed, because of anchored object, whose are moved forward.
805     return !PositionLocked();
806     // <--
807 }
808 
809 /** method to determine the page frame, on which the 'anchor' of
810     the given anchored object is.
811 
812     OD 2004-07-02 #i28701#
813     OD 2004-09-23 #i33751#, #i34060#
814     Adjust meaning of method and thus its name: If the anchored object
815     or its anchor isn't correctly inserted in the layout, no page frame
816     can be found. Thus, the return type changed to be a pointer and can
817     be NULL.
818 
819     @author OD
820 */
FindPageFrmOfAnchor()821 SwPageFrm* SwAnchoredObject::FindPageFrmOfAnchor()
822 {
823     SwPageFrm* pRetPageFrm = 0L;
824 
825     // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
826     if ( mpAnchorFrm )
827     {
828         // --> OD 2004-10-08 #i26945# - use new method <GetAnchorFrmContainingAnchPos()>
829         pRetPageFrm = GetAnchorFrmContainingAnchPos()->FindPageFrm();
830         // <--
831     }
832 
833     return pRetPageFrm;
834 }
835 
836 /** get frame, which contains the anchor character, if the object
837     is anchored at-character or as-character.
838 
839     OD 2004-10-04 #i26945#
840 
841     @author OD
842 
843     @return SwTxtFrm*
844     text frame containing the anchor character. It's NULL, if the object
845     isn't anchored at-character resp. as-character.
846 */
FindAnchorCharFrm()847 SwTxtFrm* SwAnchoredObject::FindAnchorCharFrm()
848 {
849     SwTxtFrm* pAnchorCharFrm( 0L );
850 
851     // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
852     if ( mpAnchorFrm )
853     {
854         const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor();
855         if ((rAnch.GetAnchorId() == FLY_AT_CHAR) ||
856             (rAnch.GetAnchorId() == FLY_AS_CHAR))
857         {
858             pAnchorCharFrm = &(static_cast<SwTxtFrm*>(AnchorFrm())->
859                         GetFrmAtOfst( rAnch.GetCntntAnchor()->nContent.GetIndex() ));
860         }
861     }
862     // <--
863 
864     return pAnchorCharFrm;
865 }
866 
867 /** method to determine, if a format on the anchored object is possible
868 
869     OD 2004-07-23 #i28701#
870     A format is possible, if anchored object is in an invisible layer.
871     Note: method is virtual to refine the conditions for the sub-classes.
872 
873     @author OD
874 */
IsFormatPossible() const875 bool SwAnchoredObject::IsFormatPossible() const
876 {
877     return GetFrmFmt().GetDoc()->IsVisibleLayerId( GetDrawObj()->GetLayer() );
878 }
879 
880 // --> OD 2004-08-25 #i3317#
SetTmpConsiderWrapInfluence(const bool _bTmpConsiderWrapInfluence)881 void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrapInfluence )
882 {
883     mbTmpConsiderWrapInfluence = _bTmpConsiderWrapInfluence;
884     // --> OD 2004-10-22 #i35911#
885     if ( mbTmpConsiderWrapInfluence )
886     {
887         SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrmFmt().GetDoc()),
888                                                           *this );
889     }
890     // <--
891 }
892 
IsTmpConsiderWrapInfluence() const893 bool SwAnchoredObject::IsTmpConsiderWrapInfluence() const
894 {
895     return mbTmpConsiderWrapInfluence;
896 }
897 // <--
898 
899 // --> OD 2006-07-24 #b6449874#
SetTmpConsiderWrapInfluenceOfOtherObjs(const bool bTmpConsiderWrapInfluence)900 void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs( const bool bTmpConsiderWrapInfluence )
901 {
902     const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs();
903     if ( pObjs->Count() > 1 )
904     {
905         sal_uInt32 i = 0;
906         for ( ; i < pObjs->Count(); ++i )
907         {
908             SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
909             if ( pAnchoredObj != this )
910             {
911                 pAnchoredObj->SetTmpConsiderWrapInfluence( bTmpConsiderWrapInfluence );
912             }
913         }
914     }
915 }
916 // <--
917 
918 /** method to determine, if the anchored object is overlapping with a
919     previous column
920 
921     OD 2004-08-25 #i3317#
922     overlapping with a previous column means, that the object overlaps
923     with a column, which is a previous one of the column its anchor
924     frame is in.
925     Only applied for at-paragraph and at-character anchored objects.
926 
927     @author OD
928 */
OverlapsPrevColumn() const929 bool SwAnchoredObject::OverlapsPrevColumn() const
930 {
931     bool bOverlapsPrevColumn( false );
932 
933     if ( mpAnchorFrm && mpAnchorFrm->IsTxtFrm() )
934     {
935         const SwFrm* pColFrm = mpAnchorFrm->FindColFrm();
936         if ( pColFrm && pColFrm->GetPrev() )
937         {
938             const SwFrm* pTmpColFrm = pColFrm->GetPrev();
939             SwRect aChkRect;
940             while ( pTmpColFrm )
941             {
942                 aChkRect.Union( pTmpColFrm->Frm() );
943                 pTmpColFrm = pTmpColFrm->GetPrev();
944             }
945             bOverlapsPrevColumn = GetObjRect().IsOver( aChkRect );
946         }
947     }
948 
949     return bOverlapsPrevColumn;
950 }
951 
952 /** method to determine position of anchored object relative to
953     anchor frame
954 
955     OD 2005-01-06 #i30669#
956     Usage: Needed layout information for WW8 export
957 
958     @author OD
959 */
GetRelPosToAnchorFrm() const960 Point SwAnchoredObject::GetRelPosToAnchorFrm() const
961 {
962     Point aRelPos;
963 
964     ASSERT( GetAnchorFrm(),
965             "<SwAnchoredObject::GetRelPosToAnchorFrm()> - missing anchor frame." );
966     aRelPos = GetObjRect().Pos();
967     aRelPos -= GetAnchorFrm()->Frm().Pos();
968 
969     return aRelPos;
970 }
971 
972 /** method to determine position of anchored object relative to
973     page frame
974 
975     OD 2005-01-06 #i30669#
976     Usage: Needed layout information for WW8 export
977     OD 2005-01-27 #i33818# - add parameters <_bFollowTextFlow> and
978     <_obRelToTableCell>
979     If <_bFollowTextFlow> is set and object is anchored inside table,
980     the position relative to the table cell is determined. Output
981     parameter <_obRelToTableCell> reflects this situation
982 
983     @author OD
984 */
GetRelPosToPageFrm(const bool _bFollowTextFlow,bool & _obRelToTableCell) const985 Point SwAnchoredObject::GetRelPosToPageFrm( const bool _bFollowTextFlow,
986                                             bool& _obRelToTableCell ) const
987 {
988     Point aRelPos;
989     _obRelToTableCell = false;
990 
991     ASSERT( GetAnchorFrm(),
992             "<SwAnchoredObject::GetRelPosToPageFrm()> - missing anchor frame." );
993     ASSERT( GetAnchorFrm()->FindPageFrm(),
994             "<SwAnchoredObject::GetRelPosToPageFrm()> - missing page frame." );
995 
996     aRelPos = GetObjRect().Pos();
997     // --> OD 2005-01-27 #i33818# - search for cell frame, if object has to
998     // follow the text flow.
999     const SwFrm* pFrm( 0L );
1000     if ( _bFollowTextFlow && !GetAnchorFrm()->IsPageFrm() )
1001     {
1002         pFrm = GetAnchorFrm()->GetUpper();
1003         while ( !pFrm->IsCellFrm() && !pFrm->IsPageFrm() )
1004         {
1005             pFrm = pFrm->GetUpper();
1006         }
1007     }
1008     else
1009     {
1010         pFrm = GetAnchorFrm()->FindPageFrm();
1011     }
1012     if ( pFrm->IsCellFrm() )
1013     {
1014         aRelPos -= ( pFrm->Frm().Pos() + pFrm->Prt().Pos() );
1015         _obRelToTableCell = true;
1016     }
1017     else
1018     {
1019         aRelPos -= pFrm->Frm().Pos();
1020     }
1021     // <--
1022 
1023     return aRelPos;
1024 }
1025 
1026 /** method to determine position of anchored object relative to
1027     anchor character
1028 
1029     OD 2005-01-06 #i30669#
1030     Usage: Needed layout information for WW8 export
1031 
1032     @author OD
1033 */
GetRelPosToChar() const1034 Point SwAnchoredObject::GetRelPosToChar() const
1035 {
1036     Point aRelPos;
1037 
1038     aRelPos = GetObjRect().Pos();
1039     aRelPos -= GetLastCharRect().Pos();
1040 
1041     return aRelPos;
1042 }
1043 
1044 /** method to determine position of anchored object relative to
1045     top of line
1046 
1047     OD 2005-01-06 #i30669#
1048     Usage: Needed layout information for WW8 export
1049 
1050     @author OD
1051 */
GetRelPosToLine() const1052 Point SwAnchoredObject::GetRelPosToLine() const
1053 {
1054     Point aRelPos;
1055 
1056     aRelPos = GetObjRect().Pos();
1057     aRelPos.Y() -= GetLastTopOfLine();
1058 
1059     return aRelPos;
1060 }
1061