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/eeitem.hxx>
24 #include <svl/itemiter.hxx>
25 #include <svl/whiter.hxx>
26 #include <tools/bigint.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/weld.hxx>
30 #include <getallcharpropids.hxx>
31 #include <svx/dialmgr.hxx>
32 #include <svx/svditer.hxx>
33 #include <svx/strings.hrc>
35 #include <AffineMatrixItem.hxx>
36 #include <svx/e3dsceneupdater.hxx>
37 #include <svx/obj3d.hxx>
38 #include <svx/rectenum.hxx>
39 #include <svx/sdr/contact/viewcontact.hxx>
40 #include <svx/sdooitm.hxx>
41 #include <svx/sderitm.hxx>
42 #include <svx/sdtagitm.hxx>
43 #include <svx/svdedtv.hxx>
44 #include <svx/svdetc.hxx>
45 #include <svx/svdopath.hxx>
46 #include <svx/svdpage.hxx>
47 #include <svx/svdpagv.hxx>
48 #include <svx/svdtrans.hxx>
49 #include <svx/svdundo.hxx>
50 #include <svx/svxids.hrc>
51 #include <sxallitm.hxx>
52 #include <sxmovitm.hxx>
53 #include <sxreaitm.hxx>
54 #include <sxreoitm.hxx>
55 #include <sxroaitm.hxx>
56 #include <sxrooitm.hxx>
57 #include <sxsalitm.hxx>
58 #include <sxsoitm.hxx>
59 #include <sxtraitm.hxx>
60 #include <svx/xlnedwit.hxx>
61 #include <svx/xlnstwit.hxx>
62 #include <svx/xlnwtit.hxx>
63 #include <svx/xlnclit.hxx>
64 #include <svx/xflclit.hxx>
65 #include <svx/xlntrit.hxx>
66 #include <svx/xfltrit.hxx>
67 #include <svx/sdprcitm.hxx>
68 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
69 #include <rtl/ustring.hxx>
70 #include <sfx2/viewsh.hxx>
71 #include <comphelper/lok.hxx>
72 #include <osl/diagnose.h>
77 void SdrEditView::SetMarkedObjRect(const tools::Rectangle
& rRect
)
79 DBG_ASSERT(!rRect
.IsEmpty(),"SetMarkedObjRect() with an empty Rect does not make sense.");
80 if (rRect
.IsEmpty()) return;
81 const size_t nCount
=GetMarkedObjectCount();
82 if (nCount
==0) return;
83 tools::Rectangle
aR0(GetMarkedObjRect());
84 DBG_ASSERT(!aR0
.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() is empty.");
85 if (aR0
.IsEmpty()) return;
86 tools::Long x0
=aR0
.Left();
87 tools::Long y0
=aR0
.Top();
88 tools::Long w0
=aR0
.Right()-x0
;
89 tools::Long h0
=aR0
.Bottom()-y0
;
90 tools::Long x1
=rRect
.Left();
91 tools::Long y1
=rRect
.Top();
92 tools::Long w1
=rRect
.Right()-x1
;
93 tools::Long h1
=rRect
.Bottom()-y1
;
95 const bool bUndo
= IsUndoEnabled();
98 EndTextEditCurrentView();
99 BegUndo(ImpGetDescriptionString(STR_EditPosSize
));
102 for (size_t nm
=0; nm
<nCount
; ++nm
)
104 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
105 SdrObject
* pO
=pM
->GetMarkedSdrObj();
107 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
109 tools::Rectangle
aR1(pO
->GetSnapRect());
117 { // transform aR1 to aR0 after rRect
119 BigInt
l(aR1
.Left());
120 BigInt
r(aR1
.Right());
122 BigInt
b(aR1
.Bottom());
135 aR1
.SetLeft(tools::Long(l
) );
136 aR1
.SetRight(tools::Long(r
) );
137 aR1
.SetTop(tools::Long(t
) );
138 aR1
.SetBottom(tools::Long(b
) );
141 pO
->SetSnapRect(aR1
);
143 OSL_FAIL("SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect");
150 std::vector
< std::unique_ptr
<SdrUndoAction
> > SdrEditView::CreateConnectorUndo( const SdrObject
& rO
)
152 std::vector
< std::unique_ptr
<SdrUndoAction
> > vUndoActions
;
154 if ( rO
.GetBroadcaster() )
156 const SdrPage
* pPage
= rO
.getSdrPageFromSdrObject();
159 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
);
160 while( aIter
.IsMore() )
162 SdrObject
* pPartObj
= aIter
.Next();
163 if ( dynamic_cast<const SdrEdgeObj
*>( pPartObj
) != nullptr )
165 if ( ( pPartObj
->GetConnectedNode( false ) == &rO
) ||
166 ( pPartObj
->GetConnectedNode( true ) == &rO
) )
168 vUndoActions
.push_back(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pPartObj
));
177 void SdrEditView::AddUndoActions( std::vector
< std::unique_ptr
<SdrUndoAction
> > aUndoActions
)
179 for (auto & rAction
: aUndoActions
)
180 AddUndo( std::move(rAction
) );
183 void SdrEditView::MoveMarkedObj(const Size
& rSiz
, bool bCopy
)
185 const bool bUndo
= IsUndoEnabled();
189 EndTextEditCurrentView();
190 OUString
aStr(SvxResId(STR_EditMove
));
192 aStr
+= SvxResId(STR_EditWithCopy
);
193 // needs its own UndoGroup because of its parameters
194 BegUndo(aStr
,GetDescriptionOfMarkedObjects(),SdrRepeatFunc::Move
);
200 const size_t nMarkCount
=GetMarkedObjectCount();
201 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
203 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
204 SdrObject
* pO
=pM
->GetMarkedSdrObj();
207 AddUndoActions( CreateConnectorUndo( *pO
) );
208 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoMoveObject(*pO
,rSiz
));
217 void SdrEditView::ResizeMarkedObj(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bCopy
)
219 const bool bUndo
= IsUndoEnabled();
222 EndTextEditCurrentView();
223 OUString aStr
{ImpGetDescriptionString(STR_EditResize
)};
225 aStr
+=SvxResId(STR_EditWithCopy
);
232 const size_t nMarkCount
=GetMarkedObjectCount();
233 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
235 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
236 SdrObject
* pO
=pM
->GetMarkedSdrObj();
239 AddUndoActions( CreateConnectorUndo( *pO
) );
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
,
254 const bool bUndo
= IsUndoEnabled();
257 EndTextEditCurrentView();
258 BegUndo(ImpGetDescriptionString(STR_EditResize
));
261 const size_t nMarkCount
=GetMarkedObjectCount();
262 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
264 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
265 SdrObject
* pO
=pM
->GetMarkedSdrObj();
268 AddUndoActions( CreateConnectorUndo( *pO
) );
269 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
273 if (bWdh
&& xFact
.IsValid() && bHgt
&& yFact
.IsValid())
274 pO
->Resize(rRef
, xFact
, yFact
);
275 else if (bWdh
&& xFact
.IsValid())
276 pO
->Resize(rRef
, xFact
, aFrac
);
277 else if (bHgt
&& yFact
.IsValid())
278 pO
->Resize(rRef
, aFrac
, yFact
);
284 Degree100
SdrEditView::GetMarkedObjRotate() const
286 Degree100
nRetval(0);
288 if(GetMarkedObjectCount())
290 SdrMark
* pM
= GetSdrMarkByIndex(0);
291 SdrObject
* pO
= pM
->GetMarkedSdrObj();
293 nRetval
= pO
->GetRotateAngle();
299 void SdrEditView::RotateMarkedObj(const Point
& rRef
, Degree100 nAngle
, bool bCopy
)
301 const bool bUndo
= IsUndoEnabled();
304 EndTextEditCurrentView();
305 OUString aStr
{ImpGetDescriptionString(STR_EditRotate
)};
306 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
313 double nSin
= sin(toRadians(nAngle
));
314 double nCos
= cos(toRadians(nAngle
));
315 const size_t nMarkCount(GetMarkedObjectCount());
319 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
321 for(size_t nm
= 0; nm
< nMarkCount
; ++nm
)
323 SdrMark
* pM
= GetSdrMarkByIndex(nm
);
324 SdrObject
* pO
= pM
->GetMarkedSdrObj();
328 // extra undo actions for changed connector which now may hold its laid out path (SJ)
329 AddUndoActions( CreateConnectorUndo( *pO
) );
331 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
334 // set up a scene updater if object is a 3d object
335 if(DynCastE3dObject(pO
))
337 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pO
));
340 pO
->Rotate(rRef
,nAngle
,nSin
,nCos
);
343 // fire scene updaters
344 while(!aUpdaters
.empty())
346 delete aUpdaters
.back();
347 aUpdaters
.pop_back();
355 void SdrEditView::MirrorMarkedObj(const Point
& rRef1
, const Point
& rRef2
, bool bCopy
)
357 const bool bUndo
= IsUndoEnabled();
361 EndTextEditCurrentView();
363 Point
aDif(rRef2
-rRef1
);
365 aStr
= ImpGetDescriptionString(STR_EditMirrorHori
);
366 else if (aDif
.Y()==0)
367 aStr
= ImpGetDescriptionString(STR_EditMirrorVert
);
368 else if (std::abs(aDif
.X()) == std::abs(aDif
.Y()))
369 aStr
= ImpGetDescriptionString(STR_EditMirrorDiag
);
371 aStr
= ImpGetDescriptionString(STR_EditMirrorFree
);
372 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
379 const size_t nMarkCount(GetMarkedObjectCount());
383 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
385 for(size_t nm
= 0; nm
< nMarkCount
; ++nm
)
387 SdrMark
* pM
= GetSdrMarkByIndex(nm
);
388 SdrObject
* pO
= pM
->GetMarkedSdrObj();
392 // extra undo actions for changed connector which now may hold its laid out path (SJ)
393 AddUndoActions( CreateConnectorUndo( *pO
) );
395 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
398 // set up a scene updater if object is a 3d object
399 if(DynCastE3dObject(pO
))
401 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pO
));
404 pO
->Mirror(rRef1
,rRef2
);
407 // fire scene updaters
408 while(!aUpdaters
.empty())
410 delete aUpdaters
.back();
411 aUpdaters
.pop_back();
419 void SdrEditView::MirrorMarkedObjHorizontal()
421 Point
aCenter(GetMarkedObjRect().Center());
424 MirrorMarkedObj(aCenter
,aPt2
);
427 void SdrEditView::MirrorMarkedObjVertical()
429 Point
aCenter(GetMarkedObjRect().Center());
432 MirrorMarkedObj(aCenter
,aPt2
);
435 Degree100
SdrEditView::GetMarkedObjShear() const
440 const size_t nMarkCount
=GetMarkedObjectCount();
441 for (size_t nm
=0; nm
<nMarkCount
&& bOk
; ++nm
) {
442 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
443 SdrObject
* pO
=pM
->GetMarkedSdrObj();
444 Degree100 nAngle2
=pO
->GetShearAngle();
445 if (b1st
) nAngle
=nAngle2
;
446 else if (nAngle2
!=nAngle
) bOk
=false;
449 if (nAngle
>SDRMAXSHEAR
) nAngle
=SDRMAXSHEAR
;
450 if (nAngle
<-SDRMAXSHEAR
) nAngle
=-SDRMAXSHEAR
;
451 if (!bOk
) nAngle
=0_deg100
;
455 void SdrEditView::ShearMarkedObj(const Point
& rRef
, Degree100 nAngle
, bool bVShear
, bool bCopy
)
457 const bool bUndo
= IsUndoEnabled();
461 EndTextEditCurrentView();
462 OUString aStr
{ImpGetDescriptionString(STR_EditShear
)};
464 aStr
+=SvxResId(STR_EditWithCopy
);
471 double nTan
= tan(toRadians(nAngle
));
472 const size_t nMarkCount
=GetMarkedObjectCount();
473 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
475 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
476 SdrObject
* pO
=pM
->GetMarkedSdrObj();
479 AddUndoActions( CreateConnectorUndo( *pO
) );
480 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
482 pO
->Shear(rRef
,nAngle
,nTan
,bVShear
);
489 void SdrEditView::ImpCrookObj(SdrObject
* pO
, const Point
& rRef
, const Point
& rRad
,
490 SdrCrookMode eMode
, bool bVertical
, bool bNoContortion
, bool bRotate
, const tools::Rectangle
& rMarkRect
)
492 SdrPathObj
* pPath
=dynamic_cast<SdrPathObj
*>( pO
);
495 if(pPath
!=nullptr && !bNoContortion
)
497 XPolyPolygon
aXPP(pPath
->GetPathPoly());
499 case SdrCrookMode::Rotate
: CrookRotatePoly (aXPP
,rRef
,rRad
,bVertical
); break;
500 case SdrCrookMode::Slant
: CrookSlantPoly (aXPP
,rRef
,rRad
,bVertical
); break;
501 case SdrCrookMode::Stretch
: CrookStretchPoly(aXPP
,rRef
,rRad
,bVertical
,rMarkRect
); break;
503 pPath
->SetPathPoly(aXPP
.getB2DPolyPolygon());
507 if(!bDone
&& !pPath
&& pO
->IsPolyObj() && 0 != pO
->GetPointCount())
509 // for PolyObj's, but NOT for SdrPathObj's, e.g. the measurement object
510 sal_uInt32
nPointCount(pO
->GetPointCount());
511 XPolygon
aXP(static_cast<sal_uInt16
>(nPointCount
));
514 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
516 Point
aPt(pO
->GetPoint(nPtNum
));
517 aXP
[static_cast<sal_uInt16
>(nPtNum
)]=aPt
;
522 case SdrCrookMode::Rotate
: CrookRotatePoly (aXP
,rRef
,rRad
,bVertical
); break;
523 case SdrCrookMode::Slant
: CrookSlantPoly (aXP
,rRef
,rRad
,bVertical
); break;
524 case SdrCrookMode::Stretch
: CrookStretchPoly(aXP
,rRef
,rRad
,bVertical
,rMarkRect
); break;
527 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
529 // broadcasting could be optimized here, but for the
530 // current two points of the measurement object, it's fine
531 pO
->SetPoint(aXP
[static_cast<sal_uInt16
>(nPtNum
)],nPtNum
);
540 // for all others or if bNoContortion
541 Point
aCtr0(pO
->GetSnapRect().Center());
544 double nSin(0.0), nCos(1.0);
547 if(0 != rRad
.X() && 0 != rRad
.Y())
553 case SdrCrookMode::Rotate
: nAngle
=CrookRotateXPoint (aCtr1
,nullptr,nullptr,rRef
,rRad
,nSin
,nCos
,bVertical
); bRotOk
=bRotate
; break;
554 case SdrCrookMode::Slant
: nAngle
=CrookSlantXPoint (aCtr1
,nullptr,nullptr,rRef
,rRad
,nSin
,nCos
,bVertical
); break;
555 case SdrCrookMode::Stretch
: nAngle
=CrookStretchXPoint(aCtr1
,nullptr,nullptr,rRef
,rRad
,nSin
,nCos
,bVertical
,rMarkRect
); break;
562 pO
->Rotate(aCtr0
, Degree100(FRound(basegfx::rad2deg
<100>(nAngle
))), nSin
, nCos
);
564 pO
->Move(Size(aCtr1
.X(),aCtr1
.Y()));
567 void SdrEditView::CrookMarkedObj(const Point
& rRef
, const Point
& rRad
, SdrCrookMode eMode
,
568 bool bVertical
, bool bNoContortion
, bool bCopy
)
570 tools::Rectangle
aMarkRect(GetMarkedObjRect());
571 const bool bUndo
= IsUndoEnabled();
573 bool bRotate
=bNoContortion
&& eMode
==SdrCrookMode::Rotate
&& IsRotateAllowed();
577 EndTextEditCurrentView();
578 OUString aStr
{ImpGetDescriptionString(bNoContortion
? STR_EditCrook
: STR_EditCrookContortion
)};
580 aStr
+=SvxResId(STR_EditWithCopy
);
587 const size_t nMarkCount
=GetMarkedObjectCount();
588 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
590 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
591 SdrObject
* pO
=pM
->GetMarkedSdrObj();
593 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
595 const SdrObjList
* pOL
=pO
->GetSubList();
596 if (bNoContortion
|| pOL
==nullptr) {
597 ImpCrookObj(pO
,rRef
,rRad
,eMode
,bVertical
,bNoContortion
,bRotate
,aMarkRect
);
599 SdrObjListIter
aIter(pOL
,SdrIterMode::DeepNoGroups
);
600 while (aIter
.IsMore()) {
601 SdrObject
* pO1
=aIter
.Next();
602 ImpCrookObj(pO1
,rRef
,rRad
,eMode
,bVertical
,bNoContortion
,bRotate
,aMarkRect
);
611 void SdrEditView::ImpDistortObj(SdrObject
* pO
, const tools::Rectangle
& rRef
, const XPolygon
& rDistortedRect
, bool bNoContortion
)
613 SdrPathObj
* pPath
= dynamic_cast<SdrPathObj
*>( pO
);
615 if(!bNoContortion
&& pPath
)
617 XPolyPolygon
aXPP(pPath
->GetPathPoly());
618 aXPP
.Distort(rRef
, rDistortedRect
);
619 pPath
->SetPathPoly(aXPP
.getB2DPolyPolygon());
621 else if(pO
->IsPolyObj())
623 // e. g. for the measurement object
624 sal_uInt32
nPointCount(pO
->GetPointCount());
625 XPolygon
aXP(static_cast<sal_uInt16
>(nPointCount
));
628 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
630 Point
aPt(pO
->GetPoint(nPtNum
));
631 aXP
[static_cast<sal_uInt16
>(nPtNum
)]=aPt
;
634 aXP
.Distort(rRef
, rDistortedRect
);
636 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
638 // broadcasting could be optimized here, but for the
639 // current two points of the measurement object it's fine
640 pO
->SetPoint(aXP
[static_cast<sal_uInt16
>(nPtNum
)],nPtNum
);
645 void SdrEditView::DistortMarkedObj(const tools::Rectangle
& rRef
, const XPolygon
& rDistortedRect
, bool bNoContortion
, bool bCopy
)
647 const bool bUndo
= IsUndoEnabled();
651 EndTextEditCurrentView();
652 OUString aStr
{ImpGetDescriptionString(STR_EditDistort
)};
654 aStr
+=SvxResId(STR_EditWithCopy
);
661 const size_t nMarkCount
=GetMarkedObjectCount();
662 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
664 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
665 SdrObject
* pO
=pM
->GetMarkedSdrObj();
667 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
669 tools::Rectangle
aRefRect(rRef
);
670 const SdrObjList
* pOL
=pO
->GetSubList();
671 if (bNoContortion
|| pOL
==nullptr) {
672 ImpDistortObj(pO
,aRefRect
,rDistortedRect
,bNoContortion
);
674 SdrObjListIter
aIter(pOL
,SdrIterMode::DeepNoGroups
);
675 while (aIter
.IsMore()) {
676 SdrObject
* pO1
=aIter
.Next();
677 ImpDistortObj(pO1
,aRefRect
,rDistortedRect
,bNoContortion
);
686 void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet
& rAttr
)
688 // bReplaceAll has no effect here
689 tools::Rectangle
aAllSnapRect(GetMarkedObjRect());
690 if (const SdrTransformRef1XItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF1X
))
692 tools::Long n
= pPoolItem
->GetValue();
693 SetRef1(Point(n
,GetRef1().Y()));
695 if (const SdrTransformRef1YItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF1Y
))
697 tools::Long n
= pPoolItem
->GetValue();
698 SetRef1(Point(GetRef1().X(),n
));
700 if (const SdrTransformRef2XItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF2X
))
702 tools::Long n
= pPoolItem
->GetValue();
703 SetRef2(Point(n
,GetRef2().Y()));
705 if (const SdrTransformRef2YItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF2Y
))
707 tools::Long n
= pPoolItem
->GetValue();
708 SetRef2(Point(GetRef2().X(),n
));
710 tools::Long nAllPosX
=0; bool bAllPosX
=false;
711 tools::Long nAllPosY
=0; bool bAllPosY
=false;
712 tools::Long nAllWdt
=0; bool bAllWdt
=false;
713 tools::Long nAllHgt
=0; bool bAllHgt
=false;
715 if (const SdrAllPositionXItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLPOSITIONX
))
717 nAllPosX
= pPoolItem
->GetValue();
718 bAllPosX
=true; bDoIt
=true;
720 if (const SdrAllPositionYItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLPOSITIONY
))
722 nAllPosY
= pPoolItem
->GetValue();
723 bAllPosY
=true; bDoIt
=true;
725 if (const SdrAllSizeWidthItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLSIZEWIDTH
))
727 nAllWdt
= pPoolItem
->GetValue();
728 bAllWdt
=true; bDoIt
=true;
730 if (const SdrAllSizeHeightItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLSIZEHEIGHT
))
732 nAllHgt
= pPoolItem
->GetValue();
733 bAllHgt
=true; bDoIt
=true;
736 tools::Rectangle
aRect(aAllSnapRect
); // TODO: change this for PolyPt's and GluePt's!!!
737 if (bAllPosX
) aRect
.Move(nAllPosX
-aRect
.Left(),0);
738 if (bAllPosY
) aRect
.Move(0,nAllPosY
-aRect
.Top());
739 if (bAllWdt
) aRect
.SetRight(aAllSnapRect
.Left()+nAllWdt
);
740 if (bAllHgt
) aRect
.SetBottom(aAllSnapRect
.Top()+nAllHgt
);
741 SetMarkedObjRect(aRect
);
743 if (const SdrResizeXAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_RESIZEXALL
))
745 Fraction aXFact
= pPoolItem
->GetValue();
746 ResizeMarkedObj(aAllSnapRect
.TopLeft(),aXFact
,Fraction(1,1));
748 if (const SdrResizeYAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_RESIZEYALL
))
750 Fraction aYFact
= pPoolItem
->GetValue();
751 ResizeMarkedObj(aAllSnapRect
.TopLeft(),Fraction(1,1),aYFact
);
753 if (const SdrRotateAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ROTATEALL
))
755 Degree100 nAngle
= pPoolItem
->GetValue();
756 RotateMarkedObj(aAllSnapRect
.Center(),nAngle
);
758 if (const SdrHorzShearAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_HORZSHEARALL
))
760 Degree100 nAngle
= pPoolItem
->GetValue();
761 ShearMarkedObj(aAllSnapRect
.Center(),nAngle
);
763 if (const SdrVertShearAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_VERTSHEARALL
))
765 Degree100 nAngle
= pPoolItem
->GetValue();
766 ShearMarkedObj(aAllSnapRect
.Center(),nAngle
,true);
769 const bool bUndo
= IsUndoEnabled();
771 // TODO: check if WhichRange is necessary.
772 const size_t nMarkCount
=GetMarkedObjectCount();
773 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
775 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
776 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
778 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
780 pObj
->ApplyNotPersistAttr(rAttr
);
784 void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet
& rAttr
) const
786 // TODO: Take into account the origin and PvPos.
787 tools::Rectangle
aAllSnapRect(GetMarkedObjRect()); // TODO: change this for PolyPt's and GluePt's!!!
788 tools::Long nAllSnapPosX
=aAllSnapRect
.Left();
789 tools::Long nAllSnapPosY
=aAllSnapRect
.Top();
790 tools::Long nAllSnapWdt
=aAllSnapRect
.GetWidth()-1;
791 tools::Long nAllSnapHgt
=aAllSnapRect
.GetHeight()-1;
792 // TODO: could go into CheckPossibilities
793 bool bMovProtect
= false, bMovProtectDC
= false;
794 bool bSizProtect
= false, bSizProtectDC
= false;
795 bool bPrintable
= true, bPrintableDC
= false;
796 bool bVisible
= true, bVisibleDC
= false;
797 SdrLayerID
nLayerId(0);
799 tools::Long nSnapPosX
=0; bool bSnapPosXDC
=false;
800 tools::Long nSnapPosY
=0; bool bSnapPosYDC
=false;
801 tools::Long nSnapWdt
=0; bool bSnapWdtDC
=false;
802 tools::Long nSnapHgt
=0; bool bSnapHgtDC
=false;
803 tools::Long nLogicWdt
=0; bool bLogicWdtDC
=false,bLogicWdtDiff
=false;
804 tools::Long nLogicHgt
=0; bool bLogicHgtDC
=false,bLogicHgtDiff
=false;
805 Degree100
nRotAngle(0); bool bRotAngleDC
=false;
806 Degree100
nShrAngle(0); bool bShrAngleDC
=false;
807 tools::Rectangle aSnapRect
;
808 tools::Rectangle aLogicRect
;
809 const size_t nMarkCount
=GetMarkedObjectCount();
810 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
811 const SdrMark
* pM
=GetSdrMarkByIndex(nm
);
812 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
814 nLayerId
=pObj
->GetLayer();
815 bMovProtect
=pObj
->IsMoveProtect();
816 bSizProtect
=pObj
->IsResizeProtect();
817 bPrintable
=pObj
->IsPrintable();
818 bVisible
= pObj
->IsVisible();
819 tools::Rectangle
aSnapRect2(pObj
->GetSnapRect());
820 tools::Rectangle
aLogicRect2(pObj
->GetLogicRect());
821 nSnapPosX
=aSnapRect2
.Left();
822 nSnapPosY
=aSnapRect2
.Top();
823 nSnapWdt
=aSnapRect2
.GetWidth()-1;
824 nSnapHgt
=aSnapRect2
.GetHeight()-1;
825 nLogicWdt
=aLogicRect2
.GetWidth()-1;
826 nLogicHgt
=aLogicRect2
.GetHeight()-1;
827 bLogicWdtDiff
=nLogicWdt
!=nSnapWdt
;
828 bLogicHgtDiff
=nLogicHgt
!=nSnapHgt
;
829 nRotAngle
=pObj
->GetRotateAngle();
830 nShrAngle
=pObj
->GetShearAngle();
832 if (!bLayerDC
&& nLayerId
!=pObj
->GetLayer()) bLayerDC
= true;
833 if (!bMovProtectDC
&& bMovProtect
!=pObj
->IsMoveProtect()) bMovProtectDC
= true;
834 if (!bSizProtectDC
&& bSizProtect
!=pObj
->IsResizeProtect()) bSizProtectDC
= true;
835 if (!bPrintableDC
&& bPrintable
!=pObj
->IsPrintable()) bPrintableDC
= true;
836 if (!bVisibleDC
&& bVisible
!=pObj
->IsVisible()) bVisibleDC
=true;
837 if (!bRotAngleDC
&& nRotAngle
!=pObj
->GetRotateAngle()) bRotAngleDC
=true;
838 if (!bShrAngleDC
&& nShrAngle
!=pObj
->GetShearAngle()) bShrAngleDC
=true;
839 if (!bSnapWdtDC
|| !bSnapHgtDC
|| !bSnapPosXDC
|| !bSnapPosYDC
|| !bLogicWdtDiff
|| !bLogicHgtDiff
) {
840 aSnapRect
=pObj
->GetSnapRect();
841 if (nSnapPosX
!=aSnapRect
.Left()) bSnapPosXDC
=true;
842 if (nSnapPosY
!=aSnapRect
.Top()) bSnapPosYDC
=true;
843 if (nSnapWdt
!=aSnapRect
.GetWidth()-1) bSnapWdtDC
=true;
844 if (nSnapHgt
!=aSnapRect
.GetHeight()-1) bSnapHgtDC
=true;
846 if (!bLogicWdtDC
|| !bLogicHgtDC
|| !bLogicWdtDiff
|| !bLogicHgtDiff
) {
847 aLogicRect
=pObj
->GetLogicRect();
848 if (nLogicWdt
!=aLogicRect
.GetWidth()-1) bLogicWdtDC
=true;
849 if (nLogicHgt
!=aLogicRect
.GetHeight()-1) bLogicHgtDC
=true;
850 if (!bLogicWdtDiff
&& aSnapRect
.GetWidth()!=aLogicRect
.GetWidth()) bLogicWdtDiff
=true;
851 if (!bLogicHgtDiff
&& aSnapRect
.GetHeight()!=aLogicRect
.GetHeight()) bLogicHgtDiff
=true;
856 if (bSnapPosXDC
|| nAllSnapPosX
!=nSnapPosX
) rAttr
.Put(SdrAllPositionXItem(nAllSnapPosX
));
857 if (bSnapPosYDC
|| nAllSnapPosY
!=nSnapPosY
) rAttr
.Put(SdrAllPositionYItem(nAllSnapPosY
));
858 if (bSnapWdtDC
|| nAllSnapWdt
!=nSnapWdt
) rAttr
.Put(SdrAllSizeWidthItem(nAllSnapWdt
));
859 if (bSnapHgtDC
|| nAllSnapHgt
!=nSnapHgt
) rAttr
.Put(SdrAllSizeHeightItem(nAllSnapHgt
));
861 // items for pure transformations
862 rAttr
.Put(SdrMoveXItem());
863 rAttr
.Put(SdrMoveYItem());
864 rAttr
.Put(SdrResizeXOneItem());
865 rAttr
.Put(SdrResizeYOneItem());
866 rAttr
.Put(SdrRotateOneItem());
867 rAttr
.Put(SdrHorzShearOneItem());
868 rAttr
.Put(SdrVertShearOneItem());
871 rAttr
.Put(SdrResizeXAllItem());
872 rAttr
.Put(SdrResizeYAllItem());
873 rAttr
.Put(SdrRotateAllItem());
874 rAttr
.Put(SdrHorzShearAllItem());
875 rAttr
.Put(SdrVertShearAllItem());
878 if(meDragMode
== SdrDragMode::Rotate
|| meDragMode
== SdrDragMode::Mirror
)
880 rAttr
.Put(SdrTransformRef1XItem(GetRef1().X()));
881 rAttr
.Put(SdrTransformRef1YItem(GetRef1().Y()));
884 if(meDragMode
== SdrDragMode::Mirror
)
886 rAttr
.Put(SdrTransformRef2XItem(GetRef2().X()));
887 rAttr
.Put(SdrTransformRef2YItem(GetRef2().Y()));
891 SfxItemSet
SdrEditView::GetAttrFromMarked(bool bOnlyHardAttr
) const
893 SfxItemSet
aSet(GetModel().GetItemPool());
894 MergeAttrFromMarked(aSet
,bOnlyHardAttr
);
895 //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there)
896 //so we do not set them here
898 // Do not disable, but clear the items.
899 aSet
.ClearItem(EE_FEATURE_TAB
);
900 aSet
.ClearItem(EE_FEATURE_LINEBR
);
901 aSet
.ClearItem(EE_FEATURE_NOTCONV
);
902 aSet
.ClearItem(EE_FEATURE_FIELD
);
907 void SdrEditView::MergeAttrFromMarked(SfxItemSet
& rAttr
, bool bOnlyHardAttr
) const
909 const size_t nMarkCount(GetMarkedObjectCount());
911 for(size_t a
= 0; a
< nMarkCount
; ++a
)
913 // #80277# merging was done wrong in the prev version
914 SdrObject
*pObj
= GetMarkedObjectByIndex(a
);
920 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
921 SfxWhichIter
aIter(rSet
);
922 sal_uInt16
nWhich(aIter
.FirstWhich());
928 if(SfxItemState::DONTCARE
== aIter
.GetItemState(false))
929 rAttr
.InvalidateItem(nWhich
);
931 rAttr
.MergeValue(rSet
.Get(nWhich
), true);
933 else if(SfxItemState::SET
== aIter
.GetItemState(false))
935 const SfxPoolItem
& rItem
= rSet
.Get(nWhich
);
936 rAttr
.MergeValue(rItem
, true);
939 if (comphelper::LibreOfficeKit::isActive())
944 case XATTR_LINECOLOR
:
946 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_LINECOLOR
);
949 Color aColor
= static_cast<const XLineColorItem
*>(pItem
)->GetColorValue();
950 sPayload
= OUString::number(static_cast<sal_uInt32
>(aColor
));
952 sPayload
= ".uno:XLineColor=" + sPayload
;
957 case XATTR_FILLCOLOR
:
959 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_FILLCOLOR
);
962 Color aColor
= static_cast<const XFillColorItem
*>(pItem
)->GetColorValue();
963 sPayload
= OUString::number(static_cast<sal_uInt32
>(aColor
));
965 sPayload
= ".uno:FillColor=" + sPayload
;
970 case XATTR_FILLTRANSPARENCE
:
972 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_FILLTRANSPARENCE
);
975 sal_uInt16 nTransparency
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
976 sPayload
= OUString::number(nTransparency
);
978 sPayload
= ".uno:FillTransparence=" + sPayload
;
983 case XATTR_LINETRANSPARENCE
:
985 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_LINETRANSPARENCE
);
988 sal_uInt16 nTransparency
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
989 sPayload
= OUString::number(nTransparency
);
991 sPayload
= ".uno:LineTransparence=" + sPayload
;
996 case XATTR_LINEWIDTH
:
998 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_LINEWIDTH
);
1001 sal_uInt32 nWidth
= static_cast<const XLineWidthItem
*>(pItem
)->GetValue();
1002 sPayload
= OUString::number(nWidth
);
1004 sPayload
= ".uno:LineWidth=" + sPayload
;
1009 case SDRATTR_SHADOWTRANSPARENCE
:
1011 const SfxPoolItem
* pItem
= rSet
.GetItem(SDRATTR_SHADOWTRANSPARENCE
);
1014 sal_uInt16 nWidth
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1015 sPayload
= OUString::number(nWidth
);
1017 sPayload
= ".uno:FillShadowTransparency=" + sPayload
;
1023 if (!sPayload
.isEmpty())
1024 GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED
,
1025 OUStringToOString(sPayload
, RTL_TEXTENCODING_ASCII_US
));
1028 nWhich
= aIter
.NextWhich();
1033 std::vector
<sal_uInt16
> GetAllCharPropIds(const SfxItemSet
& rSet
)
1035 std::vector
<sal_uInt16
> aCharWhichIds
;
1037 SfxItemIter
aIter(rSet
);
1038 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
1040 if (!IsInvalidItem(pItem
))
1042 sal_uInt16 nWhich
= pItem
->Which();
1043 if (nWhich
>=EE_CHAR_START
&& nWhich
<=EE_CHAR_END
)
1044 aCharWhichIds
.push_back( nWhich
);
1048 return aCharWhichIds
;
1051 std::vector
<sal_uInt16
> GetAllCharPropIds(o3tl::span
< const SfxPoolItem
* const > aChangedItems
)
1053 std::vector
<sal_uInt16
> aCharWhichIds
;
1054 for (const SfxPoolItem
* pItem
: aChangedItems
)
1056 sal_uInt16 nWhich
= pItem
->Which();
1057 if (nWhich
>=EE_CHAR_START
&& nWhich
<=EE_CHAR_END
)
1058 aCharWhichIds
.push_back( nWhich
);
1060 return aCharWhichIds
;
1063 void SdrEditView::SetAttrToMarked(const SfxItemSet
& rAttr
, bool bReplaceAll
)
1065 if (!AreObjectsMarked())
1070 bool bHasEEFeatureItems
=false;
1071 SfxItemIter
aIter(rAttr
);
1072 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); !bHasEEFeatureItems
&& pItem
;
1073 pItem
= aIter
.NextItem())
1075 if (!IsInvalidItem(pItem
)) {
1076 sal_uInt16 nW
=pItem
->Which();
1077 if (nW
>=EE_FEATURE_START
&& nW
<=EE_FEATURE_END
) bHasEEFeatureItems
=true;
1080 if(bHasEEFeatureItems
)
1082 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(nullptr,
1083 VclMessageType::Info
, VclButtonsType::Ok
,
1084 "SdrEditView::SetAttrToMarked(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents."));
1090 // #103836# if the user sets character attributes to the complete shape,
1091 // we want to remove all hard set character attributes with same
1092 // which ids from the text. We do that later but here we remember
1093 // all character attribute which id's that are set.
1094 std::vector
<sal_uInt16
> aCharWhichIds(GetAllCharPropIds(rAttr
));
1096 // To make Undo reconstruct text attributes correctly after Format.Standard
1097 bool bHasEEItems
=SearchOutlinerItems(rAttr
,bReplaceAll
);
1099 // save additional geometry information when paragraph or character attributes
1100 // are changed and the geometrical shape of the text object might be changed
1101 bool bPossibleGeomChange(false);
1102 SfxWhichIter
aIter(rAttr
);
1103 sal_uInt16 nWhich
= aIter
.FirstWhich();
1104 while(!bPossibleGeomChange
&& nWhich
)
1106 SfxItemState eState
= aIter
.GetItemState();
1107 if(eState
== SfxItemState::SET
)
1109 if((nWhich
>= SDRATTR_TEXT_MINFRAMEHEIGHT
&& nWhich
<= SDRATTR_TEXT_CONTOURFRAME
)
1110 || nWhich
== SDRATTR_3DOBJ_PERCENT_DIAGONAL
1111 || nWhich
== SDRATTR_3DOBJ_BACKSCALE
1112 || nWhich
== SDRATTR_3DOBJ_DEPTH
1113 || nWhich
== SDRATTR_3DOBJ_END_ANGLE
1114 || nWhich
== SDRATTR_3DSCENE_DISTANCE
)
1116 bPossibleGeomChange
= true;
1119 nWhich
= aIter
.NextWhich();
1122 const bool bUndo
= IsUndoEnabled();
1125 EndTextEditCurrentView();
1126 BegUndo(ImpGetDescriptionString(STR_EditSetAttributes
));
1129 const size_t nMarkCount(GetMarkedObjectCount());
1130 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
1132 // create ItemSet without SfxItemState::DONTCARE. Put()
1133 // uses its second parameter (bInvalidAsDefault) to
1134 // remove all such items to set them to default.
1135 SfxItemSet
aAttr(*rAttr
.GetPool(), rAttr
.GetRanges());
1139 bool bResetAnimationTimer(false);
1141 const bool bLineStartWidthExplicitChange(SfxItemState::SET
1142 == aAttr
.GetItemState(XATTR_LINESTARTWIDTH
));
1143 const bool bLineEndWidthExplicitChange(SfxItemState::SET
1144 == aAttr
.GetItemState(XATTR_LINEENDWIDTH
));
1145 // check if LineWidth is part of the change
1146 const bool bAdaptStartEndWidths(!(bLineStartWidthExplicitChange
&& bLineEndWidthExplicitChange
)
1147 && SfxItemState::SET
== aAttr
.GetItemState(XATTR_LINEWIDTH
));
1148 sal_Int32
nNewLineWidth(0);
1150 if(bAdaptStartEndWidths
)
1152 nNewLineWidth
= aAttr
.Get(XATTR_LINEWIDTH
).GetValue();
1155 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1157 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1158 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
1162 SdrEdgeObj
* pEdgeObj
= dynamic_cast< SdrEdgeObj
* >( pObj
);
1164 bPossibleGeomChange
= true;
1166 AddUndoActions( CreateConnectorUndo( *pObj
) );
1169 // new geometry undo
1170 if(bPossibleGeomChange
&& bUndo
)
1172 // save position and size of object, too
1173 AddUndo( GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
1179 // If this is a text object also rescue the OutlinerParaObject since
1180 // applying attributes to the object may change text layout when
1181 // multiple portions exist with multiple formats. If an OutlinerParaObject
1182 // really exists and needs to be rescued is evaluated in the undo
1183 // implementation itself.
1184 const bool bRescueText
= DynCastSdrTextObj(pObj
) != nullptr;
1186 // add attribute undo
1187 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pObj
,false,bHasEEItems
|| bPossibleGeomChange
|| bRescueText
));
1190 // set up a scene updater if object is a 3d object
1191 if(DynCastE3dObject(pObj
))
1193 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pObj
));
1196 sal_Int32
nOldLineWidth(0);
1197 if (bAdaptStartEndWidths
)
1199 nOldLineWidth
= pObj
->GetMergedItem(XATTR_LINEWIDTH
).GetValue();
1202 // set attributes at object
1203 pObj
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
1205 if(bAdaptStartEndWidths
)
1207 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
1209 if(nOldLineWidth
!= nNewLineWidth
)
1211 if(SfxItemState::DONTCARE
!= rSet
.GetItemState(XATTR_LINESTARTWIDTH
))
1213 const sal_Int32
nValAct(rSet
.Get(XATTR_LINESTARTWIDTH
).GetValue());
1214 const sal_Int32
nValNewStart(std::max(sal_Int32(0), nValAct
+ (((nNewLineWidth
- nOldLineWidth
) * 15) / 10)));
1216 pObj
->SetMergedItem(XLineStartWidthItem(nValNewStart
));
1219 if(SfxItemState::DONTCARE
!= rSet
.GetItemState(XATTR_LINEENDWIDTH
))
1221 const sal_Int32
nValAct(rSet
.Get(XATTR_LINEENDWIDTH
).GetValue());
1222 const sal_Int32
nValNewEnd(std::max(sal_Int32(0), nValAct
+ (((nNewLineWidth
- nOldLineWidth
) * 15) / 10)));
1224 pObj
->SetMergedItem(XLineEndWidthItem(nValNewEnd
));
1229 if(auto pTextObj
= DynCastSdrTextObj( pObj
))
1231 if(!aCharWhichIds
.empty())
1233 tools::Rectangle aOldBoundRect
= pTextObj
->GetLastBoundRect();
1235 // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect());
1236 pTextObj
->RemoveOutlinerCharacterAttribs( aCharWhichIds
);
1238 // object has changed, should be called from
1239 // RemoveOutlinerCharacterAttribs. This will change when the text
1240 // object implementation changes.
1241 pTextObj
->SetChanged();
1243 pTextObj
->BroadcastObjectChange();
1244 pTextObj
->SendUserCall(SdrUserCallType::ChangeAttr
, aOldBoundRect
);
1249 if(!bResetAnimationTimer
)
1251 if(pObj
->GetViewContact().isAnimatedInAnyViewObjectContact())
1253 bResetAnimationTimer
= true;
1258 // fire scene updaters
1259 while(!aUpdaters
.empty())
1261 delete aUpdaters
.back();
1262 aUpdaters
.pop_back();
1266 if(bResetAnimationTimer
)
1268 SetAnimationTimer(0);
1271 // better check before what to do:
1272 // pObj->SetAttr() or SetNotPersistAttr()
1273 // TODO: missing implementation!
1274 SetNotPersistAttrToMarked(rAttr
);
1280 SfxStyleSheet
* SdrEditView::GetStyleSheetFromMarked() const
1282 SfxStyleSheet
* pRet
=nullptr;
1284 const size_t nMarkCount
=GetMarkedObjectCount();
1285 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
1286 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1287 SfxStyleSheet
* pSS
=pM
->GetMarkedSdrObj()->GetStyleSheet();
1289 else if (pRet
!=pSS
) return nullptr; // different stylesheets
1295 void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1297 if (!AreObjectsMarked())
1300 const bool bUndo
= IsUndoEnabled();
1304 EndTextEditCurrentView();
1306 if (pStyleSheet
!=nullptr)
1307 aStr
= ImpGetDescriptionString(STR_EditSetStylesheet
);
1309 aStr
= ImpGetDescriptionString(STR_EditDelStylesheet
);
1313 const size_t nMarkCount
=GetMarkedObjectCount();
1314 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1316 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1319 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pM
->GetMarkedSdrObj()));
1320 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pM
->GetMarkedSdrObj(),true,true));
1322 pM
->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1330 void SdrEditView::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
1332 if(GetMarkedObjectCount())
1334 rTargetSet
.Put(GetAttrFromMarked(bOnlyHardAttr
), false);
1338 SdrMarkView::GetAttributes(rTargetSet
, bOnlyHardAttr
);
1342 void SdrEditView::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
1344 if (GetMarkedObjectCount()!=0) {
1345 SetAttrToMarked(rSet
,bReplaceAll
);
1347 SdrMarkView::SetAttributes(rSet
,bReplaceAll
);
1351 SfxStyleSheet
* SdrEditView::GetStyleSheet() const
1353 if (GetMarkedObjectCount()!=0) {
1354 return GetStyleSheetFromMarked();
1356 return SdrMarkView::GetStyleSheet();
1360 void SdrEditView::SetStyleSheet(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1362 if (GetMarkedObjectCount()!=0) {
1363 SetStyleSheetToMarked(pStyleSheet
,bDontRemoveHardAttr
);
1365 SdrMarkView::SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1370 SfxItemSet
SdrEditView::GetGeoAttrFromMarked() const
1373 GetModel().GetItemPool(),
1374 svl::Items
< // SID_ATTR_TRANSFORM_... from s:svxids.hrc
1375 SDRATTR_CORNER_RADIUS
, SDRATTR_CORNER_RADIUS
,
1376 SID_ATTR_TRANSFORM_POS_X
, SID_ATTR_TRANSFORM_ANGLE
,
1377 SID_ATTR_TRANSFORM_PROTECT_POS
, SID_ATTR_TRANSFORM_AUTOHEIGHT
>);
1379 if (AreObjectsMarked())
1381 SfxItemSet
aMarkAttr(GetAttrFromMarked(false)); // because of AutoGrowHeight and corner radius
1382 tools::Rectangle
aRect(GetMarkedObjRect());
1384 if(GetSdrPageView())
1386 GetSdrPageView()->LogicToPagePos(aRect
);
1390 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X
,aRect
.Left()));
1391 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y
,aRect
.Top()));
1394 tools::Long nResizeRefX
=aRect
.Left();
1395 tools::Long nResizeRefY
=aRect
.Top();
1396 if (meDragMode
==SdrDragMode::Rotate
) { // use rotation axis as a reference for resizing, too
1397 nResizeRefX
=maRef1
.X();
1398 nResizeRefY
=maRef1
.Y();
1400 aRetSet
.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH
,aRect
.Right()-aRect
.Left()));
1401 aRetSet
.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT
,aRect
.Bottom()-aRect
.Top()));
1402 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X
,nResizeRefX
));
1403 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y
,nResizeRefY
));
1405 Point
aRotateAxe(maRef1
);
1407 if(GetSdrPageView())
1409 GetSdrPageView()->LogicToPagePos(aRotateAxe
);
1413 tools::Long nRotateRefX
=aRect
.Center().X();
1414 tools::Long nRotateRefY
=aRect
.Center().Y();
1415 if (meDragMode
==SdrDragMode::Rotate
) {
1416 nRotateRefX
=aRotateAxe
.X();
1417 nRotateRefY
=aRotateAxe
.Y();
1419 aRetSet
.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE
,GetMarkedObjRotate()));
1420 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X
,nRotateRefX
));
1421 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y
,nRotateRefY
));
1424 tools::Long nShearRefX
=aRect
.Left();
1425 tools::Long nShearRefY
=aRect
.Bottom();
1426 if (meDragMode
==SdrDragMode::Rotate
) { // use rotation axis as a reference for shearing, too
1427 nShearRefX
=aRotateAxe
.X();
1428 nShearRefY
=aRotateAxe
.Y();
1430 aRetSet
.Put(SdrAngleItem(SID_ATTR_TRANSFORM_SHEAR
,GetMarkedObjShear()));
1431 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X
,nShearRefX
));
1432 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y
,nShearRefY
));
1434 // check every object whether it is protected
1435 const SdrMarkList
& rMarkList
=GetMarkedObjectList();
1436 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1437 SdrObject
* pObj
=rMarkList
.GetMark(0)->GetMarkedSdrObj();
1438 bool bPosProt
=pObj
->IsMoveProtect();
1439 bool bSizProt
=pObj
->IsResizeProtect();
1440 bool bPosProtDontCare
=false;
1441 bool bSizProtDontCare
=false;
1442 for (size_t i
=1; i
<nMarkCount
&& (!bPosProtDontCare
|| !bSizProtDontCare
); ++i
)
1444 pObj
=rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1445 if (bPosProt
!=pObj
->IsMoveProtect()) bPosProtDontCare
=true;
1446 if (bSizProt
!=pObj
->IsResizeProtect()) bSizProtDontCare
=true;
1449 // InvalidateItem sets item to DONT_CARE
1450 if (bPosProtDontCare
) {
1451 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS
);
1453 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS
,bPosProt
));
1455 if (bSizProtDontCare
) {
1456 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE
);
1458 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE
,bSizProt
));
1461 SfxItemState eState
=aMarkAttr
.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH
);
1462 bool bAutoGrow
=aMarkAttr
.Get(SDRATTR_TEXT_AUTOGROWWIDTH
).GetValue();
1463 if (eState
==SfxItemState::DONTCARE
) {
1464 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH
);
1465 } else if (eState
==SfxItemState::SET
) {
1466 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH
,bAutoGrow
));
1469 eState
=aMarkAttr
.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT
);
1470 bAutoGrow
=aMarkAttr
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
).GetValue();
1471 if (eState
==SfxItemState::DONTCARE
) {
1472 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT
);
1473 } else if (eState
==SfxItemState::SET
) {
1474 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT
,bAutoGrow
));
1477 eState
=aMarkAttr
.GetItemState(SDRATTR_CORNER_RADIUS
);
1478 tools::Long nRadius
=aMarkAttr
.Get(SDRATTR_CORNER_RADIUS
).GetValue();
1479 if (eState
==SfxItemState::DONTCARE
) {
1480 aRetSet
.InvalidateItem(SDRATTR_CORNER_RADIUS
);
1481 } else if (eState
==SfxItemState::SET
) {
1482 aRetSet
.Put(makeSdrEckenradiusItem(nRadius
));
1485 basegfx::B2DHomMatrix aTransformation
;
1489 // multiple objects, range is collected in aRect
1490 aTransformation
= basegfx::utils::createScaleTranslateB2DHomMatrix(
1491 aRect
.Left(), aRect
.Top(),
1492 aRect
.getOpenWidth(), aRect
.getOpenHeight());
1496 // single object, get homogen transformation
1497 basegfx::B2DPolyPolygon aPolyPolygon
;
1499 pObj
->TRGetBaseGeometry(aTransformation
, aPolyPolygon
);
1502 if(aTransformation
.isIdentity())
1504 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_MATRIX
);
1508 css::geometry::AffineMatrix2D aAffineMatrix2D
;
1509 Point
aPageOffset(0, 0);
1511 if(GetSdrPageView())
1513 aPageOffset
= GetSdrPageView()->GetPageOrigin();
1516 aAffineMatrix2D
.m00
= aTransformation
.get(0, 0);
1517 aAffineMatrix2D
.m01
= aTransformation
.get(0, 1);
1518 aAffineMatrix2D
.m02
= aTransformation
.get(0, 2) - aPageOffset
.X();
1519 aAffineMatrix2D
.m10
= aTransformation
.get(1, 0);
1520 aAffineMatrix2D
.m11
= aTransformation
.get(1, 1);
1521 aAffineMatrix2D
.m12
= aTransformation
.get(1, 2) - aPageOffset
.Y();
1523 aRetSet
.Put(AffineMatrixItem(&aAffineMatrix2D
));
1530 static Point
ImpGetPoint(const tools::Rectangle
& rRect
, RectPoint eRP
)
1533 case RectPoint::LT
: return rRect
.TopLeft();
1534 case RectPoint::MT
: return rRect
.TopCenter();
1535 case RectPoint::RT
: return rRect
.TopRight();
1536 case RectPoint::LM
: return rRect
.LeftCenter();
1537 case RectPoint::MM
: return rRect
.Center();
1538 case RectPoint::RM
: return rRect
.RightCenter();
1539 case RectPoint::LB
: return rRect
.BottomLeft();
1540 case RectPoint::MB
: return rRect
.BottomCenter();
1541 case RectPoint::RB
: return rRect
.BottomRight();
1543 return Point(); // Should not happen!
1546 void SdrEditView::SetGeoAttrToMarked(const SfxItemSet
& rAttr
, bool addPageMargin
)
1548 const bool bTiledRendering
= comphelper::LibreOfficeKit::isActive();
1550 tools::Rectangle
aRect(GetMarkedObjRect());
1552 if(GetSdrPageView())
1556 SdrPage
* pPage
= GetSdrPageView()->GetPage();
1557 Point
upperLeft(pPage
->GetLeftBorder(), pPage
->GetUpperBorder());
1558 aRect
.Move(upperLeft
.getX(), upperLeft
.getY());
1560 GetSdrPageView()->LogicToPagePos(aRect
);
1563 Degree100 nOldRotateAngle
=GetMarkedObjRotate();
1564 Degree100 nOldShearAngle
=GetMarkedObjShear();
1565 const SdrMarkList
& rMarkList
=GetMarkedObjectList();
1566 SdrObject
* pObj
=nullptr;
1568 RectPoint eSizePoint
=RectPoint::MM
;
1569 tools::Long nPosDX
=0;
1570 tools::Long nPosDY
=0;
1571 tools::Long nSizX
=0;
1572 tools::Long nSizY
=0;
1573 Degree100
nRotateAngle(0);
1575 bool bModeIsRotate(meDragMode
== SdrDragMode::Rotate
);
1576 tools::Long
nRotateX(0);
1577 tools::Long
nRotateY(0);
1578 tools::Long
nOldRotateX(0);
1579 tools::Long
nOldRotateY(0);
1582 Point
aRotateAxe(maRef1
);
1584 if(GetSdrPageView())
1586 GetSdrPageView()->LogicToPagePos(aRotateAxe
);
1589 nRotateX
= nOldRotateX
= aRotateAxe
.X();
1590 nRotateY
= nOldRotateY
= aRotateAxe
.Y();
1593 Degree100
nShearAngle(0);
1594 tools::Long nShearX
=0;
1595 tools::Long nShearY
=0;
1596 bool bShearVert
=false;
1605 bool bSetAttr
=false;
1606 SfxItemSet
aSetAttr(GetModel().GetItemPool());
1609 if (const SfxInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_POS_X
))
1611 nPosDX
= pPoolItem
->GetValue() - aRect
.Left();
1614 if (const SfxInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_POS_Y
))
1616 nPosDY
= pPoolItem
->GetValue() - aRect
.Top();
1620 if (const SfxUInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_WIDTH
))
1622 nSizX
= pPoolItem
->GetValue();
1626 if (const SfxUInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_HEIGHT
))
1628 nSizY
= pPoolItem
->GetValue();
1633 if (bTiledRendering
&& SfxItemState::SET
!= rAttr
.GetItemState(SID_ATTR_TRANSFORM_SIZE_POINT
))
1634 eSizePoint
= RectPoint::LT
;
1636 eSizePoint
= static_cast<RectPoint
>(rAttr
.Get(SID_ATTR_TRANSFORM_SIZE_POINT
).GetValue());
1640 if (const SdrAngleItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_DELTA_ANGLE
))
1642 nRotateAngle
= pPoolItem
->GetValue();
1643 bRotate
= (nRotateAngle
!= 0_deg100
);
1647 if (const SdrAngleItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_ANGLE
))
1649 nRotateAngle
= pPoolItem
->GetValue() - nOldRotateAngle
;
1650 bRotate
= (nRotateAngle
!= 0_deg100
);
1653 // position rotation point x
1654 if(bRotate
|| rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_ROT_X
))
1655 nRotateX
= rAttr
.Get(SID_ATTR_TRANSFORM_ROT_X
).GetValue();
1657 // position rotation point y
1658 if(bRotate
|| rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_ROT_Y
))
1659 nRotateY
= rAttr
.Get(SID_ATTR_TRANSFORM_ROT_Y
).GetValue();
1662 if (const SdrAngleItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_SHEAR
))
1664 Degree100 nNewShearAngle
=pPoolItem
->GetValue();
1665 if (nNewShearAngle
>SDRMAXSHEAR
) nNewShearAngle
=SDRMAXSHEAR
;
1666 if (nNewShearAngle
<-SDRMAXSHEAR
) nNewShearAngle
=-SDRMAXSHEAR
;
1667 if (nNewShearAngle
!=nOldShearAngle
) {
1668 bShearVert
= rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL
).GetValue();
1670 nShearAngle
=nNewShearAngle
;
1672 if (nNewShearAngle
!=0_deg100
&& nOldShearAngle
!=0_deg100
) {
1674 double nOld
= tan(toRadians(nOldShearAngle
));
1675 double nNew
= tan(toRadians(nNewShearAngle
));
1677 nNew
= basegfx::rad2deg
<100>(atan(nNew
));
1678 nShearAngle
=Degree100(FRound(nNew
));
1680 nShearAngle
=nNewShearAngle
-nOldShearAngle
;
1683 bShear
=nShearAngle
!=0_deg100
;
1685 nShearX
= rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_X
).GetValue();
1686 nShearY
= rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_Y
).GetValue();
1692 if (const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_AUTOWIDTH
))
1694 bool bAutoGrow
= pPoolItem
->GetValue();
1695 aSetAttr
.Put(makeSdrTextAutoGrowWidthItem(bAutoGrow
));
1699 if (const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_AUTOHEIGHT
))
1701 bool bAutoGrow
= pPoolItem
->GetValue();
1702 aSetAttr
.Put(makeSdrTextAutoGrowHeightItem(bAutoGrow
));
1707 if (m_bEdgeRadiusAllowed
)
1708 if (const SdrMetricItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_CORNER_RADIUS
))
1710 tools::Long nRadius
= pPoolItem
->GetValue();
1711 aSetAttr
.Put(makeSdrEckenradiusItem(nRadius
));
1715 ForcePossibilities();
1717 BegUndo(SvxResId(STR_EditTransform
),GetDescriptionOfMarkedObjects());
1720 SetAttrToMarked(aSetAttr
,false);
1723 // change size and height
1724 if (bChgSiz
&& (m_bResizeFreeAllowed
|| m_bResizePropAllowed
)) {
1725 Fraction
aWdt(nSizX
,aRect
.Right()-aRect
.Left());
1726 Fraction
aHgt(nSizY
,aRect
.Bottom()-aRect
.Top());
1727 Point
aRef(ImpGetPoint(aRect
,eSizePoint
));
1729 if(GetSdrPageView())
1731 GetSdrPageView()->PagePosToLogic(aRef
);
1734 ResizeMultMarkedObj(aRef
, aWdt
, aHgt
, bChgWdh
, bChgHgt
);
1738 if (bRotate
&& (m_bRotateFreeAllowed
|| m_bRotate90Allowed
)) {
1739 Point
aRef(nRotateX
,nRotateY
);
1741 if(GetSdrPageView())
1743 GetSdrPageView()->PagePosToLogic(aRef
);
1746 RotateMarkedObj(aRef
,nRotateAngle
);
1749 // set rotation point position
1750 if(bModeIsRotate
&& (nRotateX
!= nOldRotateX
|| nRotateY
!= nOldRotateY
))
1752 Point
aNewRef1(nRotateX
, nRotateY
);
1754 if(GetSdrPageView())
1756 GetSdrPageView()->PagePosToLogic(aNewRef1
);
1763 if (bShear
&& m_bShearAllowed
) {
1764 Point
aRef(nShearX
,nShearY
);
1766 if(GetSdrPageView())
1768 GetSdrPageView()->PagePosToLogic(aRef
);
1771 ShearMarkedObj(aRef
,nShearAngle
,bShearVert
);
1774 // ShearMarkedObj creates a linear combination of the existing transformation and
1775 // the new shear to apply. If the object is already transformed (e.g. rotated) the
1776 // linear combination will not decompose to the same start values again, but to a
1777 // new combination. Thus it makes no sense to check if the wanted shear is reached
1778 // or not. Taking out.
1782 if (bChgPos
&& m_bMoveAllowed
) {
1783 MoveMarkedObj(Size(nPosDX
,nPosDY
));
1786 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1788 if(const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_PROTECT_POS
))
1790 const bool bProtPos(pPoolItem
->GetValue());
1791 bool bChanged(false);
1793 for(size_t i
= 0; i
< nMarkCount
; ++i
)
1795 pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1797 if(pObj
->IsMoveProtect() != bProtPos
)
1800 pObj
->SetMoveProtect(bProtPos
);
1804 pObj
->SetResizeProtect(true);
1811 m_bMoveProtect
= bProtPos
;
1815 m_bResizeProtect
= true;
1818 // #i77187# there is no simple method to get the toolbars updated
1819 // in the application. The App is listening to selection change and i
1820 // will use it here (even if not true). It's acceptable since changing
1821 // this model data is pretty rare and only possible using the F4 dialog
1822 MarkListHasChanged();
1829 if(const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_PROTECT_SIZE
))
1831 const bool bProtSize(pPoolItem
->GetValue());
1832 bool bChanged(false);
1834 for(size_t i
= 0; i
< nMarkCount
; ++i
)
1836 pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1838 if(pObj
->IsResizeProtect() != bProtSize
)
1841 pObj
->SetResizeProtect(bProtSize
);
1847 m_bResizeProtect
= bProtSize
;
1849 // #i77187# see above
1850 MarkListHasChanged();
1859 bool SdrEditView::IsAlignPossible() const
1860 { // at least two selected objects, at least one of them movable
1861 ForcePossibilities();
1862 const size_t nCount
=GetMarkedObjectCount();
1863 if (nCount
==0) return false; // nothing selected!
1864 if (nCount
==1) return m_bMoveAllowed
; // align single object to page
1865 return m_bOneOrMoreMovable
; // otherwise: MarkCount>=2
1868 void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor
, SdrVertAlign eVert
)
1870 if (eHor
==SdrHorAlign::NONE
&& eVert
==SdrVertAlign::NONE
)
1873 SortMarkedObjects();
1874 if (!GetMarkedObjectCount())
1877 const bool bUndo
= IsUndoEnabled();
1880 EndTextEditCurrentView();
1881 OUString
aStr(GetDescriptionOfMarkedObjects());
1882 if (eHor
==SdrHorAlign::NONE
)
1886 case SdrVertAlign::Top
:
1887 aStr
= ImpGetDescriptionString(STR_EditAlignVTop
);
1889 case SdrVertAlign::Bottom
:
1890 aStr
= ImpGetDescriptionString(STR_EditAlignVBottom
);
1892 case SdrVertAlign::Center
:
1893 aStr
= ImpGetDescriptionString(STR_EditAlignVCenter
);
1898 else if (eVert
==SdrVertAlign::NONE
)
1902 case SdrHorAlign::Left
:
1903 aStr
= ImpGetDescriptionString(STR_EditAlignHLeft
);
1905 case SdrHorAlign::Right
:
1906 aStr
= ImpGetDescriptionString(STR_EditAlignHRight
);
1908 case SdrHorAlign::Center
:
1909 aStr
= ImpGetDescriptionString(STR_EditAlignHCenter
);
1914 else if (eHor
==SdrHorAlign::Center
&& eVert
==SdrVertAlign::Center
)
1916 aStr
= ImpGetDescriptionString(STR_EditAlignCenter
);
1920 aStr
= ImpGetDescriptionString(STR_EditAlign
);
1925 tools::Rectangle aBound
;
1926 const size_t nMarkCount
=GetMarkedObjectCount();
1927 bool bHasFixed
=false;
1928 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1930 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1931 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
1932 SdrObjTransformInfoRec aInfo
;
1933 pObj
->TakeObjInfo(aInfo
);
1934 if (!aInfo
.bMoveAllowed
|| pObj
->IsMoveProtect())
1936 tools::Rectangle
aObjRect(pObj
->GetSnapRect());
1937 aBound
.Union(aObjRect
);
1944 { // align single object to page
1945 const SdrObject
* pObj
=GetMarkedObjectByIndex(0);
1946 const SdrPage
* pPage
=pObj
->getSdrPageFromSdrObject();
1947 const SdrPageGridFrameList
* pGFL
=pPage
->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj
->GetSnapRect()));
1948 const SdrPageGridFrame
* pFrame
=nullptr;
1949 if (pGFL
!=nullptr && pGFL
->GetCount()!=0)
1951 pFrame
=&((*pGFL
)[0]);
1954 if (pFrame
!=nullptr)
1956 aBound
=pFrame
->GetUserArea();
1960 aBound
=tools::Rectangle(pPage
->GetLeftBorder(),pPage
->GetUpperBorder(),
1961 pPage
->GetWidth()-pPage
->GetRightBorder(),
1962 pPage
->GetHeight()-pPage
->GetLowerBorder());
1967 aBound
=GetMarkedObjRect();
1970 Point
aCenter(aBound
.Center());
1971 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1973 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
1974 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
1975 SdrObjTransformInfoRec aInfo
;
1976 pObj
->TakeObjInfo(aInfo
);
1977 if (aInfo
.bMoveAllowed
&& !pObj
->IsMoveProtect())
1979 tools::Long nXMov
=0;
1980 tools::Long nYMov
=0;
1981 tools::Rectangle
aObjRect(pObj
->GetSnapRect());
1984 case SdrVertAlign::Top
: nYMov
=aBound
.Top() -aObjRect
.Top() ; break;
1985 case SdrVertAlign::Bottom
: nYMov
=aBound
.Bottom()-aObjRect
.Bottom() ; break;
1986 case SdrVertAlign::Center
: nYMov
=aCenter
.Y() -aObjRect
.Center().Y(); break;
1991 case SdrHorAlign::Left
: nXMov
=aBound
.Left() -aObjRect
.Left() ; break;
1992 case SdrHorAlign::Right
: nXMov
=aBound
.Right() -aObjRect
.Right() ; break;
1993 case SdrHorAlign::Center
: nXMov
=aCenter
.X() -aObjRect
.Center().X(); break;
1996 if (nXMov
!=0 || nYMov
!=0)
1998 // SdrEdgeObj needs an extra SdrUndoGeoObj since the
1999 // connections may need to be saved
2002 if( dynamic_cast<SdrEdgeObj
*>(pObj
) )
2004 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
2007 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoMoveObject(*pObj
,Size(nXMov
,nYMov
)));
2010 pObj
->Move(Size(nXMov
,nYMov
));
2019 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */