LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/layout - anchoreddrawobject.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 238 300 79.3 %
Date: 2013-07-09 Functions: 31 37 83.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10