| /************************************************************** |
| * |
| * 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_svx.hxx" |
| |
| #include <svx/svdedtv.hxx> |
| #include <math.h> |
| |
| #ifndef _MATH_H |
| #define _MATH_H |
| #endif |
| #include <tools/bigint.hxx> |
| #include <svl/itemiter.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <svx/rectenum.hxx> |
| #include <svx/svxids.hrc> // fuer SID_ATTR_TRANSFORM_... |
| #include <svx/svdattr.hxx> // fuer Get/SetGeoAttr |
| #include "svx/svditext.hxx" |
| #include "svx/svditer.hxx" |
| #include <svx/svdtrans.hxx> |
| #include <svx/svdundo.hxx> |
| #include <svx/svdpage.hxx> |
| #include <svx/svdpagv.hxx> |
| #include <svx/svdlayer.hxx> // fuer MergeNotPersistAttr |
| #include <svx/svdattrx.hxx> // fuer MergeNotPersistAttr |
| #include <svx/svdetc.hxx> // fuer SearchOutlinerItems |
| #include <svx/svdopath.hxx> // fuer Crook |
| #include "svx/svdstr.hrc" // Namen aus der Resource |
| #include "svx/svdglob.hxx" // StringCache |
| #include <editeng/eeitem.hxx> |
| #include <svl/aeitem.hxx> |
| #include <svl/whiter.hxx> |
| #include <svx/sdr/contact/objectcontact.hxx> |
| #include <svx/sdr/contact/viewcontact.hxx> |
| #include <svx/e3dsceneupdater.hxx> |
| #include <svx/obj3d.hxx> |
| #include <basegfx/matrix/b2dhommatrix.hxx> |
| #include <svx/AffineMatrixItem.hxx> |
| #include <basegfx/matrix/b2dhommatrixtools.hxx> |
| #include <svx/xlnwtit.hxx> |
| #include <svx/xlnstwit.hxx> |
| #include <svx/xlnedwit.hxx> |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // |
| // @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@ |
| // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ |
| // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ |
| // @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@ |
| // @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@ |
| // @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@ |
| // @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@ |
| // |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| void SdrEditView::SetMarkedObjRect(const Rectangle& rRect, sal_Bool bCopy) |
| { |
| DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() mit leerem Rect mach keinen Sinn"); |
| if (rRect.IsEmpty()) return; |
| sal_uIntPtr nAnz=GetMarkedObjectCount(); |
| if (nAnz==0) return; |
| Rectangle aR0(GetMarkedObjRect()); |
| DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() ist leer"); |
| 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; nm<nAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| if( bUndo ) |
| AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); |
| |
| Rectangle aR1(pO->GetSnapRect()); |
| if (!aR1.IsEmpty()) |
| { |
| if (aR1==aR0) |
| { |
| aR1=rRect; |
| } |
| else |
| { // aR1 von aR0 nach rRect transformieren |
| 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 { |
| DBG_ERROR("SetMarkedObjRect(): pObj->GetSnapRect() liefert leeres 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); |
| // benoetigt eigene UndoGroup wegen Parameter |
| BegUndo(aStr,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE); |
| } |
| |
| if (bCopy) |
| CopyMarkedObj(); |
| |
| sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); |
| for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| if( bUndo ) |
| { |
| std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); |
| AddUndoActions( vConnectorUndoActions ); |
| AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); |
| } |
| pO->Resize(rRef,xFact,yFact); |
| } |
| |
| if( bUndo ) |
| EndUndo(); |
| } |
| void SdrEditView::ResizeMultMarkedObj(const Point& rRef, |
| const Fraction& xFact, |
| const Fraction& yFact, |
| const bool bCopy, |
| const bool bWdh, |
| const bool bHgt) |
| { |
| 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| if( bUndo ) |
| { |
| std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) ); |
| AddUndoActions( vConnectorUndoActions ); |
| AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); |
| } |
| |
| Fraction aFrac(1,1); |
| if (bWdh && bHgt) |
| pO->Resize(rRef, xFact, yFact); |
| else if (bWdh) |
| pO->Resize(rRef, xFact, aFrac); |
| else if (bHgt) |
| pO->Resize(rRef, aFrac, yFact); |
| } |
| if( bUndo ) |
| EndUndo(); |
| } |
| |
| long SdrEditView::GetMarkedObjRotate() const |
| { |
| long nRetval(0); |
| |
| if(GetMarkedObjectCount()) |
| { |
| SdrMark* pM = GetSdrMarkByIndex(0); |
| SdrObject* pO = pM->GetMarkedSdrObj(); |
| |
| nRetval = pO->GetRotateAngle(); |
| } |
| |
| return nRetval; |
| //sal_Bool b1st=sal_True; |
| //sal_Bool bOk=sal_True; |
| //long nWink=0; |
| //sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); |
| //for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) { |
| // SdrMark* pM=GetSdrMarkByIndex(nm); |
| // SdrObject* pO=pM->GetMarkedSdrObj(); |
| // 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 it's layouted 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 it's layouted 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; nm<nMarkAnz && bOk; nm++) { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| 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()) |
| { |
| // FuerPolyObj's, aber NICHT fuer SdrPathObj's, z.B. fuer's Bemassungsobjekt |
| 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++) |
| { |
| // hier koennte man vieleicht auch mal das Broadcasting optimieren |
| // ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch |
| pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum); |
| } |
| |
| bDone = sal_True; |
| } |
| |
| if(!bDone) |
| { |
| // Fuer alle anderen oder wenn 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| 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()) |
| { |
| // z.B. fuer's Bemassungsobjekt |
| 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++) |
| { |
| // hier koennte man vieleicht auch mal das Broadcasting optimieren |
| // ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch |
| 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pO=pM->GetMarkedSdrObj(); |
| 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 hat hier keinerlei Wirkung |
| 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); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!! |
| 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: WhichRange nach Notwendigkeit ueberpruefen. |
| sal_uIntPtr nMarkAnz=GetMarkedObjectCount(); |
| for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) |
| { |
| const SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pObj=pM->GetMarkedSdrObj(); |
| //const SdrPageView* pPV=pM->GetPageView(); |
| if( bUndo ) |
| AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); |
| |
| pObj->ApplyNotPersistAttr(rAttr); |
| } |
| } |
| |
| void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr, sal_Bool /*bOnlyHardAttr*/) const |
| { |
| // bOnlyHardAttr hat hier keinerlei Wirkung |
| // Hier muss ausserdem noch der Nullpunkt und |
| // die PvPos berueksichtigt werden. |
| Rectangle aAllSnapRect(GetMarkedObjRect()); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!! |
| long nAllSnapPosX=aAllSnapRect.Left(); |
| long nAllSnapPosY=aAllSnapRect.Top(); |
| long nAllSnapWdt=aAllSnapRect.GetWidth()-1; |
| long nAllSnapHgt=aAllSnapRect.GetHeight()-1; |
| // koennte mal zu CheckPossibilities mit rein |
| sal_Bool bMovProtect=sal_False,bMovProtectDC=sal_False; |
| sal_Bool bSizProtect=sal_False,bSizProtectDC=sal_False; |
| sal_Bool bPrintable =sal_True ,bPrintableDC=sal_False; |
| sal_Bool bVisible = sal_True, bVisibleDC=sal_False; |
| SdrLayerID nLayerId=0; sal_Bool bLayerDC=sal_False; |
| XubString 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; nm<nMarkAnz; nm++) { |
| const SdrMark* pM=GetSdrMarkByIndex(nm); |
| const SdrObject* pObj=pM->GetMarkedSdrObj(); |
| 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=sal_True; |
| if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect()) bMovProtectDC=sal_True; |
| if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC=sal_True; |
| if (!bPrintableDC && bPrintable !=pObj->IsPrintable()) bPrintableDC=sal_True; |
| if (!bVisibleDC && bVisible !=pObj->IsVisible()) bVisibleDC=sal_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!=pObj->GetName()) bObjNameDC=sal_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 fuer reine Transformationen |
| 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()->GetItemSet(); |
| 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(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten."); |
| 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<sal_uInt16> 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(); |
| } |
| } |
| |
| // Joe, 2.7.98: Damit Undo nach Format.Standard auch die Textattribute korrekt restauriert |
| sal_Bool bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll); |
| |
| // AW 030100: save additional geom info when para or char attributes |
| // are changed and the geom form 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 it's 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); |
| |
| // check if LineWidth is part of the change |
| const bool bLineWidthChange(SFX_ITEM_SET == aAttr.GetItemState(XATTR_LINEWIDTH)); |
| sal_Int32 nNewLineWidth(0); |
| sal_Int32 nOldLineWidth(0); |
| |
| if(bLineWidthChange) |
| { |
| nNewLineWidth = ((const XLineWidthItem&)aAttr.Get(XATTR_LINEWIDTH)).GetValue(); |
| } |
| |
| for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pObj = pM->GetMarkedSdrObj(); |
| |
| 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 obect, 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 scxene updater if object is a 3d object |
| if(dynamic_cast< E3dObject* >(pObj)) |
| { |
| aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj)); |
| } |
| |
| if(bLineWidthChange) |
| { |
| nOldLineWidth = ((const XLineWidthItem&)pObj->GetMergedItem(XATTR_LINEWIDTH)).GetValue(); |
| } |
| |
| // set attributes at object |
| pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll); |
| |
| if(bLineWidthChange) |
| { |
| const SfxItemSet& rSet = pObj->GetMergedItemSet(); |
| |
| if(nOldLineWidth != nNewLineWidth) |
| { |
| if(SFX_ITEM_DONTCARE != rSet.GetItemState(XATTR_LINESTARTWIDTH)) |
| { |
| const sal_Int32 nValAct(((const XLineStartWidthItem&)rSet.Get(XATTR_LINESTARTWIDTH)).GetValue()); |
| const sal_Int32 nValNewStart(std::max((sal_Int32)0, nValAct + (((nNewLineWidth - nOldLineWidth) * 15) / 10))); |
| |
| pObj->SetMergedItem(XLineStartWidthItem(nValNewStart)); |
| } |
| |
| if(SFX_ITEM_DONTCARE != rSet.GetItemState(XATTR_LINEENDWIDTH)) |
| { |
| const sal_Int32 nValAct(((const XLineEndWidthItem&)rSet.Get(XATTR_LINEENDWIDTH)).GetValue()); |
| const sal_Int32 nValNewEnd(std::max((sal_Int32)0, nValAct + (((nNewLineWidth - nOldLineWidth) * 15) / 10))); |
| |
| pObj->SetMergedItem(XLineEndWidthItem(nValNewEnd)); |
| } |
| } |
| } |
| |
| 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 form |
| // 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); |
| } |
| |
| // besser vorher checken, was gemacht werden soll: |
| // pObj->SetAttr() oder SetNotPersistAttr() |
| // !!! fehlende 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; nm<nMarkAnz; nm++) { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SfxStyleSheet* pSS=pM->GetMarkedSdrObj()->GetStyleSheet(); |
| if (b1st) pRet=pSS; |
| else if (pRet!=pSS) return NULL; // verschiedene 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| if( bUndo ) |
| { |
| AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj())); |
| AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true)); |
| } |
| pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); |
| } |
| |
| if( bUndo ) |
| EndUndo(); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| /* new interface src537 */ |
| 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 // SfxStyleSheet* SdrEditView::GetStyleSheet(sal_Bool& rOk) const |
| { |
| if (GetMarkedObjectCount()!=0) { |
| //rOk=sal_True; |
| return GetStyleSheetFromMarked(); |
| } else { |
| return SdrMarkView::GetStyleSheet(); // SdrMarkView::GetStyleSheet(rOk); |
| } |
| } |
| |
| 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_... aus 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)); // wg. AutoGrowHeight und Eckenradius |
| Rectangle aRect(GetMarkedObjRect()); |
| |
| 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())); |
| |
| // Groesse |
| long nResizeRefX=aRect.Left(); |
| long nResizeRefY=aRect.Top(); |
| if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Resize |
| 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); |
| } |
| |
| // Drehung |
| 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)); |
| |
| // Shear |
| long nShearRefX=aRect.Left(); |
| long nShearRefY=aRect.Bottom(); |
| if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Shear |
| 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)); |
| |
| // Pruefen der einzelnen Objekte, ob Objekte geschuetzt sind |
| const SdrMarkList& rMarkList=GetMarkedObjectList(); |
| sal_uIntPtr nMarkCount=rMarkList.GetMarkCount(); |
| SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj(); |
| sal_Bool bPosProt=pObj->IsMoveProtect(); |
| sal_Bool bSizProt=pObj->IsResizeProtect(); |
| sal_Bool bPosProtDontCare=sal_False; |
| sal_Bool bSizProtDontCare=sal_False; |
| for (sal_uIntPtr i=1; i<nMarkCount && (!bPosProtDontCare || !bSizProtDontCare); i++) |
| { |
| pObj=rMarkList.GetMark(i)->GetMarkedSdrObj(); |
| if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=sal_True; |
| if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=sal_True; |
| } |
| |
| // InvalidateItem setzt das Item auf 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)); |
| } |
| |
| basegfx::B2DHomMatrix aTransformation; |
| |
| if(nMarkCount > 1) |
| { |
| // multiple objects, range is collected in aRect |
| aTransformation = basegfx::tools::createScaleTranslateB2DHomMatrix( |
| aRect.Left(), aRect.Top(), |
| aRect.getWidth(), aRect.getHeight()); |
| } |
| else if(pObj) |
| { |
| // single object, get homogen transformation |
| basegfx::B2DPolyPolygon aPolyPolygon; |
| |
| pObj->TRGetBaseGeometry(aTransformation, aPolyPolygon); |
| } |
| |
| if(aTransformation.isIdentity()) |
| { |
| aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_MATRIX); |
| } |
| else |
| { |
| com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D; |
| Point aPageOffset(0, 0); |
| |
| if(GetSdrPageView()) |
| { |
| aPageOffset = GetSdrPageView()->GetPageOrigin(); |
| } |
| |
| aAffineMatrix2D.m00 = aTransformation.get(0, 0); |
| aAffineMatrix2D.m01 = aTransformation.get(0, 1); |
| aAffineMatrix2D.m02 = aTransformation.get(0, 2) - aPageOffset.X(); |
| aAffineMatrix2D.m10 = aTransformation.get(1, 0); |
| aAffineMatrix2D.m11 = aTransformation.get(1, 1); |
| aAffineMatrix2D.m12 = aTransformation.get(1, 2) - aPageOffset.Y(); |
| |
| aRetSet.Put(AffineMatrixItem(&aAffineMatrix2D)); |
| } |
| } |
| |
| 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(); // Sollte nicht vorkommen ! |
| } |
| |
| 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; |
| |
| // #86909# |
| 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 nNewShearAngle=0; |
| 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 bChgWdh=sal_False; |
| sal_Bool bChgHgt=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; |
| } |
| // Groesse |
| if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTH,sal_True,&pPoolItem)) { |
| nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue(); |
| bChgSiz=sal_True; |
| bChgWdh=sal_True; |
| } |
| if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,sal_True,&pPoolItem)) { |
| nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue(); |
| bChgSiz=sal_True; |
| bChgHgt=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); |
| } |
| |
| // #86909# pos rot 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(); |
| |
| // #86909# pos rot 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(); |
| |
| // Shear |
| if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,sal_True,&pPoolItem)) { |
| 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) { |
| // Bugfix #25714#. |
| 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; |
| } |
| |
| // Eckenradius |
| 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); |
| } |
| |
| // Groesse und Hoehe aendern |
| 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); |
| } |
| |
| ResizeMultMarkedObj(aRef, aWdt, aHgt, false, bChgWdh, bChgHgt); |
| } |
| |
| // Rotieren |
| if (bRotate && (bRotateFreeAllowed || bRotate90Allowed)) { |
| Point aRef(nRotateX,nRotateY); |
| |
| if(GetSdrPageView()) |
| { |
| GetSdrPageView()->PagePosToLogic(aRef); |
| } |
| |
| RotateMarkedObj(aRef,nRotateAngle); |
| } |
| |
| // #86909# 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. |
| #if 0 |
| long nTempAngle=GetMarkedObjShear(); |
| if (nTempAngle!=0 && nTempAngle!=nNewShearAngle && !bShearVert) { |
| // noch eine 2. Iteration zur Kompensation der Rundungsfehler |
| double nOld=tan((double)nTempAngle*nPi180); |
| double nNew=tan((double)nNewShearAngle*nPi180); |
| nNew-=nOld; |
| nNew=atan(nNew)/nPi180; |
| nTempAngle=Round(nNew); |
| if (nTempAngle!=0) { |
| ShearMarkedObj(aRef,nTempAngle,bShearVert); |
| } |
| } |
| #endif |
| } |
| |
| // Position aendern |
| if (bChgPos && bMoveAllowed) { |
| MoveMarkedObj(Size(nPosDX,nPosDY)); |
| } |
| |
| // protect position |
| if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS, sal_True, &pPoolItem)) |
| { |
| const sal_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 sal_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 |
| { // Mindestens 2 markierte Objekte, davon mind. 1 beweglich |
| ForcePossibilities(); |
| sal_uIntPtr nAnz=GetMarkedObjectCount(); |
| if (nAnz==0) return sal_False; // Nix markiert! |
| if (nAnz==1) return bMoveAllowed; // einzelnes Obj an der Seite ausrichten |
| return bOneOrMoreMovable; // ansonsten ist 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pObj=pM->GetMarkedSdrObj(); |
| 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) |
| { // einzelnes Obj an der Seite ausrichten |
| 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; nm<nMarkAnz; nm++) |
| { |
| SdrMark* pM=GetSdrMarkByIndex(nm); |
| SdrObject* pObj=pM->GetMarkedSdrObj(); |
| SdrObjTransformInfoRec aInfo; |
| pObj->TakeObjInfo(aInfo); |
| if (aInfo.bMoveAllowed && !pObj->IsMoveProtect()) |
| { |
| // SdrPageView* pPV=pM->GetPageView(); |
| 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) |
| { |
| // #104104# SdrEdgeObj needs an extra SdrUndoGeoObj since the |
| // connections may need to be saved |
| if( bUndo ) |
| { |
| if( dynamic_cast<SdrEdgeObj*>(pObj) ) |
| { |
| AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); |
| } |
| |
| AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov))); |
| } |
| |
| pObj->Move(Size(nXMov,nYMov)); |
| } |
| } |
| } |
| |
| if( bUndo ) |
| EndUndo(); |
| } |
| |