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

Generated by: LCOV version 1.10