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

Generated by: LCOV version 1.10