diff options
Diffstat (limited to 'sw/source/core/draw/dflyobj.cxx')
-rw-r--r-- | sw/source/core/draw/dflyobj.cxx | 962 |
1 files changed, 962 insertions, 0 deletions
diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx new file mode 100644 index 000000000000..75111933e0ec --- /dev/null +++ b/sw/source/core/draw/dflyobj.cxx @@ -0,0 +1,962 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sw.hxx" +#include "hintids.hxx" +#include <svx/svdtrans.hxx> +#include <editeng/protitem.hxx> +#include <editeng/opaqitem.hxx> +#include <svx/svdpage.hxx> + + +#include <fmtclds.hxx> +#include <fmtornt.hxx> +#include <fmtfsize.hxx> +#include <fmturl.hxx> +#include "viewsh.hxx" +#include "viewimp.hxx" +#include "cntfrm.hxx" +#include "frmatr.hxx" +#include "doc.hxx" +#include "dview.hxx" +#include "dflyobj.hxx" +#include "flyfrm.hxx" +#include "frmfmt.hxx" +#include "viewopt.hxx" +#include "frmtool.hxx" +#include "flyfrms.hxx" +#include "ndnotxt.hxx" +#include "grfatr.hxx" +#include "pagefrm.hxx" + + +using namespace ::com::sun::star; + + +// --> OD 2004-11-22 #117958# +#include <svx/sdr/properties/defaultproperties.hxx> +// <-- +#include <basegfx/range/b2drange.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +// AW: For VCOfDrawVirtObj and stuff +#include <svx/sdr/contact/viewcontactofvirtobj.hxx> +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <sw_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +using namespace ::com::sun::star; + +static BOOL bInResize = FALSE; + +TYPEINIT1( SwFlyDrawObj, SdrObject ) +TYPEINIT1( SwVirtFlyDrawObj, SdrVirtObj ) + +/************************************************************************* +|* +|* SwFlyDrawObj::Ctor +|* +|* Ersterstellung MA 18. Apr. 95 +|* Letzte Aenderung MA 28. May. 96 +|* +*************************************************************************/ + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // #i95264# currently needed since createViewIndependentPrimitive2DSequence() + // is called when RecalcBoundRect() is used. There should currently no VOCs being + // constructed since it gets not visualized (instead the corresponding SwVirtFlyDrawObj's + // referencing this one are visualized). + class VCOfSwFlyDrawObj : public ViewContactOfSdrObj + { + protected: + // This method is responsible for creating the graphical visualisation data + // ONLY based on model data + virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const; + + public: + // basic constructor, used from SdrObject. + VCOfSwFlyDrawObj(SwFlyDrawObj& rObj) + : ViewContactOfSdrObj(rObj) + { + } + virtual ~VCOfSwFlyDrawObj(); + }; + + drawinglayer::primitive2d::Primitive2DSequence VCOfSwFlyDrawObj::createViewIndependentPrimitive2DSequence() const + { + // currently gets not visualized, return empty sequence + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + VCOfSwFlyDrawObj::~VCOfSwFlyDrawObj() + { + } + } // end of namespace contact +} // end of namespace sdr + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +sdr::properties::BaseProperties* SwFlyDrawObj::CreateObjectSpecificProperties() +{ + // --> OD 2004-11-22 #117958# - create default properties + return new sdr::properties::DefaultProperties(*this); + // <-- +} + +sdr::contact::ViewContact* SwFlyDrawObj::CreateObjectSpecificViewContact() +{ + // #i95264# needs an own VC since createViewIndependentPrimitive2DSequence() + // is called when RecalcBoundRect() is used + return new sdr::contact::VCOfSwFlyDrawObj(*this); +} + +SwFlyDrawObj::SwFlyDrawObj() +{ +} + +SwFlyDrawObj::~SwFlyDrawObj() +{ +} + +/************************************************************************* +|* +|* SwFlyDrawObj::Factory-Methoden +|* +|* Ersterstellung MA 23. Feb. 95 +|* Letzte Aenderung MA 23. Feb. 95 +|* +*************************************************************************/ + +UINT32 __EXPORT SwFlyDrawObj::GetObjInventor() const +{ + return SWGInventor; +} + + +UINT16 __EXPORT SwFlyDrawObj::GetObjIdentifier() const +{ + return SwFlyDrawObjIdentifier; +} + + +UINT16 __EXPORT SwFlyDrawObj::GetObjVersion() const +{ + return SwDrawFirst; +} + +/************************************************************************* +|* +|* SwVirtFlyDrawObj::CToren, Dtor +|* +|* Ersterstellung MA 08. Dec. 94 +|* Letzte Aenderung MA 28. May. 96 +|* +*************************************************************************/ + +////////////////////////////////////////////////////////////////////////////////////// +// AW: Need own primitive to get the FlyFrame paint working + +namespace drawinglayer +{ + namespace primitive2d + { + class SwVirtFlyDrawObjPrimitive : public BufferedDecompositionPrimitive2D + { + private: + const SwVirtFlyDrawObj& mrSwVirtFlyDrawObj; + const basegfx::B2DRange maOuterRange; + + protected: + // method which is to be used to implement the local decomposition of a 2D primitive + virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + public: + SwVirtFlyDrawObjPrimitive( + const SwVirtFlyDrawObj& rSwVirtFlyDrawObj, + const basegfx::B2DRange &rOuterRange) + : BufferedDecompositionPrimitive2D(), + mrSwVirtFlyDrawObj(rSwVirtFlyDrawObj), + maOuterRange(rOuterRange) + { + } + + // compare operator + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + // get range + virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const; + + // overloaded to allow callbacks to wrap_DoPaintObject + virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const; + + // data read access + const SwVirtFlyDrawObj& getSwVirtFlyDrawObj() const { return mrSwVirtFlyDrawObj; } + const basegfx::B2DRange& getOuterRange() const { return maOuterRange; } + + // provide unique ID + DeclPrimitrive2DIDBlock() + }; + } // end of namespace primitive2d +} // end of namespace drawinglayer + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SwVirtFlyDrawObjPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + + if(!getOuterRange().isEmpty()) + { + // currently this SW object has no primitive representation. As long as this is the case, + // create invisible geometry to allow corfect HitTest and BoundRect calculations for the + // object. Use a filled primitive to get 'inside' as default object hit. The special cases from + // the old SwVirtFlyDrawObj::CheckHit implementation are handled now in SwDrawView::PickObj; + // this removed the 'hack' to get a view from inside model data or to react on null-tolerance + // as it was done in the old implementation + const Primitive2DReference aHitTestReference( + createHiddenGeometryPrimitives2D( + true, + getOuterRange())); + + aRetval = Primitive2DSequence(&aHitTestReference, 1); + } + + return aRetval; + } + + bool SwVirtFlyDrawObjPrimitive::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SwVirtFlyDrawObjPrimitive& rCompare = (SwVirtFlyDrawObjPrimitive&)rPrimitive; + + return (&getSwVirtFlyDrawObj() == &rCompare.getSwVirtFlyDrawObj() + && getOuterRange() == rCompare.getOuterRange()); + } + + return false; + } + + basegfx::B2DRange SwVirtFlyDrawObjPrimitive::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + return getOuterRange(); + } + + Primitive2DSequence SwVirtFlyDrawObjPrimitive::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + // This is the callback to keep the FlyFrame painting in SW alive as long as it + // is not changed to primitives. This is the method which will be called by the processors + // when they do not know this primitive (and they do not). Inside wrap_DoPaintObject + // there needs to be a test that paint is only done during SW repaints (see there). + // Using this mechanism guarantees the correct Z-Order of the VirtualObject-based FlyFrames. + getSwVirtFlyDrawObj().wrap_DoPaintObject(); + + // call parent + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SwVirtFlyDrawObjPrimitive, PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////////////// +// AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed +// since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj. +// For paint, that offset is used by setting at the OutputDevice; for primitives this is +// not possible since we have no OutputDevice, but define the geometry itself. + +namespace sdr +{ + namespace contact + { + class VCOfSwVirtFlyDrawObj : public ViewContactOfVirtObj + { + protected: + // This method is responsible for creating the graphical visualisation data + // ONLY based on model data + virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const; + + public: + // basic constructor, used from SdrObject. + VCOfSwVirtFlyDrawObj(SwVirtFlyDrawObj& rObj) + : ViewContactOfVirtObj(rObj) + { + } + virtual ~VCOfSwVirtFlyDrawObj(); + + // access to SwVirtFlyDrawObj + SwVirtFlyDrawObj& GetSwVirtFlyDrawObj() const + { + return (SwVirtFlyDrawObj&)mrObject; + } + }; + } // end of namespace contact +} // end of namespace sdr + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence VCOfSwVirtFlyDrawObj::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrObject& rReferencedObject = GetSwVirtFlyDrawObj().GetReferencedObj(); + + if(rReferencedObject.ISA(SwFlyDrawObj)) + { + // create an own specialized primitive which is used as repaint callpoint and HitTest + // for HitTest processor (see primitive implementation above) + const basegfx::B2DRange aOuterRange(GetSwVirtFlyDrawObj().getOuterBound()); + + if(!aOuterRange.isEmpty()) + { + const drawinglayer::primitive2d::Primitive2DReference xPrimitive( + new drawinglayer::primitive2d::SwVirtFlyDrawObjPrimitive( + GetSwVirtFlyDrawObj(), + aOuterRange)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPrimitive, 1); + } + } + + return xRetval; + } + + VCOfSwVirtFlyDrawObj::~VCOfSwVirtFlyDrawObj() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////////////// + +basegfx::B2DRange SwVirtFlyDrawObj::getOuterBound() const +{ + basegfx::B2DRange aOuterRange; + const SdrObject& rReferencedObject = GetReferencedObj(); + + if(rReferencedObject.ISA(SwFlyDrawObj)) + { + const SwFlyFrm* pFlyFrame = GetFlyFrm(); + + if(pFlyFrame) + { + const Rectangle aOuterRectangle(pFlyFrame->Frm().Pos(), pFlyFrame->Frm().SSize()); + + if(!aOuterRectangle.IsEmpty() + && RECT_EMPTY != aOuterRectangle.Right() + && RECT_EMPTY != aOuterRectangle.Bottom()) + { + aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Left(), aOuterRectangle.Top())); + aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Right(), aOuterRectangle.Bottom())); + } + } + } + + return aOuterRange; +} + +basegfx::B2DRange SwVirtFlyDrawObj::getInnerBound() const +{ + basegfx::B2DRange aInnerRange; + const SdrObject& rReferencedObject = GetReferencedObj(); + + if(rReferencedObject.ISA(SwFlyDrawObj)) + { + const SwFlyFrm* pFlyFrame = GetFlyFrm(); + + if(pFlyFrame) + { + const Rectangle aInnerRectangle(pFlyFrame->Frm().Pos() + pFlyFrame->Prt().Pos(), pFlyFrame->Prt().SSize()); + + if(!aInnerRectangle.IsEmpty() + && RECT_EMPTY != aInnerRectangle.Right() + && RECT_EMPTY != aInnerRectangle.Bottom()) + { + aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Left(), aInnerRectangle.Top())); + aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Right(), aInnerRectangle.Bottom())); + } + } + } + + return aInnerRange; +} + +sdr::contact::ViewContact* SwVirtFlyDrawObj::CreateObjectSpecificViewContact() +{ + // need an own ViewContact (VC) to allow creation of a specialized primitive + // for being able to visualize the FlyFrames in primitive renderers + return new sdr::contact::VCOfSwVirtFlyDrawObj(*this); +} + +SwVirtFlyDrawObj::SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrm* pFly) : + SdrVirtObj( rNew ), + pFlyFrm( pFly ) +{ + //#110094#-1 + // bNotPersistent = bNeedColorRestore = bWriterFlyFrame = TRUE; + const SvxProtectItem &rP = pFlyFrm->GetFmt()->GetProtect(); + bMovProt = rP.IsPosProtected(); + bSizProt = rP.IsSizeProtected(); +} + + +__EXPORT SwVirtFlyDrawObj::~SwVirtFlyDrawObj() +{ + if ( GetPage() ) //Der SdrPage die Verantwortung entziehen. + GetPage()->RemoveObject( GetOrdNum() ); +} + +/************************************************************************* +|* +|* SwVirtFlyDrawObj::GetFmt() +|* +|* Ersterstellung MA 08. Dec. 94 +|* Letzte Aenderung MA 08. Dec. 94 +|* +*************************************************************************/ + +const SwFrmFmt *SwVirtFlyDrawObj::GetFmt() const +{ + return GetFlyFrm()->GetFmt(); +} + + +SwFrmFmt *SwVirtFlyDrawObj::GetFmt() +{ + return GetFlyFrm()->GetFmt(); +} + +/************************************************************************* +|* +|* SwVirtFlyDrawObj::Paint() +|* +|* Ersterstellung MA 20. Dec. 94 +|* Letzte Aenderung MA 18. Dec. 95 +|* +*************************************************************************/ + +void SwVirtFlyDrawObj::wrap_DoPaintObject() const +{ + ViewShell* pShell = pFlyFrm->GetShell(); + + // Only paint when we have a current shell and a DrawingLayer paint is in progress. + // This avcoids evtl. problems with renderers which do processing stuff, + // but no paints. IsPaintInProgress() depends on SW repaint, so, as long + // as SW paints self and calls DrawLayer() for Heaven and Hell, this will + // be correct + if(pShell && pShell->IsDrawingLayerPaintInProgress()) + { + sal_Bool bDrawObject(sal_True); + + if(!SwFlyFrm::IsPaint((SdrObject*)this, pShell)) + { + bDrawObject = sal_False; + } + + if(bDrawObject) + { + if(!pFlyFrm->IsFlyInCntFrm()) + { + // it is also necessary to restore the VCL MapMode from ViewInformation since e.g. + // the VCL PixelRenderer resets it at the used OutputDevice. Unfortunately, this + // excludes shears and rotates which are not expressable in MapMode. + OutputDevice* pOut = pShell->GetOut(); + + pOut->Push(PUSH_MAPMODE); + pOut->SetMapMode(pShell->getPrePostMapMode()); + + // paint the FlyFrame (use standard VCL-Paint) + pFlyFrm->Paint(GetFlyFrm()->Frm()); + + pOut->Pop(); + } + } + } +} + +/************************************************************************* +|* +|* SwVirtFlyDrawObj::TakeObjInfo() +|* +|* Ersterstellung MA 03. May. 95 +|* Letzte Aenderung MA 03. May. 95 +|* +*************************************************************************/ + +void __EXPORT SwVirtFlyDrawObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const +{ + rInfo.bSelectAllowed = rInfo.bMoveAllowed = + rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = TRUE; + + rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed = + rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed = + rInfo.bMirror90Allowed = rInfo.bShearAllowed = + rInfo.bCanConvToPath = rInfo.bCanConvToPoly = + rInfo.bCanConvToPathLineToArea = rInfo.bCanConvToPolyLineToArea = FALSE; +} + + +/************************************************************************* +|* +|* SwVirtFlyDrawObj::Groessenermittlung +|* +|* Ersterstellung MA 12. Jan. 95 +|* Letzte Aenderung MA 10. Nov. 95 +|* +*************************************************************************/ + +void SwVirtFlyDrawObj::SetRect() const +{ + if ( GetFlyFrm()->Frm().HasArea() ) + ((SwVirtFlyDrawObj*)this)->aOutRect = GetFlyFrm()->Frm().SVRect(); + else + ((SwVirtFlyDrawObj*)this)->aOutRect = Rectangle(); +} + + +const Rectangle& __EXPORT SwVirtFlyDrawObj::GetCurrentBoundRect() const +{ + SetRect(); + return aOutRect; +} + +const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLastBoundRect() const +{ + return GetCurrentBoundRect(); +} + + +void __EXPORT SwVirtFlyDrawObj::RecalcBoundRect() +{ + SetRect(); +} + + +void __EXPORT SwVirtFlyDrawObj::RecalcSnapRect() +{ + SetRect(); +} + + +const Rectangle& __EXPORT SwVirtFlyDrawObj::GetSnapRect() const +{ + SetRect(); + return aOutRect; +} + + +void __EXPORT SwVirtFlyDrawObj::SetSnapRect(const Rectangle& ) +{ + Rectangle aTmp( GetLastBoundRect() ); + SetRect(); + SetChanged(); + BroadcastObjectChange(); + if (pUserCall!=NULL) + pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp); +} + + +void __EXPORT SwVirtFlyDrawObj::NbcSetSnapRect(const Rectangle& ) +{ + SetRect(); +} + + +const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLogicRect() const +{ + SetRect(); + return aOutRect; +} + + +void __EXPORT SwVirtFlyDrawObj::SetLogicRect(const Rectangle& ) +{ + Rectangle aTmp( GetLastBoundRect() ); + SetRect(); + SetChanged(); + BroadcastObjectChange(); + if (pUserCall!=NULL) + pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp); +} + + +void __EXPORT SwVirtFlyDrawObj::NbcSetLogicRect(const Rectangle& ) +{ + SetRect(); +} + + +::basegfx::B2DPolyPolygon SwVirtFlyDrawObj::TakeXorPoly() const +{ + const Rectangle aSourceRectangle(GetFlyFrm()->Frm().SVRect()); + const ::basegfx::B2DRange aSourceRange(aSourceRectangle.Left(), aSourceRectangle.Top(), aSourceRectangle.Right(), aSourceRectangle.Bottom()); + ::basegfx::B2DPolyPolygon aRetval; + + aRetval.append(::basegfx::tools::createPolygonFromRect(aSourceRange)); + + return aRetval; +} + +/************************************************************************* +|* +|* SwVirtFlyDrawObj::Move() und Resize() +|* +|* Ersterstellung MA 12. Jan. 95 +|* Letzte Aenderung MA 26. Jul. 96 +|* +*************************************************************************/ + +void __EXPORT SwVirtFlyDrawObj::NbcMove(const Size& rSiz) +{ + MoveRect( aOutRect, rSiz ); + const Point aOldPos( GetFlyFrm()->Frm().Pos() ); + const Point aNewPos( aOutRect.TopLeft() ); + const SwRect aFlyRect( aOutRect ); + + //Wenn der Fly eine automatische Ausrichtung hat (rechts oder oben), + //so soll die Automatik erhalten bleiben + SwFrmFmt *pFmt = GetFlyFrm()->GetFmt(); + const sal_Int16 eHori = pFmt->GetHoriOrient().GetHoriOrient(); + const sal_Int16 eVert = pFmt->GetVertOrient().GetVertOrient(); + const sal_Int16 eRelHori = pFmt->GetHoriOrient().GetRelationOrient(); + const sal_Int16 eRelVert = pFmt->GetVertOrient().GetRelationOrient(); + //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein + //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly selbst + //berechnet und gesetzt. + if( GetFlyFrm()->IsFlyAtCntFrm() ) + ((SwFlyAtCntFrm*)GetFlyFrm())->SetAbsPos( aNewPos ); + else + { + const SwFrmFmt *pTmpFmt = GetFmt(); + const SwFmtVertOrient &rVert = pTmpFmt->GetVertOrient(); + const SwFmtHoriOrient &rHori = pTmpFmt->GetHoriOrient(); + long lXDiff = aNewPos.X() - aOldPos.X(); + if( rHori.IsPosToggle() && text::HoriOrientation::NONE == eHori && + !GetFlyFrm()->FindPageFrm()->OnRightPage() ) + lXDiff = -lXDiff; + + if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() && + text::HoriOrientation::NONE == eHori ) + lXDiff = -lXDiff; + + long lYDiff = aNewPos.Y() - aOldPos.Y(); + if( GetFlyFrm()->GetAnchorFrm()->IsVertical() ) + { + lXDiff -= rVert.GetPos(); + lYDiff += rHori.GetPos(); + } + else + { + lXDiff += rHori.GetPos(); + lYDiff += rVert.GetPos(); + } + + if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() && + text::HoriOrientation::NONE != eHori ) + lXDiff = GetFlyFrm()->GetAnchorFrm()->Frm().Width() - + aFlyRect.Width() - lXDiff; + + const Point aTmp( lXDiff, lYDiff ); + GetFlyFrm()->ChgRelPos( aTmp ); + } + + SwAttrSet aSet( pFmt->GetDoc()->GetAttrPool(), + RES_VERT_ORIENT, RES_HORI_ORIENT ); + SwFmtHoriOrient aHori( pFmt->GetHoriOrient() ); + SwFmtVertOrient aVert( pFmt->GetVertOrient() ); + BOOL bPut = FALSE; + + if( !GetFlyFrm()->IsFlyLayFrm() && + ::GetHtmlMode(pFmt->GetDoc()->GetDocShell()) ) + { + //Im HTML-Modus sind nur automatische Ausrichtungen erlaubt. + //Einzig einen Snap auf Links/Rechts bzw. Linker-/Rechter-Rand koennen + //wir versuchen. + const SwFrm* pAnch = GetFlyFrm()->GetAnchorFrm(); + BOOL bNextLine = FALSE; + + if( !GetFlyFrm()->IsAutoPos() || text::RelOrientation::PAGE_FRAME != aHori.GetRelationOrient() ) + { + if( text::RelOrientation::CHAR == eRelHori ) + { + aHori.SetHoriOrient( text::HoriOrientation::LEFT ); + aHori.SetRelationOrient( text::RelOrientation::CHAR ); + } + else + { + bNextLine = TRUE; + //Horizontale Ausrichtung: + const BOOL bLeftFrm = + aFlyRect.Left() < pAnch->Frm().Left() + pAnch->Prt().Left(), + bLeftPrt = aFlyRect.Left() + aFlyRect.Width() < + pAnch->Frm().Left() + pAnch->Prt().Width()/2; + if ( bLeftFrm || bLeftPrt ) + { + aHori.SetHoriOrient( text::HoriOrientation::LEFT ); + aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); + } + else + { + const BOOL bRightFrm = aFlyRect.Left() > + pAnch->Frm().Left() + pAnch->Prt().Width(); + aHori.SetHoriOrient( text::HoriOrientation::RIGHT ); + aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA ); + } + } + aSet.Put( aHori ); + } + //Vertikale Ausrichtung bleibt grundsaetzlich schlicht erhalten, + //nur bei nicht automatischer Ausrichtung wird umgeschaltet. + BOOL bRelChar = text::RelOrientation::CHAR == eRelVert; + aVert.SetVertOrient( eVert != text::VertOrientation::NONE ? eVert : + GetFlyFrm()->IsFlyInCntFrm() ? text::VertOrientation::CHAR_CENTER : + bRelChar && bNextLine ? text::VertOrientation::CHAR_TOP : text::VertOrientation::TOP ); + if( bRelChar ) + aVert.SetRelationOrient( text::RelOrientation::CHAR ); + else + aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA ); + aSet.Put( aVert ); + bPut = TRUE; + } + + //Automatische Ausrichtungen wollen wir moeglichst nicht verlieren. + if ( !bPut && bInResize ) + { + if ( text::HoriOrientation::NONE != eHori ) + { + aHori.SetHoriOrient( eHori ); + aHori.SetRelationOrient( eRelHori ); + aSet.Put( aHori ); + bPut = TRUE; + } + if ( text::VertOrientation::NONE != eVert ) + { + aVert.SetVertOrient( eVert ); + aVert.SetRelationOrient( eRelVert ); + aSet.Put( aVert ); + bPut = TRUE; + } + } + if ( bPut ) + pFmt->SetFmtAttr( aSet ); +} + + +void __EXPORT SwVirtFlyDrawObj::NbcResize(const Point& rRef, + const Fraction& xFact, const Fraction& yFact) +{ + ResizeRect( aOutRect, rRef, xFact, yFact ); + + const SwFrm* pTmpFrm = GetFlyFrm()->GetAnchorFrm(); + if( !pTmpFrm ) + pTmpFrm = GetFlyFrm(); + const bool bVertX = pTmpFrm->IsVertical(); + + const sal_Bool bRTL = pTmpFrm->IsRightToLeft(); + + const Point aNewPos( bVertX || bRTL ? + aOutRect.Right() + 1 : + aOutRect.Left(), + aOutRect.Top() ); + + Size aSz( aOutRect.Right() - aOutRect.Left() + 1, + aOutRect.Bottom()- aOutRect.Top() + 1 ); + if( aSz != GetFlyFrm()->Frm().SSize() ) + { + //Die Breite darf bei Spalten nicht zu schmal werden + if ( GetFlyFrm()->Lower() && GetFlyFrm()->Lower()->IsColumnFrm() ) + { + SwBorderAttrAccess aAccess( SwFrm::GetCache(), GetFlyFrm() ); + const SwBorderAttrs &rAttrs = *aAccess.Get(); + long nMin = rAttrs.CalcLeftLine()+rAttrs.CalcRightLine(); + const SwFmtCol& rCol = rAttrs.GetAttrSet().GetCol(); + if ( rCol.GetColumns().Count() > 1 ) + { + for ( USHORT i = 0; i < rCol.GetColumns().Count(); ++i ) + { + nMin += rCol.GetColumns()[i]->GetLeft() + + rCol.GetColumns()[i]->GetRight() + + MINFLY; + } + nMin -= MINFLY; + } + aSz.Width() = Max( aSz.Width(), nMin ); + } + + SwFrmFmt *pFmt = GetFmt(); + const SwFmtFrmSize aOldFrmSz( pFmt->GetFrmSize() ); + GetFlyFrm()->ChgSize( aSz ); + SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() ); + if ( aFrmSz.GetWidthPercent() || aFrmSz.GetHeightPercent() ) + { + long nRelWidth, nRelHeight; + const SwFrm *pRel = GetFlyFrm()->IsFlyLayFrm() ? + GetFlyFrm()->GetAnchorFrm() : + GetFlyFrm()->GetAnchorFrm()->GetUpper(); + const ViewShell *pSh = GetFlyFrm()->GetShell(); + if ( pSh && pRel->IsBodyFrm() && + pFmt->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) && + pSh->VisArea().HasArea() ) + { + nRelWidth = pSh->GetBrowseWidth(); + nRelHeight = pSh->VisArea().Height(); + const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); + nRelHeight -= 2*aBorder.Height(); + } + else + { + nRelWidth = pRel->Prt().Width(); + nRelHeight = pRel->Prt().Height(); + } + if ( aFrmSz.GetWidthPercent() && aFrmSz.GetWidthPercent() != 0xFF && + aOldFrmSz.GetWidth() != aFrmSz.GetWidth() ) + aFrmSz.SetWidthPercent( BYTE(aSz.Width() * 100L / nRelWidth + 0.5) ); + if ( aFrmSz.GetHeightPercent() && aFrmSz.GetHeightPercent() != 0xFF && + aOldFrmSz.GetHeight() != aFrmSz.GetHeight() ) + aFrmSz.SetHeightPercent( BYTE(aSz.Height() * 100L / nRelHeight + 0.5) ); + pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt ); + } + } + + //Position kann auch veraendert sein! + const Point aOldPos( bVertX || bRTL ? + GetFlyFrm()->Frm().TopRight() : + GetFlyFrm()->Frm().Pos() ); + + if ( aNewPos != aOldPos ) + { + //Kann sich durch das ChgSize veraendert haben! + if( bVertX || bRTL ) + { + if( aOutRect.TopRight() != aNewPos ) + { + SwTwips nDeltaX = aNewPos.X() - aOutRect.Right(); + SwTwips nDeltaY = aNewPos.Y() - aOutRect.Top(); + MoveRect( aOutRect, Size( nDeltaX, nDeltaY ) ); + } + } + else if ( aOutRect.TopLeft() != aNewPos ) + aOutRect.SetPos( aNewPos ); + bInResize = TRUE; + NbcMove( Size( 0, 0 ) ); + bInResize = FALSE; + } +} + + +void __EXPORT SwVirtFlyDrawObj::Move(const Size& rSiz) +{ + NbcMove( rSiz ); + SetChanged(); + GetFmt()->GetDoc()->SetNoDrawUndoObj( TRUE ); +} + + +void __EXPORT SwVirtFlyDrawObj::Resize(const Point& rRef, + const Fraction& xFact, const Fraction& yFact) +{ + NbcResize( rRef, xFact, yFact ); + SetChanged(); + GetFmt()->GetDoc()->SetNoDrawUndoObj( TRUE ); +} + + +Pointer __EXPORT SwVirtFlyDrawObj::GetMacroPointer( + const SdrObjMacroHitRec& ) const +{ + return Pointer( POINTER_REFHAND ); +} + + +FASTBOOL __EXPORT SwVirtFlyDrawObj::HasMacro() const +{ + const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL(); + return rURL.GetMap() || rURL.GetURL().Len(); +} + + +SdrObject* SwVirtFlyDrawObj::CheckMacroHit( const SdrObjMacroHitRec& rRec ) const +{ + const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL(); + if( rURL.GetMap() || rURL.GetURL().Len() ) + { + SwRect aRect; + if ( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() ) + { + aRect = pFlyFrm->Prt(); + aRect += pFlyFrm->Frm().Pos(); + } + else + aRect = pFlyFrm->Frm(); + + if( aRect.IsInside( rRec.aPos ) ) + { + SwRect aActRect( aRect ); + Size aActSz( aRect.SSize() ); + aRect.Pos().X() += rRec.nTol; + aRect.Pos().Y() += rRec.nTol; + aRect.SSize().Height()-= 2 * rRec.nTol; + aRect.SSize().Width() -= 2 * rRec.nTol; + + if( aRect.IsInside( rRec.aPos ) ) + { + if( !rURL.GetMap() || + pFlyFrm->GetFmt()->GetIMapObject( rRec.aPos, pFlyFrm )) + return (SdrObject*)this; + + return 0; + } + } + } + return SdrObject::CheckMacroHit( rRec ); +} + +bool SwVirtFlyDrawObj::supportsFullDrag() const +{ + // call parent + return SdrVirtObj::supportsFullDrag(); +} + +SdrObject* SwVirtFlyDrawObj::getFullDragClone() const +{ + // call parent + return SdrVirtObj::getFullDragClone(); +} + +// eof |