/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include "hintids.hxx" #include #include #include #include #include #include #include #include #include "viewsh.hxx" #include "viewimp.hxx" #include "cntfrm.hxx" #include "frmatr.hxx" #include "doc.hxx" #include #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" #include "rootfrm.hxx" using namespace ::com::sun::star; // --> OD 2004-11-22 #117958# #include // <-- #include #include #include // AW: For VCOfDrawVirtObj and stuff #include #include #include #include using namespace ::com::sun::star; static sal_Bool bInResize = sal_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 |* *************************************************************************/ sal_uInt32 __EXPORT SwFlyDrawObj::GetObjInventor() const { return SWGInventor; } sal_uInt16 __EXPORT SwFlyDrawObj::GetObjIdentifier() const { return SwFlyDrawObjIdentifier; } sal_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 = sal_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 |* *************************************************************************/ // --> OD #i102707# namespace { class RestoreMapMode { public: explicit RestoreMapMode( ViewShell* pViewShell ) : mbMapModeRestored( false ) , mpOutDev( pViewShell->GetOut() ) { if ( pViewShell->getPrePostMapMode() != mpOutDev->GetMapMode() ) { mpOutDev->Push(PUSH_MAPMODE); GDIMetaFile* pMetaFile = mpOutDev->GetConnectMetaFile(); if ( pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause() ) { ASSERT( false, "MapMode restoration during meta file creation is somehow suspect - using , but not sure, if correct." ) mpOutDev->SetRelativeMapMode( pViewShell->getPrePostMapMode() ); } else { mpOutDev->SetMapMode( pViewShell->getPrePostMapMode() ); } mbMapModeRestored = true; } }; ~RestoreMapMode() { if ( mbMapModeRestored ) { mpOutDev->Pop(); } }; private: bool mbMapModeRestored; OutputDevice* mpOutDev; }; } // <-- void SwVirtFlyDrawObj::wrap_DoPaintObject() const { ViewShell* pShell = pFlyFrm->getRootFrm()->GetCurrShell(); // 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. // OD #i102707# // new helper class to restore MapMode - restoration, only if // needed and consideration of paint for meta file creation . RestoreMapMode aRestoreMapModeIfNeeded( pShell ); // paint the FlyFrame (use standard VCL-Paint) pFlyFrm->Paint( GetFlyFrm()->Frm() ); } } } } /************************************************************************* |* |* 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 = sal_True; rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed = rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed = rInfo.bMirror90Allowed = rInfo.bShearAllowed = rInfo.bCanConvToPath = rInfo.bCanConvToPoly = rInfo.bCanConvToPathLineToArea = rInfo.bCanConvToPolyLineToArea = sal_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(); //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin if ( GetFlyFrm()->GetAnchorFrm()->IsVertLR() ) { lXDiff += rVert.GetPos(); lXDiff = -lXDiff; } else { 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() ); sal_Bool bPut = sal_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(); sal_Bool bNextLine = sal_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 = sal_True; //Horizontale Ausrichtung: const sal_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 sal_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. sal_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 = sal_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 = sal_True; } if ( text::VertOrientation::NONE != eVert ) { aVert.SetVertOrient( eVert ); aVert.SetRelationOrient( eRelVert ); aSet.Put( aVert ); bPut = sal_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(); //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin const bool bVertL2RX = pTmpFrm->IsVertLR(); const Point aNewPos( ( bVertX && !bVertL2RX ) || 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 ( sal_uInt16 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()->getRootFrm()->GetCurrShell(); if ( pSh && pRel->IsBodyFrm() && pSh->GetViewOptions()->getBrowseMode() && 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( sal_uInt8(aSz.Width() * 100L / nRelWidth + 0.5) ); if ( aFrmSz.GetHeightPercent() && aFrmSz.GetHeightPercent() != 0xFF && aOldFrmSz.GetHeight() != aFrmSz.GetHeight() ) aFrmSz.SetHeightPercent( sal_uInt8(aSz.Height() * 100L / nRelHeight + 0.5) ); pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt ); } } //Position kann auch veraendert sein! const Point aOldPos( ( bVertX && !bVertL2RX ) || bRTL ? GetFlyFrm()->Frm().TopRight() : GetFlyFrm()->Frm().Pos() ); if ( aNewPos != aOldPos ) { //Kann sich durch das ChgSize veraendert haben! if( bVertX || bRTL ) { if( aOutRect.TopRight() != aNewPos ) { //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin SwTwips nDeltaX; if ( bVertL2RX ) nDeltaX = aNewPos.X() - aOutRect.Left(); else 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 = sal_True; NbcMove( Size( 0, 0 ) ); bInResize = sal_False; } } void __EXPORT SwVirtFlyDrawObj::Move(const Size& rSiz) { NbcMove( rSiz ); SetChanged(); GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); } void __EXPORT SwVirtFlyDrawObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) { NbcResize( rRef, xFact, yFact ); SetChanged(); GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false); } 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