/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include #include #ifndef _MATH_H #define _MATH_H #endif #include #include #include #include #include // for SID_ATTR_TRANSFORM_... #include // for Get/SetGeoAttr #include "svx/svditext.hxx" #include "svx/svditer.hxx" #include #include #include #include #include // for MergeNotPersistAttr #include // for MergeNotPersistAttr #include // for SearchOutlinerItems #include // for Crook #include "svx/svdstr.hrc" // names taken from the resource #include "svx/svdglob.hxx" // StringCache #include #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // EditView //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrEditView::SetMarkedObjRect(const Rectangle& rRect, sal_Bool bCopy) { DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() with an empty Rect does not make sense."); if (rRect.IsEmpty()) return; sal_uIntPtr nAnz=GetMarkedObjectCount(); if (nAnz==0) return; Rectangle aR0(GetMarkedObjRect()); DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() is empty."); if (aR0.IsEmpty()) return; long x0=aR0.Left(); long y0=aR0.Top(); long w0=aR0.Right()-x0; long h0=aR0.Bottom()-y0; long x1=rRect.Left(); long y1=rRect.Top(); long w1=rRect.Right()-x1; long h1=rRect.Bottom()-y1; XubString aStr; ImpTakeDescriptionStr(STR_EditPosSize,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); const bool bUndo = IsUndoEnabled(); if( bUndo ) BegUndo(aStr); if (bCopy) CopyMarkedObj(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); Rectangle aR1(pO->GetSnapRect()); if (!aR1.IsEmpty()) { if (aR1==aR0) { aR1=rRect; } else { // transform aR1 to aR0 after rRect aR1.Move(-x0,-y0); BigInt l(aR1.Left()); BigInt r(aR1.Right()); BigInt t(aR1.Top()); BigInt b(aR1.Bottom()); if (w0!=0) { l*=w1; l/=w0; r*=w1; r/=w0; } else { l=0; r=w1; } if (h0!=0) { t*=h1; t/=h0; b*=h1; b/=h0; } else { t=0; b=h1; } aR1.Left ()=long(l); aR1.Right ()=long(r); aR1.Top ()=long(t); aR1.Bottom()=long(b); aR1.Move(x1,y1); } pO->SetSnapRect(aR1); } else { OSL_FAIL("SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect"); } } if( bUndo ) EndUndo(); } std::vector< SdrUndoAction* > SdrEditView::CreateConnectorUndo( SdrObject& rO ) { std::vector< SdrUndoAction* > vUndoActions; if ( rO.GetBroadcaster() ) { const SdrPage* pPage = rO.GetPage(); if ( pPage ) { SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS ); while( aIter.IsMore() ) { SdrObject* pPartObj = aIter.Next(); if ( pPartObj->ISA( SdrEdgeObj ) ) { if ( ( pPartObj->GetConnectedNode( sal_False ) == &rO ) || ( pPartObj->GetConnectedNode( sal_True ) == &rO ) ) { vUndoActions.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj ) ); } } } } } return vUndoActions; } void SdrEditView::AddUndoActions( std::vector< SdrUndoAction* >& rUndoActions ) { std::vector< SdrUndoAction* >::iterator aUndoActionIter( rUndoActions.begin() ); while( aUndoActionIter != rUndoActions.end() ) AddUndo( *aUndoActionIter++ ); } void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr(ImpGetResStr(STR_EditMove)); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); // meeds its own UndoGroup because of its parameters BegUndo(aStr,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE); } if (bCopy) CopyMarkedObj(); sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) { std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); AddUndoActions( vConnectorUndoActions ); AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,rSiz)); } pO->Move(rSiz); } if( bUndo ) EndUndo(); } void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; ImpTakeDescriptionStr(STR_EditResize,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr); } if (bCopy) CopyMarkedObj(); sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) { std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); AddUndoActions( vConnectorUndoActions ); AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); } pO->Resize(rRef,xFact,yFact); } if( bUndo ) EndUndo(); } long SdrEditView::GetMarkedObjRotate() const { sal_Bool b1st=sal_True; sal_Bool bOk=sal_True; long nWink=0; sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); long nWink2=pO->GetRotateAngle(); if (b1st) nWink=nWink2; else if (nWink2!=nWink) bOk=sal_False; b1st=sal_False; } if (!bOk) nWink=0; return nWink; } void SdrEditView::RotateMarkedObj(const Point& rRef, long nWink, bool bCopy) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; ImpTakeDescriptionStr(STR_EditRotate,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr); } if (bCopy) CopyMarkedObj(); double nSin=sin(nWink*nPi180); double nCos=cos(nWink*nPi180); const sal_uInt32 nMarkAnz(GetMarkedObjectCount()); if(nMarkAnz) { std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; for(sal_uInt32 nm(0); nm < nMarkAnz; nm++) { SdrMark* pM = GetSdrMarkByIndex(nm); SdrObject* pO = pM->GetMarkedSdrObj(); if( bUndo ) { // extra undo actions for changed connector which now may hold its laid out path (SJ) std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); AddUndoActions( vConnectorUndoActions ); AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); } // set up a scene updater if object is a 3d object if(dynamic_cast< E3dObject* >(pO)) { aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO)); } pO->Rotate(rRef,nWink,nSin,nCos); } // fire scene updaters while(!aUpdaters.empty()) { delete aUpdaters.back(); aUpdaters.pop_back(); } } if( bUndo ) EndUndo(); } void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool bCopy) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; Point aDif(rRef2-rRef1); if (aDif.X()==0) ImpTakeDescriptionStr(STR_EditMirrorHori,aStr); else if (aDif.Y()==0) ImpTakeDescriptionStr(STR_EditMirrorVert,aStr); else if (Abs(aDif.X())==Abs(aDif.Y())) ImpTakeDescriptionStr(STR_EditMirrorDiag,aStr); else ImpTakeDescriptionStr(STR_EditMirrorFree,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr); } if (bCopy) CopyMarkedObj(); const sal_uInt32 nMarkAnz(GetMarkedObjectCount()); if(nMarkAnz) { std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; for(sal_uInt32 nm(0); nm < nMarkAnz; nm++) { SdrMark* pM = GetSdrMarkByIndex(nm); SdrObject* pO = pM->GetMarkedSdrObj(); if( bUndo ) { // extra undo actions for changed connector which now may hold its laid out path (SJ) std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); AddUndoActions( vConnectorUndoActions ); AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); } // set up a scene updater if object is a 3d object if(dynamic_cast< E3dObject* >(pO)) { aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO)); } pO->Mirror(rRef1,rRef2); } // fire scene updaters while(!aUpdaters.empty()) { delete aUpdaters.back(); aUpdaters.pop_back(); } } if( bUndo ) EndUndo(); } void SdrEditView::MirrorMarkedObjHorizontal(sal_Bool bCopy) { Point aCenter(GetMarkedObjRect().Center()); Point aPt2(aCenter); aPt2.Y()++; MirrorMarkedObj(aCenter,aPt2,bCopy); } void SdrEditView::MirrorMarkedObjVertical(sal_Bool bCopy) { Point aCenter(GetMarkedObjRect().Center()); Point aPt2(aCenter); aPt2.X()++; MirrorMarkedObj(aCenter,aPt2,bCopy); } long SdrEditView::GetMarkedObjShear() const { sal_Bool b1st=sal_True; sal_Bool bOk=sal_True; long nWink=0; sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); long nWink2=pO->GetShearAngle(); if (b1st) nWink=nWink2; else if (nWink2!=nWink) bOk=sal_False; b1st=sal_False; } if (nWink>SDRMAXSHEAR) nWink=SDRMAXSHEAR; if (nWink<-SDRMAXSHEAR) nWink=-SDRMAXSHEAR; if (!bOk) nWink=0; return nWink; } void SdrEditView::ShearMarkedObj(const Point& rRef, long nWink, bool bVShear, bool bCopy) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; ImpTakeDescriptionStr(STR_EditShear,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr); } if (bCopy) CopyMarkedObj(); double nTan=tan(nWink*nPi180); sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) { std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); AddUndoActions( vConnectorUndoActions ); AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); } pO->Shear(rRef,nWink,nTan,bVShear); } if( bUndo ) EndUndo(); } void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRad, SdrCrookMode eMode, sal_Bool bVertical, sal_Bool bNoContortion, sal_Bool bRotate, const Rectangle& rMarkRect) { SdrPathObj* pPath=PTR_CAST(SdrPathObj,pO); sal_Bool bDone = sal_False; if(pPath!=NULL && !bNoContortion) { XPolyPolygon aXPP(pPath->GetPathPoly()); switch (eMode) { case SDRCROOK_ROTATE : CrookRotatePoly (aXPP,rRef,rRad,bVertical); break; case SDRCROOK_SLANT : CrookSlantPoly (aXPP,rRef,rRad,bVertical); break; case SDRCROOK_STRETCH: CrookStretchPoly(aXPP,rRef,rRad,bVertical,rMarkRect); break; } // switch pPath->SetPathPoly(aXPP.getB2DPolyPolygon()); bDone = sal_True; } if(!bDone && !pPath && pO->IsPolyObj() && 0L != pO->GetPointCount()) { // for PolyObj's, but NOT for SdrPathObj's, e.g. the measurement object sal_uInt32 nPtAnz(pO->GetPointCount()); XPolygon aXP((sal_uInt16)nPtAnz); sal_uInt32 nPtNum; for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) { Point aPt(pO->GetPoint(nPtNum)); aXP[(sal_uInt16)nPtNum]=aPt; } switch (eMode) { case SDRCROOK_ROTATE : CrookRotatePoly (aXP,rRef,rRad,bVertical); break; case SDRCROOK_SLANT : CrookSlantPoly (aXP,rRef,rRad,bVertical); break; case SDRCROOK_STRETCH: CrookStretchPoly(aXP,rRef,rRad,bVertical,rMarkRect); break; } for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) { // broadcasting could be optimized here, but for the // current two points of the measurement object, it's fine pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum); } bDone = sal_True; } if(!bDone) { // for all others or if bNoContortion Point aCtr0(pO->GetSnapRect().Center()); Point aCtr1(aCtr0); sal_Bool bRotOk(sal_False); double nSin(0.0), nCos(1.0); double nWink(0.0); if(0 != rRad.X() && 0 != rRad.Y()) { bRotOk = bRotate; switch (eMode) { case SDRCROOK_ROTATE : nWink=CrookRotateXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); bRotOk=bRotate; break; case SDRCROOK_SLANT : nWink=CrookSlantXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); break; case SDRCROOK_STRETCH: nWink=CrookStretchXPoint(aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical,rMarkRect); break; } } aCtr1 -= aCtr0; if(bRotOk) pO->Rotate(aCtr0, Round(nWink/nPi180), nSin, nCos); pO->Move(Size(aCtr1.X(),aCtr1.Y())); } } void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookMode eMode, bool bVertical, bool bNoContortion, bool bCopy) { Rectangle aMarkRect(GetMarkedObjRect()); const bool bUndo = IsUndoEnabled(); bool bRotate=bNoContortion && eMode==SDRCROOK_ROTATE && IsRotateAllowed(sal_False); if( bUndo ) { XubString aStr; ImpTakeDescriptionStr(bNoContortion?STR_EditCrook:STR_EditCrookContortion,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr); } if (bCopy) CopyMarkedObj(); sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); const SdrObjList* pOL=pO->GetSubList(); if (bNoContortion || pOL==NULL) { ImpCrookObj(pO,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect); } else { SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS); while (aIter.IsMore()) { SdrObject* pO1=aIter.Next(); ImpCrookObj(pO1,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect); } } } if( bUndo ) EndUndo(); } void SdrEditView::ImpDistortObj(SdrObject* pO, const Rectangle& rRef, const XPolygon& rDistortedRect, sal_Bool bNoContortion) { SdrPathObj* pPath = PTR_CAST(SdrPathObj, pO); if(!bNoContortion && pPath) { XPolyPolygon aXPP(pPath->GetPathPoly()); aXPP.Distort(rRef, rDistortedRect); pPath->SetPathPoly(aXPP.getB2DPolyPolygon()); } else if(pO->IsPolyObj()) { // e. g. for the measurement object sal_uInt32 nPtAnz(pO->GetPointCount()); XPolygon aXP((sal_uInt16)nPtAnz); sal_uInt32 nPtNum; for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) { Point aPt(pO->GetPoint(nPtNum)); aXP[(sal_uInt16)nPtNum]=aPt; } aXP.Distort(rRef, rDistortedRect); for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++) { // broadcasting could be optimized here, but for the // current two points of the measurement object it's fine pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum); } } } void SdrEditView::DistortMarkedObj(const Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion, bool bCopy) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; ImpTakeDescriptionStr(STR_EditDistort,aStr); if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy); BegUndo(aStr); } if (bCopy) CopyMarkedObj(); sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); Rectangle aRefRect(rRef); XPolygon aRefPoly(rDistortedRect); const SdrObjList* pOL=pO->GetSubList(); if (bNoContortion || pOL==NULL) { ImpDistortObj(pO,aRefRect,aRefPoly,bNoContortion); } else { SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS); while (aIter.IsMore()) { SdrObject* pO1=aIter.Next(); ImpDistortObj(pO1,aRefRect,aRefPoly,bNoContortion); } } } if( bUndo ) EndUndo(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, sal_Bool /*bReplaceAll*/) { // bReplaceAll has no effect here Rectangle aAllSnapRect(GetMarkedObjRect()); const SfxPoolItem *pPoolItem=NULL; if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,sal_True,&pPoolItem)==SFX_ITEM_SET) { long n=((const SdrTransformRef1XItem*)pPoolItem)->GetValue(); SetRef1(Point(n,GetRef1().Y())); } if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,sal_True,&pPoolItem)==SFX_ITEM_SET) { long n=((const SdrTransformRef1YItem*)pPoolItem)->GetValue(); SetRef1(Point(GetRef1().X(),n)); } if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,sal_True,&pPoolItem)==SFX_ITEM_SET) { long n=((const SdrTransformRef2XItem*)pPoolItem)->GetValue(); SetRef2(Point(n,GetRef2().Y())); } if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,sal_True,&pPoolItem)==SFX_ITEM_SET) { long n=((const SdrTransformRef2YItem*)pPoolItem)->GetValue(); SetRef2(Point(GetRef2().X(),n)); } long nAllPosX=0; sal_Bool bAllPosX=sal_False; long nAllPosY=0; sal_Bool bAllPosY=sal_False; long nAllWdt=0; sal_Bool bAllWdt=sal_False; long nAllHgt=0; sal_Bool bAllHgt=sal_False; sal_Bool bDoIt=sal_False; if (rAttr.GetItemState(SDRATTR_ALLPOSITIONX,sal_True,&pPoolItem)==SFX_ITEM_SET) { nAllPosX=((const SdrAllPositionXItem*)pPoolItem)->GetValue(); bAllPosX=sal_True; bDoIt=sal_True; } if (rAttr.GetItemState(SDRATTR_ALLPOSITIONY,sal_True,&pPoolItem)==SFX_ITEM_SET) { nAllPosY=((const SdrAllPositionYItem*)pPoolItem)->GetValue(); bAllPosY=sal_True; bDoIt=sal_True; } if (rAttr.GetItemState(SDRATTR_ALLSIZEWIDTH,sal_True,&pPoolItem)==SFX_ITEM_SET) { nAllWdt=((const SdrAllSizeWidthItem*)pPoolItem)->GetValue(); bAllWdt=sal_True; bDoIt=sal_True; } if (rAttr.GetItemState(SDRATTR_ALLSIZEHEIGHT,sal_True,&pPoolItem)==SFX_ITEM_SET) { nAllHgt=((const SdrAllSizeHeightItem*)pPoolItem)->GetValue(); bAllHgt=sal_True; bDoIt=sal_True; } if (bDoIt) { Rectangle aRect(aAllSnapRect); // TODO: change this for PolyPt's and GluePt's!!! if (bAllPosX) aRect.Move(nAllPosX-aRect.Left(),0); if (bAllPosY) aRect.Move(0,nAllPosY-aRect.Top()); if (bAllWdt) aRect.Right()=aAllSnapRect.Left()+nAllWdt; if (bAllHgt) aRect.Bottom()=aAllSnapRect.Top()+nAllHgt; SetMarkedObjRect(aRect); } if (rAttr.GetItemState(SDRATTR_RESIZEXALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { Fraction aXFact=((const SdrResizeXAllItem*)pPoolItem)->GetValue(); ResizeMarkedObj(aAllSnapRect.TopLeft(),aXFact,Fraction(1,1)); } if (rAttr.GetItemState(SDRATTR_RESIZEYALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { Fraction aYFact=((const SdrResizeYAllItem*)pPoolItem)->GetValue(); ResizeMarkedObj(aAllSnapRect.TopLeft(),Fraction(1,1),aYFact); } if (rAttr.GetItemState(SDRATTR_ROTATEALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { long nAngle=((const SdrRotateAllItem*)pPoolItem)->GetValue(); RotateMarkedObj(aAllSnapRect.Center(),nAngle); } if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { long nAngle=((const SdrHorzShearAllItem*)pPoolItem)->GetValue(); ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_False); } if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) { long nAngle=((const SdrVertShearAllItem*)pPoolItem)->GetValue(); ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_True); } const bool bUndo = IsUndoEnabled(); // TODO: check if WhichRange is necessary. sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); pObj->ApplyNotPersistAttr(rAttr); } } void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr, sal_Bool /*bOnlyHardAttr*/) const { // bOnlyHardAttr has no effect here. // TODO: Take into account the origin and PvPos. Rectangle aAllSnapRect(GetMarkedObjRect()); // TODO: change this for PolyPt's and GluePt's!!! long nAllSnapPosX=aAllSnapRect.Left(); long nAllSnapPosY=aAllSnapRect.Top(); long nAllSnapWdt=aAllSnapRect.GetWidth()-1; long nAllSnapHgt=aAllSnapRect.GetHeight()-1; // TODO: could go into CheckPossibilities bool bMovProtect = false, bMovProtectDC = false; bool bSizProtect = false, bSizProtectDC = false; bool bPrintable = true, bPrintableDC = false; bool bVisible = true, bVisibleDC = false; SdrLayerID nLayerId=0; sal_Bool bLayerDC=sal_False; rtl::OUString aObjName; sal_Bool bObjNameDC=sal_False,bObjNameSet=sal_False; long nSnapPosX=0; sal_Bool bSnapPosXDC=sal_False; long nSnapPosY=0; sal_Bool bSnapPosYDC=sal_False; long nSnapWdt=0; sal_Bool bSnapWdtDC=sal_False; long nSnapHgt=0; sal_Bool bSnapHgtDC=sal_False; long nLogicWdt=0; sal_Bool bLogicWdtDC=sal_False,bLogicWdtDiff=sal_False; long nLogicHgt=0; sal_Bool bLogicHgtDC=sal_False,bLogicHgtDiff=sal_False; long nRotAngle=0; sal_Bool bRotAngleDC=sal_False; long nShrAngle=0; sal_Bool bShrAngleDC=sal_False; Rectangle aSnapRect; Rectangle aLogicRect; sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if (nm==0) { nLayerId=pObj->GetLayer(); bMovProtect=pObj->IsMoveProtect(); bSizProtect=pObj->IsResizeProtect(); bPrintable =pObj->IsPrintable(); bVisible = pObj->IsVisible(); Rectangle aSnapRect2(pObj->GetSnapRect()); Rectangle aLogicRect2(pObj->GetLogicRect()); nSnapPosX=aSnapRect2.Left(); nSnapPosY=aSnapRect2.Top(); nSnapWdt=aSnapRect2.GetWidth()-1; nSnapHgt=aSnapRect2.GetHeight()-1; nLogicWdt=aLogicRect2.GetWidth()-1; nLogicHgt=aLogicRect2.GetHeight()-1; bLogicWdtDiff=nLogicWdt!=nSnapWdt; bLogicHgtDiff=nLogicHgt!=nSnapHgt; nRotAngle=pObj->GetRotateAngle(); nShrAngle=pObj->GetShearAngle(); } else { if (!bLayerDC && nLayerId !=pObj->GetLayer()) bLayerDC = true; if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect()) bMovProtectDC = true; if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC = true; if (!bPrintableDC && bPrintable !=pObj->IsPrintable()) bPrintableDC = true; if (!bVisibleDC && bVisible !=pObj->IsVisible()) bVisibleDC=true; if (!bRotAngleDC && nRotAngle !=pObj->GetRotateAngle()) bRotAngleDC=sal_True; if (!bShrAngleDC && nShrAngle !=pObj->GetShearAngle()) bShrAngleDC=sal_True; if (!bSnapWdtDC || !bSnapHgtDC || !bSnapPosXDC || !bSnapPosYDC || !bLogicWdtDiff || !bLogicHgtDiff) { aSnapRect=pObj->GetSnapRect(); if (nSnapPosX!=aSnapRect.Left()) bSnapPosXDC=sal_True; if (nSnapPosY!=aSnapRect.Top()) bSnapPosYDC=sal_True; if (nSnapWdt!=aSnapRect.GetWidth()-1) bSnapWdtDC=sal_True; if (nSnapHgt!=aSnapRect.GetHeight()-1) bSnapHgtDC=sal_True; } if (!bLogicWdtDC || !bLogicHgtDC || !bLogicWdtDiff || !bLogicHgtDiff) { aLogicRect=pObj->GetLogicRect(); if (nLogicWdt!=aLogicRect.GetWidth()-1) bLogicWdtDC=sal_True; if (nLogicHgt!=aLogicRect.GetHeight()-1) bLogicHgtDC=sal_True; if (!bLogicWdtDiff && aSnapRect.GetWidth()!=aLogicRect.GetWidth()) bLogicWdtDiff=sal_True; if (!bLogicHgtDiff && aSnapRect.GetHeight()!=aLogicRect.GetHeight()) bLogicHgtDiff=sal_True; } } if (!bObjNameDC ) { if (!bObjNameSet) { aObjName=pObj->GetName(); } else { if (!aObjName.equals(pObj->GetName())) bObjNameDC = true; } } } if (bSnapPosXDC || nAllSnapPosX!=nSnapPosX) rAttr.Put(SdrAllPositionXItem(nAllSnapPosX)); if (bSnapPosYDC || nAllSnapPosY!=nSnapPosY) rAttr.Put(SdrAllPositionYItem(nAllSnapPosY)); if (bSnapWdtDC || nAllSnapWdt !=nSnapWdt ) rAttr.Put(SdrAllSizeWidthItem(nAllSnapWdt)); if (bSnapHgtDC || nAllSnapHgt !=nSnapHgt ) rAttr.Put(SdrAllSizeHeightItem(nAllSnapHgt)); // items for pure transformations rAttr.Put(SdrMoveXItem()); rAttr.Put(SdrMoveYItem()); rAttr.Put(SdrResizeXOneItem()); rAttr.Put(SdrResizeYOneItem()); rAttr.Put(SdrRotateOneItem()); rAttr.Put(SdrHorzShearOneItem()); rAttr.Put(SdrVertShearOneItem()); if (nMarkAnz>1) { rAttr.Put(SdrResizeXAllItem()); rAttr.Put(SdrResizeYAllItem()); rAttr.Put(SdrRotateAllItem()); rAttr.Put(SdrHorzShearAllItem()); rAttr.Put(SdrVertShearAllItem()); } if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR) { rAttr.Put(SdrTransformRef1XItem(GetRef1().X())); rAttr.Put(SdrTransformRef1YItem(GetRef1().Y())); } if(eDragMode == SDRDRAG_MIRROR) { rAttr.Put(SdrTransformRef2XItem(GetRef2().X())); rAttr.Put(SdrTransformRef2YItem(GetRef2().Y())); } } SfxItemSet SdrEditView::GetAttrFromMarked(sal_Bool bOnlyHardAttr) const { SfxItemSet aSet(pMod->GetItemPool()); MergeAttrFromMarked(aSet,bOnlyHardAttr); //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there) //so we do not set them here // #i32448# // Do not disable, but clear the items. aSet.ClearItem(EE_FEATURE_TAB); aSet.ClearItem(EE_FEATURE_LINEBR); aSet.ClearItem(EE_FEATURE_NOTCONV); aSet.ClearItem(EE_FEATURE_FIELD); return aSet; } void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, sal_Bool bOnlyHardAttr) const { sal_uInt32 nMarkAnz(GetMarkedObjectCount()); for(sal_uInt32 a(0); a < nMarkAnz; a++) { // #80277# merging was done wrong in the prev version const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet(); SfxWhichIter aIter(rSet); sal_uInt16 nWhich(aIter.FirstWhich()); while(nWhich) { if(!bOnlyHardAttr) { if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False)) rAttr.InvalidateItem(nWhich); else rAttr.MergeValue(rSet.Get(nWhich), sal_True); } else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False)) { const SfxPoolItem& rItem = rSet.Get(nWhich); rAttr.MergeValue(rItem, sal_True); } nWhich = aIter.NextWhich(); } } } void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, sal_Bool bReplaceAll) { if (AreObjectsMarked()) { #ifdef DBG_UTIL { sal_Bool bHasEEFeatureItems=sal_False; SfxItemIter aIter(rAttr); const SfxPoolItem* pItem=aIter.FirstItem(); while (!bHasEEFeatureItems && pItem!=NULL) { if (!IsInvalidItem(pItem)) { sal_uInt16 nW=pItem->Which(); if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=sal_True; } pItem=aIter.NextItem(); } if(bHasEEFeatureItems) { String aMessage; aMessage.AppendAscii("SdrEditView::SetAttrToMarked(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents."); InfoBox(NULL, aMessage).Execute(); } } #endif // #103836# if the user thets character attributes to the complete shape, // we want to remove all hard set character attributes with same // which ids from the text. We do that later but here we remember // all character attribute which id's that are set. std::vector aCharWhichIds; { SfxItemIter aIter(rAttr); const SfxPoolItem* pItem=aIter.FirstItem(); while( pItem!=NULL ) { if (!IsInvalidItem(pItem)) { sal_uInt16 nWhich = pItem->Which(); if (nWhich>=EE_CHAR_START && nWhich<=EE_CHAR_END) aCharWhichIds.push_back( nWhich ); } pItem=aIter.NextItem(); } } // To make Undo reconstruct text attributes correctly after Format.Standard sal_Bool bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll); // save additional geometry information when paragraph or character attributes // are changed and the geometrical shape of the text object might be changed sal_Bool bPossibleGeomChange(sal_False); SfxWhichIter aIter(rAttr); sal_uInt16 nWhich = aIter.FirstWhich(); while(!bPossibleGeomChange && nWhich) { SfxItemState eState = rAttr.GetItemState(nWhich); if(eState == SFX_ITEM_SET) { if((nWhich >= SDRATTR_TEXT_MINFRAMEHEIGHT && nWhich <= SDRATTR_TEXT_CONTOURFRAME) || nWhich == SDRATTR_3DOBJ_PERCENT_DIAGONAL || nWhich == SDRATTR_3DOBJ_BACKSCALE || nWhich == SDRATTR_3DOBJ_DEPTH || nWhich == SDRATTR_3DOBJ_END_ANGLE || nWhich == SDRATTR_3DSCENE_DISTANCE) { bPossibleGeomChange = sal_True; } } nWhich = aIter.NextWhich(); } const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; ImpTakeDescriptionStr(STR_EditSetAttributes,aStr); BegUndo(aStr); } const sal_uInt32 nMarkAnz(GetMarkedObjectCount()); std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; // create ItemSet without SFX_ITEM_DONTCARE. Put() // uses its second parameter (bInvalidAsDefault) to // remove all such items to set them to default. SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges()); aAttr.Put(rAttr, sal_True); // #i38135# bool bResetAnimationTimer(false); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj(); if( bUndo ) { std::vector< SdrUndoAction* > vConnectorUndoActions; SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >( pObj ); if ( pEdgeObj ) bPossibleGeomChange = sal_True; else if( bUndo ) vConnectorUndoActions = CreateConnectorUndo( *pObj ); AddUndoActions( vConnectorUndoActions ); } // new geometry undo if(bPossibleGeomChange && bUndo) { // save position and size of object, too AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); } if( bUndo ) { // #i8508# // If this is a text object also rescue the OutlinerParaObject since // applying attributes to the object may change text layout when // multiple portions exist with multiple formats. If a OutlinerParaObject // really exists and needs to be rescued is evaluated in the undo // implementation itself. const bool bRescueText = dynamic_cast< SdrTextObj* >(pObj) != 0; // add attribute undo AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj,sal_False,bHasEEItems || bPossibleGeomChange || bRescueText)); } // set up a scene updater if object is a 3d object if(dynamic_cast< E3dObject* >(pObj)) { aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj)); } // set attributes at object pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll); if(pObj->ISA(SdrTextObj)) { SdrTextObj* pTextObj = ((SdrTextObj*)pObj); if(!aCharWhichIds.empty()) { Rectangle aOldBoundRect = pTextObj->GetLastBoundRect(); // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect()); pTextObj->RemoveOutlinerCharacterAttribs( aCharWhichIds ); // object has changed, should be called from // RemoveOutlinerCharacterAttribs. This will change when the text // object implementation changes. pTextObj->SetChanged(); pTextObj->BroadcastObjectChange(); pTextObj->SendUserCall(SDRUSERCALL_CHGATTR, aOldBoundRect); } } // #i38495# if(!bResetAnimationTimer) { if(pObj->GetViewContact().isAnimatedInAnyViewObjectContact()) { bResetAnimationTimer = true; } } } // fire scene updaters while(!aUpdaters.empty()) { delete aUpdaters.back(); aUpdaters.pop_back(); } // #i38135# if(bResetAnimationTimer) { SetAnimationTimer(0L); } // better check before what to do: // pObj->SetAttr() or SetNotPersistAttr() // TODO: missing implementation! SetNotPersistAttrToMarked(rAttr,bReplaceAll); if( bUndo ) EndUndo(); } } SfxStyleSheet* SdrEditView::GetStyleSheetFromMarked() const { SfxStyleSheet* pRet=NULL; sal_Bool b1st=sal_True; sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetMarkedSdrObj()->GetStyleSheet(); if (b1st) pRet=pSS; else if (pRet!=pSS) return NULL; // different stylesheets b1st=sal_False; } return pRet; } void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr) { if (AreObjectsMarked()) { const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr; if (pStyleSheet!=NULL) ImpTakeDescriptionStr(STR_EditSetStylesheet,aStr); else ImpTakeDescriptionStr(STR_EditDelStylesheet,aStr); BegUndo(aStr); } sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); for (sal_uIntPtr nm=0; nmGetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj())); AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true)); } pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); } if( bUndo ) EndUndo(); } } //////////////////////////////////////////////////////////////////////////////////////////////////// sal_Bool SdrEditView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const { if(GetMarkedObjectCount()) { rTargetSet.Put(GetAttrFromMarked(bOnlyHardAttr), sal_False); return sal_True; } else { return SdrMarkView::GetAttributes(rTargetSet, bOnlyHardAttr); } } sal_Bool SdrEditView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll) { if (GetMarkedObjectCount()!=0) { SetAttrToMarked(rSet,bReplaceAll); return sal_True; } else { return SdrMarkView::SetAttributes(rSet,bReplaceAll); } } SfxStyleSheet* SdrEditView::GetStyleSheet() const { if (GetMarkedObjectCount()!=0) { return GetStyleSheetFromMarked(); } else { return SdrMarkView::GetStyleSheet(); } } sal_Bool SdrEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr) { if (GetMarkedObjectCount()!=0) { SetStyleSheetToMarked(pStyleSheet,bDontRemoveHardAttr); return sal_True; } else { return SdrMarkView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); } } //////////////////////////////////////////////////////////////////////////////////////////////////// SfxItemSet SdrEditView::GetGeoAttrFromMarked() const { SfxItemSet aRetSet(pMod->GetItemPool(), // SID_ATTR_TRANSFORM_... from s:svxids.hrc SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE, SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT, SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS, 0); if (AreObjectsMarked()) { SfxItemSet aMarkAttr(GetAttrFromMarked(sal_False)); // because of AutoGrowHeight and corner radius Rectangle aRect(GetMarkedObjRect() ); // restore position to that before calc hack aRect -= GetGridOffset(); if(GetSdrPageView()) { GetSdrPageView()->LogicToPagePos(aRect); } // position aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X,aRect.Left())); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y,aRect.Top())); // size long nResizeRefX=aRect.Left(); long nResizeRefY=aRect.Top(); if (eDragMode==SDRDRAG_ROTATE) { // use rotation axis as a reference for resizing, too nResizeRefX=aRef1.X(); nResizeRefY=aRef1.Y(); } aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH,aRect.Right()-aRect.Left())); aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT,aRect.Bottom()-aRect.Top())); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X,nResizeRefX)); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y,nResizeRefY)); Point aRotateAxe(aRef1); if(GetSdrPageView()) { GetSdrPageView()->LogicToPagePos(aRotateAxe); } // rotation long nRotateRefX=aRect.Center().X(); long nRotateRefY=aRect.Center().Y(); if (eDragMode==SDRDRAG_ROTATE) { nRotateRefX=aRotateAxe.X(); nRotateRefY=aRotateAxe.Y(); } aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE,GetMarkedObjRotate())); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X,nRotateRefX)); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y,nRotateRefY)); // shearing long nShearRefX=aRect.Left(); long nShearRefY=aRect.Bottom(); if (eDragMode==SDRDRAG_ROTATE) { // use rotation axis as a reference for shearing, too nShearRefX=aRotateAxe.X(); nShearRefY=aRotateAxe.Y(); } aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,GetMarkedObjShear())); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X,nShearRefX)); aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y,nShearRefY)); // check every object whether it is protected const SdrMarkList& rMarkList=GetMarkedObjectList(); sal_uIntPtr nMarkCount=rMarkList.GetMarkCount(); SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj(); bool bPosProt=pObj->IsMoveProtect(); bool bSizProt=pObj->IsResizeProtect(); bool bPosProtDontCare=false; bool bSizProtDontCare=false; for (sal_uIntPtr i=1; iGetMarkedSdrObj(); if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=true; if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=true; } // InvalidateItem sets item to DONT_CARE if (bPosProtDontCare) { aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS); } else { aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS,bPosProt)); } if (bSizProtDontCare) { aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE); } else { aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE,bSizProt)); } SfxItemState eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH); sal_Bool bAutoGrow=((SdrTextAutoGrowWidthItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue(); if (eState==SFX_ITEM_DONTCARE) { aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH); } else if (eState==SFX_ITEM_SET) { aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH,bAutoGrow)); } eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT); bAutoGrow=((SdrTextAutoGrowHeightItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue(); if (eState==SFX_ITEM_DONTCARE) { aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT); } else if (eState==SFX_ITEM_SET) { aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT,bAutoGrow)); } eState=aMarkAttr.GetItemState(SDRATTR_ECKENRADIUS); long nRadius=((SdrEckenradiusItem&)(aMarkAttr.Get(SDRATTR_ECKENRADIUS))).GetValue(); if (eState==SFX_ITEM_DONTCARE) { aRetSet.InvalidateItem(SDRATTR_ECKENRADIUS); } else if (eState==SFX_ITEM_SET) { aRetSet.Put(SdrEckenradiusItem(nRadius)); } } return aRetSet; } Point ImpGetPoint(Rectangle aRect, RECT_POINT eRP) { switch(eRP) { case RP_LT: return aRect.TopLeft(); case RP_MT: return aRect.TopCenter(); case RP_RT: return aRect.TopRight(); case RP_LM: return aRect.LeftCenter(); case RP_MM: return aRect.Center(); case RP_RM: return aRect.RightCenter(); case RP_LB: return aRect.BottomLeft(); case RP_MB: return aRect.BottomCenter(); case RP_RB: return aRect.BottomRight(); } return Point(); // Should not happen! } void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) { Rectangle aRect(GetMarkedObjRect()); if(GetSdrPageView()) { GetSdrPageView()->LogicToPagePos(aRect); } long nOldRotateAngle=GetMarkedObjRotate(); long nOldShearAngle=GetMarkedObjShear(); const SdrMarkList& rMarkList=GetMarkedObjectList(); sal_uIntPtr nMarkCount=rMarkList.GetMarkCount(); SdrObject* pObj=NULL; RECT_POINT eSizePoint=RP_MM; long nPosDX=0; long nPosDY=0; long nSizX=0; long nSizY=0; long nRotateAngle=0; sal_Bool bModeIsRotate(eDragMode == SDRDRAG_ROTATE); long nRotateX(0); long nRotateY(0); long nOldRotateX(0); long nOldRotateY(0); if(bModeIsRotate) { Point aRotateAxe(aRef1); if(GetSdrPageView()) { GetSdrPageView()->LogicToPagePos(aRotateAxe); } nRotateX = nOldRotateX = aRotateAxe.X(); nRotateY = nOldRotateY = aRotateAxe.Y(); } long nShearAngle=0; long nShearX=0; long nShearY=0; sal_Bool bShearVert=sal_False; sal_Bool bChgPos=sal_False; sal_Bool bChgSiz=sal_False; sal_Bool bRotate=sal_False; sal_Bool bShear =sal_False; sal_Bool bSetAttr=sal_False; SfxItemSet aSetAttr(pMod->GetItemPool()); const SfxPoolItem* pPoolItem=NULL; // position if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_X,sal_True,&pPoolItem)) { nPosDX=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Left(); bChgPos=sal_True; } if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_Y,sal_True,&pPoolItem)){ nPosDY=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Top(); bChgPos=sal_True; } // size if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTH,sal_True,&pPoolItem)) { nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue(); bChgSiz=sal_True; } if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,sal_True,&pPoolItem)) { nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue(); bChgSiz=sal_True; } if (bChgSiz) { eSizePoint=(RECT_POINT)((const SfxAllEnumItem&)rAttr.Get(SID_ATTR_TRANSFORM_SIZE_POINT)).GetValue(); } // rotation if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,sal_True,&pPoolItem)) { nRotateAngle=((const SfxInt32Item*)pPoolItem)->GetValue()-nOldRotateAngle; bRotate = (nRotateAngle != 0); } // position rotation point x if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_X, sal_True ,&pPoolItem)) nRotateX = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_X)).GetValue(); // position rotation point y if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_Y, sal_True ,&pPoolItem)) nRotateY = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_Y)).GetValue(); // shearing if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,sal_True,&pPoolItem)) { long nNewShearAngle=((const SfxInt32Item*)pPoolItem)->GetValue(); if (nNewShearAngle>SDRMAXSHEAR) nNewShearAngle=SDRMAXSHEAR; if (nNewShearAngle<-SDRMAXSHEAR) nNewShearAngle=-SDRMAXSHEAR; if (nNewShearAngle!=nOldShearAngle) { bShearVert=((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue(); if (bShearVert) { nShearAngle=nNewShearAngle; } else { if (nNewShearAngle!=0 && nOldShearAngle!=0) { // bug fix double nOld=tan((double)nOldShearAngle*nPi180); double nNew=tan((double)nNewShearAngle*nPi180); nNew-=nOld; nNew=atan(nNew)/nPi180; nShearAngle=Round(nNew); } else { nShearAngle=nNewShearAngle-nOldShearAngle; } } bShear=nShearAngle!=0; if (bShear) { nShearX=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X)).GetValue(); nShearY=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y)).GetValue(); } } } // AutoGrow if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH,sal_True,&pPoolItem)) { sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue(); aSetAttr.Put(SdrTextAutoGrowWidthItem(bAutoGrow)); bSetAttr=sal_True; } if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT,sal_True,&pPoolItem)) { sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue(); aSetAttr.Put(SdrTextAutoGrowHeightItem(bAutoGrow)); bSetAttr=sal_True; } // corner radius if (bEdgeRadiusAllowed && SFX_ITEM_SET==rAttr.GetItemState(SDRATTR_ECKENRADIUS,sal_True,&pPoolItem)) { long nRadius=((SdrEckenradiusItem*)pPoolItem)->GetValue(); aSetAttr.Put(SdrEckenradiusItem(nRadius)); bSetAttr=sal_True; } ForcePossibilities(); BegUndo(ImpGetResStr(STR_EditTransform),GetDescriptionOfMarkedObjects()); if (bSetAttr) { SetAttrToMarked(aSetAttr,sal_False); } // change size and height if (bChgSiz && (bResizeFreeAllowed || bResizePropAllowed)) { Fraction aWdt(nSizX,aRect.Right()-aRect.Left()); Fraction aHgt(nSizY,aRect.Bottom()-aRect.Top()); Point aRef(ImpGetPoint(aRect,eSizePoint)); if(GetSdrPageView()) { GetSdrPageView()->PagePosToLogic(aRef); } ResizeMarkedObj(aRef,aWdt,aHgt); } // rotate if (bRotate && (bRotateFreeAllowed || bRotate90Allowed)) { Point aRef(nRotateX,nRotateY); if(GetSdrPageView()) { GetSdrPageView()->PagePosToLogic(aRef); } RotateMarkedObj(aRef,nRotateAngle); } // set rotation point position if(bModeIsRotate && (nRotateX != nOldRotateX || nRotateY != nOldRotateY)) { Point aNewRef1(nRotateX, nRotateY); if(GetSdrPageView()) { GetSdrPageView()->PagePosToLogic(aNewRef1); } SetRef1(aNewRef1); } // shear if (bShear && bShearAllowed) { Point aRef(nShearX,nShearY); if(GetSdrPageView()) { GetSdrPageView()->PagePosToLogic(aRef); } ShearMarkedObj(aRef,nShearAngle,bShearVert); // #i74358# // ShearMarkedObj creates a linear combination of the existing transformation and // the new shear to apply. If the object is already transformed (e.g. rotated) the // linear combination will not decompose to the same start values again, but to a // new combination. Thus it makes no sense to check if the wanted shear is reached // or not. Taking out. } // change position if (bChgPos && bMoveAllowed) { MoveMarkedObj(Size(nPosDX,nPosDY)); } // protect position if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS, sal_True, &pPoolItem)) { const bool bProtPos(((const SfxBoolItem*)pPoolItem)->GetValue()); bool bChanged(false); for(sal_uInt32 i(0); i < nMarkCount; i++) { pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); if(pObj->IsMoveProtect() != bProtPos) { bChanged = true; pObj->SetMoveProtect(bProtPos); if(bProtPos) { pObj->SetResizeProtect(true); } } } if(bChanged) { bMoveProtect = bProtPos; if(bProtPos) { bResizeProtect = true; } // #i77187# there is no simple method to get the toolbars updated // in the application. The App is listening to selection change and i // will use it here (even if not true). It's acceptable since changing // this model data is pretty rare and only possible using the F4 dialog MarkListHasChanged(); } } if(!bMoveProtect) { // protect size if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZE, sal_True, &pPoolItem)) { const bool bProtSize(((const SfxBoolItem*)pPoolItem)->GetValue()); bool bChanged(false); for(sal_uInt32 i(0); i < nMarkCount; i++) { pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); if(pObj->IsResizeProtect() != bProtSize) { bChanged = true; pObj->SetResizeProtect(bProtSize); } } if(bChanged) { bResizeProtect = bProtSize; // #i77187# see above MarkListHasChanged(); } } } EndUndo(); } //////////////////////////////////////////////////////////////////////////////////////////////////// sal_Bool SdrEditView::IsAlignPossible() const { // at least two selected objects, at least one of them movable ForcePossibilities(); sal_uIntPtr nAnz=GetMarkedObjectCount(); if (nAnz==0) return sal_False; // nothing selected! if (nAnz==1) return bMoveAllowed; // align single object to page return bOneOrMoreMovable; // otherwise: MarkCount>=2 } void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert, sal_Bool bBoundRects) { if (eHor==SDRHALIGN_NONE && eVert==SDRVALIGN_NONE) return; SortMarkedObjects(); if (GetMarkedObjectCount()<1) return; const bool bUndo = IsUndoEnabled(); if( bUndo ) { XubString aStr(GetDescriptionOfMarkedObjects()); if (eHor==SDRHALIGN_NONE) { switch (eVert) { case SDRVALIGN_TOP : ImpTakeDescriptionStr(STR_EditAlignVTop ,aStr); break; case SDRVALIGN_BOTTOM: ImpTakeDescriptionStr(STR_EditAlignVBottom,aStr); break; case SDRVALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignVCenter,aStr); break; default: break; } } else if (eVert==SDRVALIGN_NONE) { switch (eHor) { case SDRHALIGN_LEFT : ImpTakeDescriptionStr(STR_EditAlignHLeft ,aStr); break; case SDRHALIGN_RIGHT : ImpTakeDescriptionStr(STR_EditAlignHRight ,aStr); break; case SDRHALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignHCenter,aStr); break; default: break; } } else if (eHor==SDRHALIGN_CENTER && eVert==SDRVALIGN_CENTER) { ImpTakeDescriptionStr(STR_EditAlignCenter,aStr); } else { ImpTakeDescriptionStr(STR_EditAlign,aStr); } BegUndo(aStr); } Rectangle aBound; sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); sal_uIntPtr nm; sal_Bool bHasFixed=sal_False; for (nm=0; nmGetMarkedSdrObj(); SdrObjTransformInfoRec aInfo; pObj->TakeObjInfo(aInfo); if (!aInfo.bMoveAllowed || pObj->IsMoveProtect()) { Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect()); aBound.Union(aObjRect); bHasFixed=sal_True; } } if (!bHasFixed) { if (nMarkAnz==1) { // align single object to page const SdrObject* pObj=GetMarkedObjectByIndex(0L); const SdrPage* pPage=pObj->GetPage(); const SdrPageGridFrameList* pGFL=pPage->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj->GetSnapRect())); const SdrPageGridFrame* pFrame=NULL; if (pGFL!=NULL && pGFL->GetCount()!=0) { // Writer pFrame=&((*pGFL)[0]); } if (pFrame!=NULL) { // Writer aBound=pFrame->GetUserArea(); } else { aBound=Rectangle(pPage->GetLftBorder(),pPage->GetUppBorder(), pPage->GetWdt()-pPage->GetRgtBorder(), pPage->GetHgt()-pPage->GetLwrBorder()); } } else { if (bBoundRects) aBound=GetMarkedObjBoundRect(); else aBound=GetMarkedObjRect(); } } Point aCenter(aBound.Center()); for (nm=0; nmGetMarkedSdrObj(); SdrObjTransformInfoRec aInfo; pObj->TakeObjInfo(aInfo); if (aInfo.bMoveAllowed && !pObj->IsMoveProtect()) { long nXMov=0; long nYMov=0; Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect()); switch (eVert) { case SDRVALIGN_TOP : nYMov=aBound.Top() -aObjRect.Top() ; break; case SDRVALIGN_BOTTOM: nYMov=aBound.Bottom()-aObjRect.Bottom() ; break; case SDRVALIGN_CENTER: nYMov=aCenter.Y() -aObjRect.Center().Y(); break; default: break; } switch (eHor) { case SDRHALIGN_LEFT : nXMov=aBound.Left() -aObjRect.Left() ; break; case SDRHALIGN_RIGHT : nXMov=aBound.Right() -aObjRect.Right() ; break; case SDRHALIGN_CENTER: nXMov=aCenter.X() -aObjRect.Center().X(); break; default: break; } if (nXMov!=0 || nYMov!=0) { // SdrEdgeObj needs an extra SdrUndoGeoObj since the // connections may need to be saved if( bUndo ) { if( dynamic_cast(pObj) ) { AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); } AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov))); } pObj->Move(Size(nXMov,nYMov)); } } } if( bUndo ) EndUndo(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */