1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basegfx/matrix/b2dhommatrix.hxx>
21 #include <basegfx/matrix/b2dhommatrixtools.hxx>
22 #include <editeng/editdata.hxx>
23 #include <editeng/eeitem.hxx>
25 #include <svl/aeitem.hxx>
26 #include <svl/itemiter.hxx>
27 #include <svl/whiter.hxx>
28 #include <tools/bigint.hxx>
29 #include <vcl/msgbox.hxx>
31 #include "getallcharpropids.hxx"
32 #include "svdglob.hxx"
33 #include "svx/svditer.hxx"
34 #include "svx/svdstr.hrc"
36 #include <svx/AffineMatrixItem.hxx>
37 #include <svx/e3dsceneupdater.hxx>
38 #include <svx/obj3d.hxx>
39 #include <svx/rectenum.hxx>
40 #include <svx/sdr/contact/objectcontact.hxx>
41 #include <svx/sdr/contact/viewcontact.hxx>
42 #include <svx/svdattr.hxx>
43 #include <svx/svdedtv.hxx>
44 #include <svx/svdetc.hxx>
45 #include <svx/svdlayer.hxx>
46 #include <svx/svdopath.hxx>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdpagv.hxx>
49 #include <svx/svdtrans.hxx>
50 #include <svx/svdundo.hxx>
51 #include <svx/svxids.hrc>
52 #include <sxallitm.hxx>
53 #include <sxmovitm.hxx>
54 #include <sxreaitm.hxx>
55 #include <sxreoitm.hxx>
56 #include <sxroaitm.hxx>
57 #include <sxrooitm.hxx>
58 #include <sxsalitm.hxx>
59 #include <sxsoitm.hxx>
60 #include <sxtraitm.hxx>
61 #include <svx/xlnedwit.hxx>
62 #include <svx/xlnstwit.hxx>
63 #include <svx/xlnwtit.hxx>
71 void SdrEditView::SetMarkedObjRect(const Rectangle
& rRect
, bool bCopy
)
73 DBG_ASSERT(!rRect
.IsEmpty(),"SetMarkedObjRect() with an empty Rect does not make sense.");
74 if (rRect
.IsEmpty()) return;
75 const size_t nCount
=GetMarkedObjectCount();
76 if (nCount
==0) return;
77 Rectangle
aR0(GetMarkedObjRect());
78 DBG_ASSERT(!aR0
.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() is empty.");
79 if (aR0
.IsEmpty()) return;
82 long w0
=aR0
.Right()-x0
;
83 long h0
=aR0
.Bottom()-y0
;
86 long w1
=rRect
.Right()-x1
;
87 long h1
=rRect
.Bottom()-y1
;
89 ImpTakeDescriptionStr(STR_EditPosSize
,aStr
);
91 aStr
+=ImpGetResStr(STR_EditWithCopy
);
93 const bool bUndo
= IsUndoEnabled();
100 for (size_t nm
=0; nm
<nCount
; ++nm
)
102 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
103 SdrObject
* pO
=pM
->GetMarkedSdrObj();
105 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
107 Rectangle
aR1(pO
->GetSnapRect());
115 { // transform aR1 to aR0 after rRect
117 BigInt
l(aR1
.Left());
118 BigInt
r(aR1
.Right());
120 BigInt
b(aR1
.Bottom());
134 aR1
.Right ()=long(r
);
136 aR1
.Bottom()=long(b
);
139 pO
->SetSnapRect(aR1
);
141 OSL_FAIL("SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect");
148 std::vector
< SdrUndoAction
* > SdrEditView::CreateConnectorUndo( SdrObject
& rO
)
150 std::vector
< SdrUndoAction
* > vUndoActions
;
152 if ( rO
.GetBroadcaster() )
154 const SdrPage
* pPage
= rO
.GetPage();
157 SdrObjListIter
aIter( *pPage
, IM_DEEPWITHGROUPS
);
158 while( aIter
.IsMore() )
160 SdrObject
* pPartObj
= aIter
.Next();
161 if ( pPartObj
->ISA( SdrEdgeObj
) )
163 if ( ( pPartObj
->GetConnectedNode( false ) == &rO
) ||
164 ( pPartObj
->GetConnectedNode( true ) == &rO
) )
166 vUndoActions
.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj
) );
175 void SdrEditView::AddUndoActions( std::vector
< SdrUndoAction
* >& rUndoActions
)
177 std::vector
< SdrUndoAction
* >::iterator
aUndoActionIter( rUndoActions
.begin() );
178 while( aUndoActionIter
!= rUndoActions
.end() )
179 AddUndo( *aUndoActionIter
++ );
182 void SdrEditView::MoveMarkedObj(const Size
& rSiz
, bool bCopy
)
184 const bool bUndo
= IsUndoEnabled();
188 OUString
aStr(ImpGetResStr(STR_EditMove
));
190 aStr
+= ImpGetResStr(STR_EditWithCopy
);
191 // meeds its own UndoGroup because of its parameters
192 BegUndo(aStr
,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE
);
198 const size_t nMarkCount
=GetMarkedObjectCount();
199 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
201 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
202 SdrObject
* pO
=pM
->GetMarkedSdrObj();
205 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pO
) );
206 AddUndoActions( vConnectorUndoActions
);
207 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO
,rSiz
));
216 void SdrEditView::ResizeMarkedObj(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bCopy
)
218 const bool bUndo
= IsUndoEnabled();
222 ImpTakeDescriptionStr(STR_EditResize
,aStr
);
224 aStr
+=ImpGetResStr(STR_EditWithCopy
);
231 const size_t nMarkCount
=GetMarkedObjectCount();
232 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
234 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
235 SdrObject
* pO
=pM
->GetMarkedSdrObj();
238 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pO
) );
239 AddUndoActions( vConnectorUndoActions
);
240 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
242 pO
->Resize(rRef
,xFact
,yFact
);
248 void SdrEditView::ResizeMultMarkedObj(const Point
& rRef
,
249 const Fraction
& xFact
,
250 const Fraction
& yFact
,
255 const bool bUndo
= IsUndoEnabled();
259 ImpTakeDescriptionStr(STR_EditResize
,aStr
);
261 aStr
+=ImpGetResStr(STR_EditWithCopy
);
268 const size_t nMarkCount
=GetMarkedObjectCount();
269 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
271 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
272 SdrObject
* pO
=pM
->GetMarkedSdrObj();
275 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pO
) );
276 AddUndoActions( vConnectorUndoActions
);
277 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
282 pO
->Resize(rRef
, xFact
, yFact
);
284 pO
->Resize(rRef
, xFact
, aFrac
);
286 pO
->Resize(rRef
, aFrac
, yFact
);
292 long SdrEditView::GetMarkedObjRotate() const
296 if(GetMarkedObjectCount())
298 SdrMark
* pM
= GetSdrMarkByIndex(0);
299 SdrObject
* pO
= pM
->GetMarkedSdrObj();
301 nRetval
= pO
->GetRotateAngle();
305 //sal_Bool b1st=true;
308 //sal_uIntPtr nMarkCount=GetMarkedObjectCount();
309 //for (sal_uIntPtr nm=0; nm<nMarkCount && bOk; nm++) {
310 // SdrMark* pM=GetSdrMarkByIndex(nm);
311 // SdrObject* pO=pM->GetMarkedSdrObj();
312 // long nAngle2=pO->GetRotateAngle();
313 // if (b1st) nAngle=nAngle2;
314 // else if (nAngle2!=nAngle) bOk=false;
317 //if (!bOk) nAngle=0;
321 void SdrEditView::RotateMarkedObj(const Point
& rRef
, long nAngle
, bool bCopy
)
323 const bool bUndo
= IsUndoEnabled();
327 ImpTakeDescriptionStr(STR_EditRotate
,aStr
);
328 if (bCopy
) aStr
+=ImpGetResStr(STR_EditWithCopy
);
335 double nSin
=sin(nAngle
*nPi180
);
336 double nCos
=cos(nAngle
*nPi180
);
337 const size_t nMarkCount(GetMarkedObjectCount());
341 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
343 for(size_t nm
= 0; nm
< nMarkCount
; ++nm
)
345 SdrMark
* pM
= GetSdrMarkByIndex(nm
);
346 SdrObject
* pO
= pM
->GetMarkedSdrObj();
350 // extra undo actions for changed connector which now may hold its laid out path (SJ)
351 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pO
) );
352 AddUndoActions( vConnectorUndoActions
);
354 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
357 // set up a scene updater if object is a 3d object
358 if(dynamic_cast< E3dObject
* >(pO
))
360 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pO
));
363 pO
->Rotate(rRef
,nAngle
,nSin
,nCos
);
366 // fire scene updaters
367 while(!aUpdaters
.empty())
369 delete aUpdaters
.back();
370 aUpdaters
.pop_back();
378 void SdrEditView::MirrorMarkedObj(const Point
& rRef1
, const Point
& rRef2
, bool bCopy
)
380 const bool bUndo
= IsUndoEnabled();
385 Point
aDif(rRef2
-rRef1
);
386 if (aDif
.X()==0) ImpTakeDescriptionStr(STR_EditMirrorHori
,aStr
);
387 else if (aDif
.Y()==0) ImpTakeDescriptionStr(STR_EditMirrorVert
,aStr
);
388 else if (std::abs(aDif
.X()) == std::abs(aDif
.Y())) ImpTakeDescriptionStr(STR_EditMirrorDiag
,aStr
);
389 else ImpTakeDescriptionStr(STR_EditMirrorFree
,aStr
);
390 if (bCopy
) aStr
+=ImpGetResStr(STR_EditWithCopy
);
397 const size_t nMarkCount(GetMarkedObjectCount());
401 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
403 for(size_t nm
= 0; nm
< nMarkCount
; ++nm
)
405 SdrMark
* pM
= GetSdrMarkByIndex(nm
);
406 SdrObject
* pO
= pM
->GetMarkedSdrObj();
410 // extra undo actions for changed connector which now may hold its laid out path (SJ)
411 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pO
) );
412 AddUndoActions( vConnectorUndoActions
);
414 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
417 // set up a scene updater if object is a 3d object
418 if(dynamic_cast< E3dObject
* >(pO
))
420 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pO
));
423 pO
->Mirror(rRef1
,rRef2
);
426 // fire scene updaters
427 while(!aUpdaters
.empty())
429 delete aUpdaters
.back();
430 aUpdaters
.pop_back();
438 void SdrEditView::MirrorMarkedObjHorizontal(bool bCopy
)
440 Point
aCenter(GetMarkedObjRect().Center());
443 MirrorMarkedObj(aCenter
,aPt2
,bCopy
);
446 void SdrEditView::MirrorMarkedObjVertical(bool bCopy
)
448 Point
aCenter(GetMarkedObjRect().Center());
451 MirrorMarkedObj(aCenter
,aPt2
,bCopy
);
454 long SdrEditView::GetMarkedObjShear() const
459 const size_t nMarkCount
=GetMarkedObjectCount();
460 for (size_t nm
=0; nm
<nMarkCount
&& bOk
; ++nm
) {
461 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
462 SdrObject
* pO
=pM
->GetMarkedSdrObj();
463 long nAngle2
=pO
->GetShearAngle();
464 if (b1st
) nAngle
=nAngle2
;
465 else if (nAngle2
!=nAngle
) bOk
=false;
468 if (nAngle
>SDRMAXSHEAR
) nAngle
=SDRMAXSHEAR
;
469 if (nAngle
<-SDRMAXSHEAR
) nAngle
=-SDRMAXSHEAR
;
474 void SdrEditView::ShearMarkedObj(const Point
& rRef
, long nAngle
, bool bVShear
, bool bCopy
)
476 const bool bUndo
= IsUndoEnabled();
481 ImpTakeDescriptionStr(STR_EditShear
,aStr
);
483 aStr
+=ImpGetResStr(STR_EditWithCopy
);
490 double nTan
=tan(nAngle
*nPi180
);
491 const size_t nMarkCount
=GetMarkedObjectCount();
492 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
494 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
495 SdrObject
* pO
=pM
->GetMarkedSdrObj();
498 std::vector
< SdrUndoAction
* > vConnectorUndoActions( CreateConnectorUndo( *pO
) );
499 AddUndoActions( vConnectorUndoActions
);
500 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
502 pO
->Shear(rRef
,nAngle
,nTan
,bVShear
);
509 void SdrEditView::ImpCrookObj(SdrObject
* pO
, const Point
& rRef
, const Point
& rRad
,
510 SdrCrookMode eMode
, bool bVertical
, bool bNoContortion
, bool bRotate
, const Rectangle
& rMarkRect
)
512 SdrPathObj
* pPath
=PTR_CAST(SdrPathObj
,pO
);
515 if(pPath
!=NULL
&& !bNoContortion
)
517 XPolyPolygon
aXPP(pPath
->GetPathPoly());
519 case SDRCROOK_ROTATE
: CrookRotatePoly (aXPP
,rRef
,rRad
,bVertical
); break;
520 case SDRCROOK_SLANT
: CrookSlantPoly (aXPP
,rRef
,rRad
,bVertical
); break;
521 case SDRCROOK_STRETCH
: CrookStretchPoly(aXPP
,rRef
,rRad
,bVertical
,rMarkRect
); break;
523 pPath
->SetPathPoly(aXPP
.getB2DPolyPolygon());
527 if(!bDone
&& !pPath
&& pO
->IsPolyObj() && 0L != pO
->GetPointCount())
529 // for PolyObj's, but NOT for SdrPathObj's, e.g. the measurement object
530 sal_uInt32
nPointCount(pO
->GetPointCount());
531 XPolygon
aXP((sal_uInt16
)nPointCount
);
534 for(nPtNum
= 0L; nPtNum
< nPointCount
; nPtNum
++)
536 Point
aPt(pO
->GetPoint(nPtNum
));
537 aXP
[(sal_uInt16
)nPtNum
]=aPt
;
542 case SDRCROOK_ROTATE
: CrookRotatePoly (aXP
,rRef
,rRad
,bVertical
); break;
543 case SDRCROOK_SLANT
: CrookSlantPoly (aXP
,rRef
,rRad
,bVertical
); break;
544 case SDRCROOK_STRETCH
: CrookStretchPoly(aXP
,rRef
,rRad
,bVertical
,rMarkRect
); break;
547 for(nPtNum
= 0L; nPtNum
< nPointCount
; nPtNum
++)
549 // broadcasting could be optimized here, but for the
550 // current two points of the measurement object, it's fine
551 pO
->SetPoint(aXP
[(sal_uInt16
)nPtNum
],nPtNum
);
559 // for all others or if bNoContortion
560 Point
aCtr0(pO
->GetSnapRect().Center());
563 double nSin(0.0), nCos(1.0);
566 if(0 != rRad
.X() && 0 != rRad
.Y())
572 case SDRCROOK_ROTATE
: nAngle
=CrookRotateXPoint (aCtr1
,NULL
,NULL
,rRef
,rRad
,nSin
,nCos
,bVertical
); bRotOk
=bRotate
; break;
573 case SDRCROOK_SLANT
: nAngle
=CrookSlantXPoint (aCtr1
,NULL
,NULL
,rRef
,rRad
,nSin
,nCos
,bVertical
); break;
574 case SDRCROOK_STRETCH
: nAngle
=CrookStretchXPoint(aCtr1
,NULL
,NULL
,rRef
,rRad
,nSin
,nCos
,bVertical
,rMarkRect
); break;
581 pO
->Rotate(aCtr0
, Round(nAngle
/nPi180
), nSin
, nCos
);
583 pO
->Move(Size(aCtr1
.X(),aCtr1
.Y()));
587 void SdrEditView::CrookMarkedObj(const Point
& rRef
, const Point
& rRad
, SdrCrookMode eMode
,
588 bool bVertical
, bool bNoContortion
, bool bCopy
)
590 Rectangle
aMarkRect(GetMarkedObjRect());
591 const bool bUndo
= IsUndoEnabled();
593 bool bRotate
=bNoContortion
&& eMode
==SDRCROOK_ROTATE
&& IsRotateAllowed(false);
598 ImpTakeDescriptionStr(bNoContortion
?STR_EditCrook
:STR_EditCrookContortion
,aStr
);
600 aStr
+=ImpGetResStr(STR_EditWithCopy
);
607 const size_t nMarkCount
=GetMarkedObjectCount();
608 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
610 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
611 SdrObject
* pO
=pM
->GetMarkedSdrObj();
613 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
615 const SdrObjList
* pOL
=pO
->GetSubList();
616 if (bNoContortion
|| pOL
==NULL
) {
617 ImpCrookObj(pO
,rRef
,rRad
,eMode
,bVertical
,bNoContortion
,bRotate
,aMarkRect
);
619 SdrObjListIter
aIter(*pOL
,IM_DEEPNOGROUPS
);
620 while (aIter
.IsMore()) {
621 SdrObject
* pO1
=aIter
.Next();
622 ImpCrookObj(pO1
,rRef
,rRad
,eMode
,bVertical
,bNoContortion
,bRotate
,aMarkRect
);
631 void SdrEditView::ImpDistortObj(SdrObject
* pO
, const Rectangle
& rRef
, const XPolygon
& rDistortedRect
, bool bNoContortion
)
633 SdrPathObj
* pPath
= PTR_CAST(SdrPathObj
, pO
);
635 if(!bNoContortion
&& pPath
)
637 XPolyPolygon
aXPP(pPath
->GetPathPoly());
638 aXPP
.Distort(rRef
, rDistortedRect
);
639 pPath
->SetPathPoly(aXPP
.getB2DPolyPolygon());
641 else if(pO
->IsPolyObj())
643 // e. g. for the measurement object
644 sal_uInt32
nPointCount(pO
->GetPointCount());
645 XPolygon
aXP((sal_uInt16
)nPointCount
);
648 for(nPtNum
= 0L; nPtNum
< nPointCount
; nPtNum
++)
650 Point
aPt(pO
->GetPoint(nPtNum
));
651 aXP
[(sal_uInt16
)nPtNum
]=aPt
;
654 aXP
.Distort(rRef
, rDistortedRect
);
656 for(nPtNum
= 0L; nPtNum
< nPointCount
; nPtNum
++)
658 // broadcasting could be optimized here, but for the
659 // current two points of the measurement object it's fine
660 pO
->SetPoint(aXP
[(sal_uInt16
)nPtNum
],nPtNum
);
665 void SdrEditView::DistortMarkedObj(const Rectangle
& rRef
, const XPolygon
& rDistortedRect
, bool bNoContortion
, bool bCopy
)
667 const bool bUndo
= IsUndoEnabled();
672 ImpTakeDescriptionStr(STR_EditDistort
,aStr
);
674 aStr
+=ImpGetResStr(STR_EditWithCopy
);
681 const size_t nMarkCount
=GetMarkedObjectCount();
682 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
684 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
685 SdrObject
* pO
=pM
->GetMarkedSdrObj();
687 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
689 Rectangle
aRefRect(rRef
);
690 XPolygon
aRefPoly(rDistortedRect
);
691 const SdrObjList
* pOL
=pO
->GetSubList();
692 if (bNoContortion
|| pOL
==NULL
) {
693 ImpDistortObj(pO
,aRefRect
,aRefPoly
,bNoContortion
);
695 SdrObjListIter
aIter(*pOL
,IM_DEEPNOGROUPS
);
696 while (aIter
.IsMore()) {
697 SdrObject
* pO1
=aIter
.Next();
698 ImpDistortObj(pO1
,aRefRect
,aRefPoly
,bNoContortion
);
708 void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet
& rAttr
, bool /*bReplaceAll*/)
710 // bReplaceAll has no effect here
711 Rectangle
aAllSnapRect(GetMarkedObjRect());
712 const SfxPoolItem
*pPoolItem
=NULL
;
713 if (rAttr
.GetItemState(SDRATTR_TRANSFORMREF1X
,true,&pPoolItem
)==SfxItemState::SET
) {
714 long n
=static_cast<const SdrTransformRef1XItem
*>(pPoolItem
)->GetValue();
715 SetRef1(Point(n
,GetRef1().Y()));
717 if (rAttr
.GetItemState(SDRATTR_TRANSFORMREF1Y
,true,&pPoolItem
)==SfxItemState::SET
) {
718 long n
=static_cast<const SdrTransformRef1YItem
*>(pPoolItem
)->GetValue();
719 SetRef1(Point(GetRef1().X(),n
));
721 if (rAttr
.GetItemState(SDRATTR_TRANSFORMREF2X
,true,&pPoolItem
)==SfxItemState::SET
) {
722 long n
=static_cast<const SdrTransformRef2XItem
*>(pPoolItem
)->GetValue();
723 SetRef2(Point(n
,GetRef2().Y()));
725 if (rAttr
.GetItemState(SDRATTR_TRANSFORMREF2Y
,true,&pPoolItem
)==SfxItemState::SET
) {
726 long n
=static_cast<const SdrTransformRef2YItem
*>(pPoolItem
)->GetValue();
727 SetRef2(Point(GetRef2().X(),n
));
729 long nAllPosX
=0; bool bAllPosX
=false;
730 long nAllPosY
=0; bool bAllPosY
=false;
731 long nAllWdt
=0; bool bAllWdt
=false;
732 long nAllHgt
=0; bool bAllHgt
=false;
734 if (rAttr
.GetItemState(SDRATTR_ALLPOSITIONX
,true,&pPoolItem
)==SfxItemState::SET
) {
735 nAllPosX
=static_cast<const SdrAllPositionXItem
*>(pPoolItem
)->GetValue();
736 bAllPosX
=true; bDoIt
=true;
738 if (rAttr
.GetItemState(SDRATTR_ALLPOSITIONY
,true,&pPoolItem
)==SfxItemState::SET
) {
739 nAllPosY
=static_cast<const SdrAllPositionYItem
*>(pPoolItem
)->GetValue();
740 bAllPosY
=true; bDoIt
=true;
742 if (rAttr
.GetItemState(SDRATTR_ALLSIZEWIDTH
,true,&pPoolItem
)==SfxItemState::SET
) {
743 nAllWdt
=static_cast<const SdrAllSizeWidthItem
*>(pPoolItem
)->GetValue();
744 bAllWdt
=true; bDoIt
=true;
746 if (rAttr
.GetItemState(SDRATTR_ALLSIZEHEIGHT
,true,&pPoolItem
)==SfxItemState::SET
) {
747 nAllHgt
=static_cast<const SdrAllSizeHeightItem
*>(pPoolItem
)->GetValue();
748 bAllHgt
=true; bDoIt
=true;
751 Rectangle
aRect(aAllSnapRect
); // TODO: change this for PolyPt's and GluePt's!!!
752 if (bAllPosX
) aRect
.Move(nAllPosX
-aRect
.Left(),0);
753 if (bAllPosY
) aRect
.Move(0,nAllPosY
-aRect
.Top());
754 if (bAllWdt
) aRect
.Right()=aAllSnapRect
.Left()+nAllWdt
;
755 if (bAllHgt
) aRect
.Bottom()=aAllSnapRect
.Top()+nAllHgt
;
756 SetMarkedObjRect(aRect
);
758 if (rAttr
.GetItemState(SDRATTR_RESIZEXALL
,true,&pPoolItem
)==SfxItemState::SET
) {
759 Fraction aXFact
=static_cast<const SdrResizeXAllItem
*>(pPoolItem
)->GetValue();
760 ResizeMarkedObj(aAllSnapRect
.TopLeft(),aXFact
,Fraction(1,1));
762 if (rAttr
.GetItemState(SDRATTR_RESIZEYALL
,true,&pPoolItem
)==SfxItemState::SET
) {
763 Fraction aYFact
=static_cast<const SdrResizeYAllItem
*>(pPoolItem
)->GetValue();
764 ResizeMarkedObj(aAllSnapRect
.TopLeft(),Fraction(1,1),aYFact
);
766 if (rAttr
.GetItemState(SDRATTR_ROTATEALL
,true,&pPoolItem
)==SfxItemState::SET
) {
767 long nAngle
=static_cast<const SdrRotateAllItem
*>(pPoolItem
)->GetValue();
768 RotateMarkedObj(aAllSnapRect
.Center(),nAngle
);
770 if (rAttr
.GetItemState(SDRATTR_HORZSHEARALL
,true,&pPoolItem
)==SfxItemState::SET
) {
771 long nAngle
=static_cast<const SdrHorzShearAllItem
*>(pPoolItem
)->GetValue();
772 ShearMarkedObj(aAllSnapRect
.Center(),nAngle
,false);
774 if (rAttr
.GetItemState(SDRATTR_VERTSHEARALL
,true,&pPoolItem
)==SfxItemState::SET
) {
775 long nAngle
=static_cast<const SdrVertShearAllItem
*>(pPoolItem
)->GetValue();
776 ShearMarkedObj(aAllSnapRect
.Center(),nAngle
,true);
779 const bool bUndo
= IsUndoEnabled();
781 // TODO: check if WhichRange is necessary.
782 const size_t nMarkCount
=GetMarkedObjectCount();
783 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
785 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
786 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
788 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
790 pObj
->ApplyNotPersistAttr(rAttr
);
794 void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet
& rAttr
, bool /*bOnlyHardAttr*/) const
796 // bOnlyHardAttr has no effect here.
797 // TODO: Take into account the origin and PvPos.
798 Rectangle
aAllSnapRect(GetMarkedObjRect()); // TODO: change this for PolyPt's and GluePt's!!!
799 long nAllSnapPosX
=aAllSnapRect
.Left();
800 long nAllSnapPosY
=aAllSnapRect
.Top();
801 long nAllSnapWdt
=aAllSnapRect
.GetWidth()-1;
802 long nAllSnapHgt
=aAllSnapRect
.GetHeight()-1;
803 // TODO: could go into CheckPossibilities
804 bool bMovProtect
= false, bMovProtectDC
= false;
805 bool bSizProtect
= false, bSizProtectDC
= false;
806 bool bPrintable
= true, bPrintableDC
= false;
807 bool bVisible
= true, bVisibleDC
= false;
808 SdrLayerID nLayerId
=0; bool bLayerDC
=false;
810 bool bObjNameDC
=false,bObjNameSet
=false;
811 long nSnapPosX
=0; bool bSnapPosXDC
=false;
812 long nSnapPosY
=0; bool bSnapPosYDC
=false;
813 long nSnapWdt
=0; bool bSnapWdtDC
=false;
814 long nSnapHgt
=0; bool bSnapHgtDC
=false;
815 long nLogicWdt
=0; bool bLogicWdtDC
=false,bLogicWdtDiff
=false;
816 long nLogicHgt
=0; bool bLogicHgtDC
=false,bLogicHgtDiff
=false;
817 long nRotAngle
=0; bool bRotAngleDC
=false;
818 long nShrAngle
=0; bool bShrAngleDC
=false;
820 Rectangle aLogicRect
;
821 const size_t nMarkCount
=GetMarkedObjectCount();
822 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
823 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
824 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
826 nLayerId
=pObj
->GetLayer();
827 bMovProtect
=pObj
->IsMoveProtect();
828 bSizProtect
=pObj
->IsResizeProtect();
829 bPrintable
=pObj
->IsPrintable();
830 bVisible
= pObj
->IsVisible();
831 Rectangle
aSnapRect2(pObj
->GetSnapRect());
832 Rectangle
aLogicRect2(pObj
->GetLogicRect());
833 nSnapPosX
=aSnapRect2
.Left();
834 nSnapPosY
=aSnapRect2
.Top();
835 nSnapWdt
=aSnapRect2
.GetWidth()-1;
836 nSnapHgt
=aSnapRect2
.GetHeight()-1;
837 nLogicWdt
=aLogicRect2
.GetWidth()-1;
838 nLogicHgt
=aLogicRect2
.GetHeight()-1;
839 bLogicWdtDiff
=nLogicWdt
!=nSnapWdt
;
840 bLogicHgtDiff
=nLogicHgt
!=nSnapHgt
;
841 nRotAngle
=pObj
->GetRotateAngle();
842 nShrAngle
=pObj
->GetShearAngle();
844 if (!bLayerDC
&& nLayerId
!=pObj
->GetLayer()) bLayerDC
= true;
845 if (!bMovProtectDC
&& bMovProtect
!=pObj
->IsMoveProtect()) bMovProtectDC
= true;
846 if (!bSizProtectDC
&& bSizProtect
!=pObj
->IsResizeProtect()) bSizProtectDC
= true;
847 if (!bPrintableDC
&& bPrintable
!=pObj
->IsPrintable()) bPrintableDC
= true;
848 if (!bVisibleDC
&& bVisible
!=pObj
->IsVisible()) bVisibleDC
=true;
849 if (!bRotAngleDC
&& nRotAngle
!=pObj
->GetRotateAngle()) bRotAngleDC
=true;
850 if (!bShrAngleDC
&& nShrAngle
!=pObj
->GetShearAngle()) bShrAngleDC
=true;
851 if (!bSnapWdtDC
|| !bSnapHgtDC
|| !bSnapPosXDC
|| !bSnapPosYDC
|| !bLogicWdtDiff
|| !bLogicHgtDiff
) {
852 aSnapRect
=pObj
->GetSnapRect();
853 if (nSnapPosX
!=aSnapRect
.Left()) bSnapPosXDC
=true;
854 if (nSnapPosY
!=aSnapRect
.Top()) bSnapPosYDC
=true;
855 if (nSnapWdt
!=aSnapRect
.GetWidth()-1) bSnapWdtDC
=true;
856 if (nSnapHgt
!=aSnapRect
.GetHeight()-1) bSnapHgtDC
=true;
858 if (!bLogicWdtDC
|| !bLogicHgtDC
|| !bLogicWdtDiff
|| !bLogicHgtDiff
) {
859 aLogicRect
=pObj
->GetLogicRect();
860 if (nLogicWdt
!=aLogicRect
.GetWidth()-1) bLogicWdtDC
=true;
861 if (nLogicHgt
!=aLogicRect
.GetHeight()-1) bLogicHgtDC
=true;
862 if (!bLogicWdtDiff
&& aSnapRect
.GetWidth()!=aLogicRect
.GetWidth()) bLogicWdtDiff
=true;
863 if (!bLogicHgtDiff
&& aSnapRect
.GetHeight()!=aLogicRect
.GetHeight()) bLogicHgtDiff
=true;
868 aObjName
=pObj
->GetName();
870 if (!aObjName
.equals(pObj
->GetName()))
876 if (bSnapPosXDC
|| nAllSnapPosX
!=nSnapPosX
) rAttr
.Put(SdrAllPositionXItem(nAllSnapPosX
));
877 if (bSnapPosYDC
|| nAllSnapPosY
!=nSnapPosY
) rAttr
.Put(SdrAllPositionYItem(nAllSnapPosY
));
878 if (bSnapWdtDC
|| nAllSnapWdt
!=nSnapWdt
) rAttr
.Put(SdrAllSizeWidthItem(nAllSnapWdt
));
879 if (bSnapHgtDC
|| nAllSnapHgt
!=nSnapHgt
) rAttr
.Put(SdrAllSizeHeightItem(nAllSnapHgt
));
881 // items for pure transformations
882 rAttr
.Put(SdrMoveXItem());
883 rAttr
.Put(SdrMoveYItem());
884 rAttr
.Put(SdrResizeXOneItem());
885 rAttr
.Put(SdrResizeYOneItem());
886 rAttr
.Put(SdrRotateOneItem());
887 rAttr
.Put(SdrHorzShearOneItem());
888 rAttr
.Put(SdrVertShearOneItem());
891 rAttr
.Put(SdrResizeXAllItem());
892 rAttr
.Put(SdrResizeYAllItem());
893 rAttr
.Put(SdrRotateAllItem());
894 rAttr
.Put(SdrHorzShearAllItem());
895 rAttr
.Put(SdrVertShearAllItem());
898 if(eDragMode
== SDRDRAG_ROTATE
|| eDragMode
== SDRDRAG_MIRROR
)
900 rAttr
.Put(SdrTransformRef1XItem(GetRef1().X()));
901 rAttr
.Put(SdrTransformRef1YItem(GetRef1().Y()));
904 if(eDragMode
== SDRDRAG_MIRROR
)
906 rAttr
.Put(SdrTransformRef2XItem(GetRef2().X()));
907 rAttr
.Put(SdrTransformRef2YItem(GetRef2().Y()));
911 SfxItemSet
SdrEditView::GetAttrFromMarked(bool bOnlyHardAttr
) const
913 SfxItemSet
aSet(pMod
->GetItemPool());
914 MergeAttrFromMarked(aSet
,bOnlyHardAttr
);
915 //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there)
916 //so we do not set them here
918 // Do not disable, but clear the items.
919 aSet
.ClearItem(EE_FEATURE_TAB
);
920 aSet
.ClearItem(EE_FEATURE_LINEBR
);
921 aSet
.ClearItem(EE_FEATURE_NOTCONV
);
922 aSet
.ClearItem(EE_FEATURE_FIELD
);
926 void SdrEditView::MergeAttrFromMarked(SfxItemSet
& rAttr
, bool bOnlyHardAttr
) const
928 const size_t nMarkCount(GetMarkedObjectCount());
930 for(size_t a
= 0; a
< nMarkCount
; ++a
)
932 // #80277# merging was done wrong in the prev version
933 const SfxItemSet
& rSet
= GetMarkedObjectByIndex(a
)->GetMergedItemSet();
934 SfxWhichIter
aIter(rSet
);
935 sal_uInt16
nWhich(aIter
.FirstWhich());
941 if(SfxItemState::DONTCARE
== rSet
.GetItemState(nWhich
, false))
942 rAttr
.InvalidateItem(nWhich
);
944 rAttr
.MergeValue(rSet
.Get(nWhich
), true);
946 else if(SfxItemState::SET
== rSet
.GetItemState(nWhich
, false))
948 const SfxPoolItem
& rItem
= rSet
.Get(nWhich
);
949 rAttr
.MergeValue(rItem
, true);
952 nWhich
= aIter
.NextWhich();
957 std::vector
<sal_uInt16
> GetAllCharPropIds(const SfxItemSet
& rSet
)
959 std::vector
<sal_uInt16
> aCharWhichIds
;
961 SfxItemIter
aIter(rSet
);
962 const SfxPoolItem
* pItem
=aIter
.FirstItem();
965 if (!IsInvalidItem(pItem
))
967 sal_uInt16 nWhich
= pItem
->Which();
968 if (nWhich
>=EE_CHAR_START
&& nWhich
<=EE_CHAR_END
)
969 aCharWhichIds
.push_back( nWhich
);
971 pItem
=aIter
.NextItem();
974 return aCharWhichIds
;
977 void SdrEditView::SetAttrToMarked(const SfxItemSet
& rAttr
, bool bReplaceAll
)
979 if (AreObjectsMarked())
983 bool bHasEEFeatureItems
=false;
984 SfxItemIter
aIter(rAttr
);
985 const SfxPoolItem
* pItem
=aIter
.FirstItem();
986 while (!bHasEEFeatureItems
&& pItem
!=NULL
) {
987 if (!IsInvalidItem(pItem
)) {
988 sal_uInt16 nW
=pItem
->Which();
989 if (nW
>=EE_FEATURE_START
&& nW
<=EE_FEATURE_END
) bHasEEFeatureItems
=true;
991 pItem
=aIter
.NextItem();
993 if(bHasEEFeatureItems
)
995 OUString
aMessage("SdrEditView::SetAttrToMarked(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents.");
996 ScopedVclPtr
<InfoBox
>::Create(nullptr, aMessage
)->Execute();
1001 // #103836# if the user sets character attributes to the complete shape,
1002 // we want to remove all hard set character attributes with same
1003 // which ids from the text. We do that later but here we remember
1004 // all character attribute which id's that are set.
1005 std::vector
<sal_uInt16
> aCharWhichIds(GetAllCharPropIds(rAttr
));
1007 // To make Undo reconstruct text attributes correctly after Format.Standard
1008 bool bHasEEItems
=SearchOutlinerItems(rAttr
,bReplaceAll
);
1010 // save additional geometry information when paragraph or character attributes
1011 // are changed and the geometrical shape of the text object might be changed
1012 bool bPossibleGeomChange(false);
1013 SfxWhichIter
aIter(rAttr
);
1014 sal_uInt16 nWhich
= aIter
.FirstWhich();
1015 while(!bPossibleGeomChange
&& nWhich
)
1017 SfxItemState eState
= rAttr
.GetItemState(nWhich
);
1018 if(eState
== SfxItemState::SET
)
1020 if((nWhich
>= SDRATTR_TEXT_MINFRAMEHEIGHT
&& nWhich
<= SDRATTR_TEXT_CONTOURFRAME
)
1021 || nWhich
== SDRATTR_3DOBJ_PERCENT_DIAGONAL
1022 || nWhich
== SDRATTR_3DOBJ_BACKSCALE
1023 || nWhich
== SDRATTR_3DOBJ_DEPTH
1024 || nWhich
== SDRATTR_3DOBJ_END_ANGLE
1025 || nWhich
== SDRATTR_3DSCENE_DISTANCE
)
1027 bPossibleGeomChange
= true;
1030 nWhich
= aIter
.NextWhich();
1033 const bool bUndo
= IsUndoEnabled();
1037 ImpTakeDescriptionStr(STR_EditSetAttributes
,aStr
);
1041 const size_t nMarkCount(GetMarkedObjectCount());
1042 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
1044 // create ItemSet without SfxItemState::DONTCARE. Put()
1045 // uses its second parameter (bInvalidAsDefault) to
1046 // remove all such items to set them to default.
1047 SfxItemSet
aAttr(*rAttr
.GetPool(), rAttr
.GetRanges());
1048 aAttr
.Put(rAttr
, true);
1051 bool bResetAnimationTimer(false);
1053 // check if LineWidth is part of the change
1054 const bool bLineWidthChange(SfxItemState::SET
== aAttr
.GetItemState(XATTR_LINEWIDTH
));
1055 sal_Int32
nNewLineWidth(0);
1056 sal_Int32
nOldLineWidth(0);
1058 if(bLineWidthChange
)
1060 nNewLineWidth
= static_cast<const XLineWidthItem
&>(aAttr
.Get(XATTR_LINEWIDTH
)).GetValue();
1063 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1065 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1066 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
1070 std::vector
< SdrUndoAction
* > vConnectorUndoActions
;
1071 SdrEdgeObj
* pEdgeObj
= dynamic_cast< SdrEdgeObj
* >( pObj
);
1073 bPossibleGeomChange
= true;
1075 vConnectorUndoActions
= CreateConnectorUndo( *pObj
);
1077 AddUndoActions( vConnectorUndoActions
);
1080 // new geometry undo
1081 if(bPossibleGeomChange
&& bUndo
)
1083 // save position and size of object, too
1084 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
1090 // If this is a text object also rescue the OutlinerParaObject since
1091 // applying attributes to the object may change text layout when
1092 // multiple portions exist with multiple formats. If a OutlinerParaObject
1093 // really exists and needs to be rescued is evaluated in the undo
1094 // implementation itself.
1095 const bool bRescueText
= dynamic_cast< SdrTextObj
* >(pObj
) != 0;
1097 // add attribute undo
1098 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj
,false,bHasEEItems
|| bPossibleGeomChange
|| bRescueText
));
1101 // set up a scene updater if object is a 3d object
1102 if(dynamic_cast< E3dObject
* >(pObj
))
1104 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pObj
));
1107 if(bLineWidthChange
)
1109 nOldLineWidth
= static_cast<const XLineWidthItem
&>(pObj
->GetMergedItem(XATTR_LINEWIDTH
)).GetValue();
1112 // set attributes at object
1113 pObj
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
1115 if(bLineWidthChange
)
1117 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
1119 if(nOldLineWidth
!= nNewLineWidth
)
1121 if(SfxItemState::DONTCARE
!= rSet
.GetItemState(XATTR_LINESTARTWIDTH
))
1123 const sal_Int32
nValAct(static_cast<const XLineStartWidthItem
&>(rSet
.Get(XATTR_LINESTARTWIDTH
)).GetValue());
1124 const sal_Int32
nValNewStart(std::max((sal_Int32
)0, nValAct
+ (((nNewLineWidth
- nOldLineWidth
) * 15) / 10)));
1126 pObj
->SetMergedItem(XLineStartWidthItem(nValNewStart
));
1129 if(SfxItemState::DONTCARE
!= rSet
.GetItemState(XATTR_LINEENDWIDTH
))
1131 const sal_Int32
nValAct(static_cast<const XLineEndWidthItem
&>(rSet
.Get(XATTR_LINEENDWIDTH
)).GetValue());
1132 const sal_Int32
nValNewEnd(std::max((sal_Int32
)0, nValAct
+ (((nNewLineWidth
- nOldLineWidth
) * 15) / 10)));
1134 pObj
->SetMergedItem(XLineEndWidthItem(nValNewEnd
));
1139 if(pObj
->ISA(SdrTextObj
))
1141 SdrTextObj
* pTextObj
= static_cast<SdrTextObj
*>(pObj
);
1143 if(!aCharWhichIds
.empty())
1145 Rectangle aOldBoundRect
= pTextObj
->GetLastBoundRect();
1147 // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect());
1148 pTextObj
->RemoveOutlinerCharacterAttribs( aCharWhichIds
);
1150 // object has changed, should be called from
1151 // RemoveOutlinerCharacterAttribs. This will change when the text
1152 // object implementation changes.
1153 pTextObj
->SetChanged();
1155 pTextObj
->BroadcastObjectChange();
1156 pTextObj
->SendUserCall(SDRUSERCALL_CHGATTR
, aOldBoundRect
);
1161 if(!bResetAnimationTimer
)
1163 if(pObj
->GetViewContact().isAnimatedInAnyViewObjectContact())
1165 bResetAnimationTimer
= true;
1170 // fire scene updaters
1171 while(!aUpdaters
.empty())
1173 delete aUpdaters
.back();
1174 aUpdaters
.pop_back();
1178 if(bResetAnimationTimer
)
1180 SetAnimationTimer(0L);
1183 // better check before what to do:
1184 // pObj->SetAttr() or SetNotPersistAttr()
1185 // TODO: missing implementation!
1186 SetNotPersistAttrToMarked(rAttr
,bReplaceAll
);
1193 SfxStyleSheet
* SdrEditView::GetStyleSheetFromMarked() const
1195 SfxStyleSheet
* pRet
=NULL
;
1197 const size_t nMarkCount
=GetMarkedObjectCount();
1198 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
1199 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1200 SfxStyleSheet
* pSS
=pM
->GetMarkedSdrObj()->GetStyleSheet();
1202 else if (pRet
!=pSS
) return NULL
; // different stylesheets
1208 void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1210 if (AreObjectsMarked())
1212 const bool bUndo
= IsUndoEnabled();
1217 if (pStyleSheet
!=NULL
)
1218 ImpTakeDescriptionStr(STR_EditSetStylesheet
,aStr
);
1220 ImpTakeDescriptionStr(STR_EditDelStylesheet
,aStr
);
1224 const size_t nMarkCount
=GetMarkedObjectCount();
1225 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1227 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1230 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM
->GetMarkedSdrObj()));
1231 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM
->GetMarkedSdrObj(),true,true));
1233 pM
->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1243 bool SdrEditView::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
1245 if(GetMarkedObjectCount())
1247 rTargetSet
.Put(GetAttrFromMarked(bOnlyHardAttr
), false);
1252 return SdrMarkView::GetAttributes(rTargetSet
, bOnlyHardAttr
);
1256 bool SdrEditView::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
1258 if (GetMarkedObjectCount()!=0) {
1259 SetAttrToMarked(rSet
,bReplaceAll
);
1262 return SdrMarkView::SetAttributes(rSet
,bReplaceAll
);
1266 SfxStyleSheet
* SdrEditView::GetStyleSheet() const
1268 if (GetMarkedObjectCount()!=0) {
1269 return GetStyleSheetFromMarked();
1271 return SdrMarkView::GetStyleSheet();
1275 bool SdrEditView::SetStyleSheet(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1277 if (GetMarkedObjectCount()!=0) {
1278 SetStyleSheetToMarked(pStyleSheet
,bDontRemoveHardAttr
);
1281 return SdrMarkView::SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1287 SfxItemSet
SdrEditView::GetGeoAttrFromMarked() const
1289 SfxItemSet
aRetSet(pMod
->GetItemPool(), // SID_ATTR_TRANSFORM_... from s:svxids.hrc
1290 SID_ATTR_TRANSFORM_POS_X
, SID_ATTR_TRANSFORM_ANGLE
,
1291 SID_ATTR_TRANSFORM_PROTECT_POS
, SID_ATTR_TRANSFORM_AUTOHEIGHT
,
1292 SDRATTR_ECKENRADIUS
, SDRATTR_ECKENRADIUS
,
1295 if (AreObjectsMarked())
1297 SfxItemSet
aMarkAttr(GetAttrFromMarked(false)); // because of AutoGrowHeight and corner radius
1298 Rectangle
aRect(GetMarkedObjRect());
1299 // restore position to that before calc hack
1300 aRect
-= GetGridOffset();
1302 if(GetSdrPageView())
1304 GetSdrPageView()->LogicToPagePos(aRect
);
1308 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X
,aRect
.Left()));
1309 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y
,aRect
.Top()));
1312 long nResizeRefX
=aRect
.Left();
1313 long nResizeRefY
=aRect
.Top();
1314 if (eDragMode
==SDRDRAG_ROTATE
) { // use rotation axis as a reference for resizing, too
1315 nResizeRefX
=aRef1
.X();
1316 nResizeRefY
=aRef1
.Y();
1318 aRetSet
.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH
,aRect
.Right()-aRect
.Left()));
1319 aRetSet
.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT
,aRect
.Bottom()-aRect
.Top()));
1320 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X
,nResizeRefX
));
1321 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y
,nResizeRefY
));
1323 Point
aRotateAxe(aRef1
);
1325 if(GetSdrPageView())
1327 GetSdrPageView()->LogicToPagePos(aRotateAxe
);
1331 long nRotateRefX
=aRect
.Center().X();
1332 long nRotateRefY
=aRect
.Center().Y();
1333 if (eDragMode
==SDRDRAG_ROTATE
) {
1334 nRotateRefX
=aRotateAxe
.X();
1335 nRotateRefY
=aRotateAxe
.Y();
1337 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE
,GetMarkedObjRotate()));
1338 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X
,nRotateRefX
));
1339 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y
,nRotateRefY
));
1342 long nShearRefX
=aRect
.Left();
1343 long nShearRefY
=aRect
.Bottom();
1344 if (eDragMode
==SDRDRAG_ROTATE
) { // use rotation axis as a reference for shearing, too
1345 nShearRefX
=aRotateAxe
.X();
1346 nShearRefY
=aRotateAxe
.Y();
1348 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR
,GetMarkedObjShear()));
1349 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X
,nShearRefX
));
1350 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y
,nShearRefY
));
1352 // check every object whether it is protected
1353 const SdrMarkList
& rMarkList
=GetMarkedObjectList();
1354 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1355 SdrObject
* pObj
=rMarkList
.GetMark(0)->GetMarkedSdrObj();
1356 bool bPosProt
=pObj
->IsMoveProtect();
1357 bool bSizProt
=pObj
->IsResizeProtect();
1358 bool bPosProtDontCare
=false;
1359 bool bSizProtDontCare
=false;
1360 for (size_t i
=1; i
<nMarkCount
&& (!bPosProtDontCare
|| !bSizProtDontCare
); ++i
)
1362 pObj
=rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1363 if (bPosProt
!=pObj
->IsMoveProtect()) bPosProtDontCare
=true;
1364 if (bSizProt
!=pObj
->IsResizeProtect()) bSizProtDontCare
=true;
1367 // InvalidateItem sets item to DONT_CARE
1368 if (bPosProtDontCare
) {
1369 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS
);
1371 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS
,bPosProt
));
1373 if (bSizProtDontCare
) {
1374 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE
);
1376 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE
,bSizProt
));
1379 SfxItemState eState
=aMarkAttr
.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH
);
1380 bool bAutoGrow
=static_cast<const SdrOnOffItem
&>(aMarkAttr
.Get(SDRATTR_TEXT_AUTOGROWWIDTH
)).GetValue();
1381 if (eState
==SfxItemState::DONTCARE
) {
1382 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH
);
1383 } else if (eState
==SfxItemState::SET
) {
1384 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH
,bAutoGrow
));
1387 eState
=aMarkAttr
.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT
);
1388 bAutoGrow
=static_cast<const SdrOnOffItem
&>(aMarkAttr
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
)).GetValue();
1389 if (eState
==SfxItemState::DONTCARE
) {
1390 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT
);
1391 } else if (eState
==SfxItemState::SET
) {
1392 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT
,bAutoGrow
));
1395 eState
=aMarkAttr
.GetItemState(SDRATTR_ECKENRADIUS
);
1396 long nRadius
=static_cast<const SdrMetricItem
&>(aMarkAttr
.Get(SDRATTR_ECKENRADIUS
)).GetValue();
1397 if (eState
==SfxItemState::DONTCARE
) {
1398 aRetSet
.InvalidateItem(SDRATTR_ECKENRADIUS
);
1399 } else if (eState
==SfxItemState::SET
) {
1400 aRetSet
.Put(makeSdrEckenradiusItem(nRadius
));
1403 basegfx::B2DHomMatrix aTransformation
;
1407 // multiple objects, range is collected in aRect
1408 aTransformation
= basegfx::tools::createScaleTranslateB2DHomMatrix(
1409 aRect
.Left(), aRect
.Top(),
1410 aRect
.getWidth(), aRect
.getHeight());
1414 // single object, get homogen transformation
1415 basegfx::B2DPolyPolygon aPolyPolygon
;
1417 pObj
->TRGetBaseGeometry(aTransformation
, aPolyPolygon
);
1420 if(aTransformation
.isIdentity())
1422 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_MATRIX
);
1426 com::sun::star::geometry::AffineMatrix2D aAffineMatrix2D
;
1427 Point
aPageOffset(0, 0);
1429 if(GetSdrPageView())
1431 aPageOffset
= GetSdrPageView()->GetPageOrigin();
1434 aAffineMatrix2D
.m00
= aTransformation
.get(0, 0);
1435 aAffineMatrix2D
.m01
= aTransformation
.get(0, 1);
1436 aAffineMatrix2D
.m02
= aTransformation
.get(0, 2) - aPageOffset
.X();
1437 aAffineMatrix2D
.m10
= aTransformation
.get(1, 0);
1438 aAffineMatrix2D
.m11
= aTransformation
.get(1, 1);
1439 aAffineMatrix2D
.m12
= aTransformation
.get(1, 2) - aPageOffset
.Y();
1441 aRetSet
.Put(AffineMatrixItem(&aAffineMatrix2D
));
1448 Point
ImpGetPoint(const Rectangle
& rRect
, RECT_POINT eRP
)
1451 case RP_LT
: return rRect
.TopLeft();
1452 case RP_MT
: return rRect
.TopCenter();
1453 case RP_RT
: return rRect
.TopRight();
1454 case RP_LM
: return rRect
.LeftCenter();
1455 case RP_MM
: return rRect
.Center();
1456 case RP_RM
: return rRect
.RightCenter();
1457 case RP_LB
: return rRect
.BottomLeft();
1458 case RP_MB
: return rRect
.BottomCenter();
1459 case RP_RB
: return rRect
.BottomRight();
1461 return Point(); // Should not happen!
1464 void SdrEditView::SetGeoAttrToMarked(const SfxItemSet
& rAttr
)
1466 Rectangle
aRect(GetMarkedObjRect());
1468 if(GetSdrPageView())
1470 GetSdrPageView()->LogicToPagePos(aRect
);
1473 long nOldRotateAngle
=GetMarkedObjRotate();
1474 long nOldShearAngle
=GetMarkedObjShear();
1475 const SdrMarkList
& rMarkList
=GetMarkedObjectList();
1476 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1477 SdrObject
* pObj
=NULL
;
1479 RECT_POINT eSizePoint
=RP_MM
;
1484 long nRotateAngle
=0;
1486 bool bModeIsRotate(eDragMode
== SDRDRAG_ROTATE
);
1489 long nOldRotateX(0);
1490 long nOldRotateY(0);
1493 Point
aRotateAxe(aRef1
);
1495 if(GetSdrPageView())
1497 GetSdrPageView()->LogicToPagePos(aRotateAxe
);
1500 nRotateX
= nOldRotateX
= aRotateAxe
.X();
1501 nRotateY
= nOldRotateY
= aRotateAxe
.Y();
1507 bool bShearVert
=false;
1516 bool bSetAttr
=false;
1517 SfxItemSet
aSetAttr(pMod
->GetItemPool());
1519 const SfxPoolItem
* pPoolItem
=NULL
;
1522 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_POS_X
,true,&pPoolItem
)) {
1523 nPosDX
=static_cast<const SfxInt32Item
*>(pPoolItem
)->GetValue()-aRect
.Left();
1526 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_POS_Y
,true,&pPoolItem
)){
1527 nPosDY
=static_cast<const SfxInt32Item
*>(pPoolItem
)->GetValue()-aRect
.Top();
1531 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_WIDTH
,true,&pPoolItem
)) {
1532 nSizX
=static_cast<const SfxUInt32Item
*>(pPoolItem
)->GetValue();
1536 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_HEIGHT
,true,&pPoolItem
)) {
1537 nSizY
=static_cast<const SfxUInt32Item
*>(pPoolItem
)->GetValue();
1542 eSizePoint
=(RECT_POINT
)static_cast<const SfxAllEnumItem
&>(rAttr
.Get(SID_ATTR_TRANSFORM_SIZE_POINT
)).GetValue();
1546 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_ANGLE
,true,&pPoolItem
)) {
1547 nRotateAngle
=static_cast<const SfxInt32Item
*>(pPoolItem
)->GetValue()-nOldRotateAngle
;
1548 bRotate
= (nRotateAngle
!= 0);
1551 // position rotation point x
1552 if(bRotate
|| SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_ROT_X
, true ,&pPoolItem
))
1553 nRotateX
= static_cast<const SfxInt32Item
&>(rAttr
.Get(SID_ATTR_TRANSFORM_ROT_X
)).GetValue();
1555 // position rotation point y
1556 if(bRotate
|| SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_ROT_Y
, true ,&pPoolItem
))
1557 nRotateY
= static_cast<const SfxInt32Item
&>(rAttr
.Get(SID_ATTR_TRANSFORM_ROT_Y
)).GetValue();
1560 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_SHEAR
,true,&pPoolItem
)) {
1561 long nNewShearAngle
=static_cast<const SfxInt32Item
*>(pPoolItem
)->GetValue();
1562 if (nNewShearAngle
>SDRMAXSHEAR
) nNewShearAngle
=SDRMAXSHEAR
;
1563 if (nNewShearAngle
<-SDRMAXSHEAR
) nNewShearAngle
=-SDRMAXSHEAR
;
1564 if (nNewShearAngle
!=nOldShearAngle
) {
1565 bShearVert
=static_cast<const SfxBoolItem
&>(rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL
)).GetValue();
1567 nShearAngle
=nNewShearAngle
;
1569 if (nNewShearAngle
!=0 && nOldShearAngle
!=0) {
1571 double nOld
=tan((double)nOldShearAngle
*nPi180
);
1572 double nNew
=tan((double)nNewShearAngle
*nPi180
);
1574 nNew
=atan(nNew
)/nPi180
;
1575 nShearAngle
=Round(nNew
);
1577 nShearAngle
=nNewShearAngle
-nOldShearAngle
;
1580 bShear
=nShearAngle
!=0;
1582 nShearX
=static_cast<const SfxInt32Item
&>(rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_X
)).GetValue();
1583 nShearY
=static_cast<const SfxInt32Item
&>(rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_Y
)).GetValue();
1589 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH
,true,&pPoolItem
)) {
1590 bool bAutoGrow
=static_cast<const SfxBoolItem
*>(pPoolItem
)->GetValue();
1591 aSetAttr
.Put(makeSdrTextAutoGrowWidthItem(bAutoGrow
));
1595 if (SfxItemState::SET
==rAttr
.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT
,true,&pPoolItem
)) {
1596 bool bAutoGrow
=static_cast<const SfxBoolItem
*>(pPoolItem
)->GetValue();
1597 aSetAttr
.Put(makeSdrTextAutoGrowHeightItem(bAutoGrow
));
1602 if (bEdgeRadiusAllowed
&& SfxItemState::SET
==rAttr
.GetItemState(SDRATTR_ECKENRADIUS
,true,&pPoolItem
)) {
1603 long nRadius
=static_cast<const SdrMetricItem
*>(pPoolItem
)->GetValue();
1604 aSetAttr
.Put(makeSdrEckenradiusItem(nRadius
));
1608 ForcePossibilities();
1610 BegUndo(ImpGetResStr(STR_EditTransform
),GetDescriptionOfMarkedObjects());
1613 SetAttrToMarked(aSetAttr
,false);
1616 // change size and height
1617 if (bChgSiz
&& (bResizeFreeAllowed
|| bResizePropAllowed
)) {
1618 Fraction
aWdt(nSizX
,aRect
.Right()-aRect
.Left());
1619 Fraction
aHgt(nSizY
,aRect
.Bottom()-aRect
.Top());
1620 Point
aRef(ImpGetPoint(aRect
,eSizePoint
));
1622 if(GetSdrPageView())
1624 GetSdrPageView()->PagePosToLogic(aRef
);
1627 ResizeMultMarkedObj(aRef
, aWdt
, aHgt
, false, bChgWdh
, bChgHgt
);
1631 if (bRotate
&& (bRotateFreeAllowed
|| bRotate90Allowed
)) {
1632 Point
aRef(nRotateX
,nRotateY
);
1634 if(GetSdrPageView())
1636 GetSdrPageView()->PagePosToLogic(aRef
);
1639 RotateMarkedObj(aRef
,nRotateAngle
);
1642 // set rotation point position
1643 if(bModeIsRotate
&& (nRotateX
!= nOldRotateX
|| nRotateY
!= nOldRotateY
))
1645 Point
aNewRef1(nRotateX
, nRotateY
);
1647 if(GetSdrPageView())
1649 GetSdrPageView()->PagePosToLogic(aNewRef1
);
1656 if (bShear
&& bShearAllowed
) {
1657 Point
aRef(nShearX
,nShearY
);
1659 if(GetSdrPageView())
1661 GetSdrPageView()->PagePosToLogic(aRef
);
1664 ShearMarkedObj(aRef
,nShearAngle
,bShearVert
);
1667 // ShearMarkedObj creates a linear combination of the existing transformation and
1668 // the new shear to apply. If the object is already transformed (e.g. rotated) the
1669 // linear combination will not decompose to the same start values again, but to a
1670 // new combination. Thus it makes no sense to check if the wanted shear is reached
1671 // or not. Taking out.
1675 if (bChgPos
&& bMoveAllowed
) {
1676 MoveMarkedObj(Size(nPosDX
,nPosDY
));
1680 if(SfxItemState::SET
== rAttr
.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS
, true, &pPoolItem
))
1682 const bool bProtPos(static_cast<const SfxBoolItem
*>(pPoolItem
)->GetValue());
1683 bool bChanged(false);
1685 for(size_t i
= 0; i
< nMarkCount
; ++i
)
1687 pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1689 if(pObj
->IsMoveProtect() != bProtPos
)
1692 pObj
->SetMoveProtect(bProtPos
);
1696 pObj
->SetResizeProtect(true);
1703 bMoveProtect
= bProtPos
;
1707 bResizeProtect
= true;
1710 // #i77187# there is no simple method to get the toolbars updated
1711 // in the application. The App is listening to selection change and i
1712 // will use it here (even if not true). It's acceptable since changing
1713 // this model data is pretty rare and only possible using the F4 dialog
1714 MarkListHasChanged();
1721 if(SfxItemState::SET
== rAttr
.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZE
, true, &pPoolItem
))
1723 const bool bProtSize(static_cast<const SfxBoolItem
*>(pPoolItem
)->GetValue());
1724 bool bChanged(false);
1726 for(size_t i
= 0; i
< nMarkCount
; ++i
)
1728 pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1730 if(pObj
->IsResizeProtect() != bProtSize
)
1733 pObj
->SetResizeProtect(bProtSize
);
1739 bResizeProtect
= bProtSize
;
1741 // #i77187# see above
1742 MarkListHasChanged();
1752 bool SdrEditView::IsAlignPossible() const
1753 { // at least two selected objects, at least one of them movable
1754 ForcePossibilities();
1755 const size_t nCount
=GetMarkedObjectCount();
1756 if (nCount
==0) return false; // nothing selected!
1757 if (nCount
==1) return bMoveAllowed
; // align single object to page
1758 return bOneOrMoreMovable
; // otherwise: MarkCount>=2
1761 void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor
, SdrVertAlign eVert
, bool bBoundRects
)
1763 if (eHor
==SDRHALIGN_NONE
&& eVert
==SDRVALIGN_NONE
)
1766 SortMarkedObjects();
1767 if (!GetMarkedObjectCount())
1770 const bool bUndo
= IsUndoEnabled();
1773 OUString
aStr(GetDescriptionOfMarkedObjects());
1774 if (eHor
==SDRHALIGN_NONE
)
1778 case SDRVALIGN_TOP
: ImpTakeDescriptionStr(STR_EditAlignVTop
,aStr
); break;
1779 case SDRVALIGN_BOTTOM
: ImpTakeDescriptionStr(STR_EditAlignVBottom
,aStr
); break;
1780 case SDRVALIGN_CENTER
: ImpTakeDescriptionStr(STR_EditAlignVCenter
,aStr
); break;
1784 else if (eVert
==SDRVALIGN_NONE
)
1788 case SDRHALIGN_LEFT
: ImpTakeDescriptionStr(STR_EditAlignHLeft
,aStr
); break;
1789 case SDRHALIGN_RIGHT
: ImpTakeDescriptionStr(STR_EditAlignHRight
,aStr
); break;
1790 case SDRHALIGN_CENTER
: ImpTakeDescriptionStr(STR_EditAlignHCenter
,aStr
); break;
1794 else if (eHor
==SDRHALIGN_CENTER
&& eVert
==SDRVALIGN_CENTER
)
1796 ImpTakeDescriptionStr(STR_EditAlignCenter
,aStr
);
1800 ImpTakeDescriptionStr(STR_EditAlign
,aStr
);
1806 const size_t nMarkCount
=GetMarkedObjectCount();
1807 bool bHasFixed
=false;
1808 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1810 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1811 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
1812 SdrObjTransformInfoRec aInfo
;
1813 pObj
->TakeObjInfo(aInfo
);
1814 if (!aInfo
.bMoveAllowed
|| pObj
->IsMoveProtect())
1816 Rectangle
aObjRect(bBoundRects
?pObj
->GetCurrentBoundRect():pObj
->GetSnapRect());
1817 aBound
.Union(aObjRect
);
1824 { // align single object to page
1825 const SdrObject
* pObj
=GetMarkedObjectByIndex(0);
1826 const SdrPage
* pPage
=pObj
->GetPage();
1827 const SdrPageGridFrameList
* pGFL
=pPage
->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj
->GetSnapRect()));
1828 const SdrPageGridFrame
* pFrame
=NULL
;
1829 if (pGFL
!=NULL
&& pGFL
->GetCount()!=0)
1831 pFrame
=&((*pGFL
)[0]);
1836 aBound
=pFrame
->GetUserArea();
1840 aBound
=Rectangle(pPage
->GetLftBorder(),pPage
->GetUppBorder(),
1841 pPage
->GetWdt()-pPage
->GetRgtBorder(),
1842 pPage
->GetHgt()-pPage
->GetLwrBorder());
1848 aBound
=GetMarkedObjBoundRect();
1850 aBound
=GetMarkedObjRect();
1853 Point
aCenter(aBound
.Center());
1854 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1856 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1857 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
1858 SdrObjTransformInfoRec aInfo
;
1859 pObj
->TakeObjInfo(aInfo
);
1860 if (aInfo
.bMoveAllowed
&& !pObj
->IsMoveProtect())
1864 Rectangle
aObjRect(bBoundRects
?pObj
->GetCurrentBoundRect():pObj
->GetSnapRect());
1867 case SDRVALIGN_TOP
: nYMov
=aBound
.Top() -aObjRect
.Top() ; break;
1868 case SDRVALIGN_BOTTOM
: nYMov
=aBound
.Bottom()-aObjRect
.Bottom() ; break;
1869 case SDRVALIGN_CENTER
: nYMov
=aCenter
.Y() -aObjRect
.Center().Y(); break;
1874 case SDRHALIGN_LEFT
: nXMov
=aBound
.Left() -aObjRect
.Left() ; break;
1875 case SDRHALIGN_RIGHT
: nXMov
=aBound
.Right() -aObjRect
.Right() ; break;
1876 case SDRHALIGN_CENTER
: nXMov
=aCenter
.X() -aObjRect
.Center().X(); break;
1879 if (nXMov
!=0 || nYMov
!=0)
1881 // SdrEdgeObj needs an extra SdrUndoGeoObj since the
1882 // connections may need to be saved
1885 if( dynamic_cast<SdrEdgeObj
*>(pObj
) )
1887 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
1890 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj
,Size(nXMov
,nYMov
)));
1893 pObj
->Move(Size(nXMov
,nYMov
));
1902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */