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/rectenum.hxx>
38 #include <svx/sdr/contact/viewcontact.hxx>
39 #include <svx/sdooitm.hxx>
40 #include <svx/sderitm.hxx>
41 #include <svx/sdtagitm.hxx>
42 #include <svx/svdedtv.hxx>
43 #include <svx/svdetc.hxx>
44 #include <svx/svdopath.hxx>
45 #include <svx/svdpage.hxx>
46 #include <svx/svdpagv.hxx>
47 #include <svx/svdtrans.hxx>
48 #include <svx/svdundo.hxx>
49 #include <svx/svxids.hrc>
50 #include <sxallitm.hxx>
51 #include <sxmovitm.hxx>
52 #include <sxreaitm.hxx>
53 #include <sxreoitm.hxx>
54 #include <sxroaitm.hxx>
55 #include <sxrooitm.hxx>
56 #include <sxsalitm.hxx>
57 #include <sxsoitm.hxx>
58 #include <sxtraitm.hxx>
59 #include <svx/xlnedwit.hxx>
60 #include <svx/xlnstwit.hxx>
61 #include <svx/xlnwtit.hxx>
62 #include <svx/xlnclit.hxx>
63 #include <svx/xflclit.hxx>
64 #include <svx/xlntrit.hxx>
65 #include <svx/xfltrit.hxx>
66 #include <svx/sdprcitm.hxx>
67 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
68 #include <rtl/ustring.hxx>
69 #include <sfx2/viewsh.hxx>
70 #include <comphelper/lok.hxx>
71 #include <osl/diagnose.h>
76 void SdrEditView::SetMarkedObjRect(const tools::Rectangle
& rRect
)
78 DBG_ASSERT(!rRect
.IsEmpty(),"SetMarkedObjRect() with an empty Rect does not make sense.");
81 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
82 const size_t nCount
=rMarkList
.GetMarkCount();
83 if (nCount
==0) return;
84 tools::Rectangle
aR0(GetMarkedObjRect());
85 DBG_ASSERT(!aR0
.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() is empty.");
86 if (aR0
.IsEmpty()) return;
87 tools::Long x0
=aR0
.Left();
88 tools::Long y0
=aR0
.Top();
89 tools::Long w0
=aR0
.Right()-x0
;
90 tools::Long h0
=aR0
.Bottom()-y0
;
91 tools::Long x1
=rRect
.Left();
92 tools::Long y1
=rRect
.Top();
93 tools::Long w1
=rRect
.Right()-x1
;
94 tools::Long h1
=rRect
.Bottom()-y1
;
96 const bool bUndo
= IsUndoEnabled();
99 EndTextEditCurrentView();
100 BegUndo(ImpGetDescriptionString(STR_EditPosSize
));
103 for (size_t nm
=0; nm
<nCount
; ++nm
)
105 SdrMark
* pM
=rMarkList
.GetMark(nm
);
106 SdrObject
* pO
=pM
->GetMarkedSdrObj();
108 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
110 tools::Rectangle
aR1(pO
->GetSnapRect());
118 { // transform aR1 to aR0 after rRect
120 BigInt
l(aR1
.Left());
121 BigInt
r(aR1
.Right());
123 BigInt
b(aR1
.Bottom());
136 aR1
.SetLeft(tools::Long(l
) );
137 aR1
.SetRight(tools::Long(r
) );
138 aR1
.SetTop(tools::Long(t
) );
139 aR1
.SetBottom(tools::Long(b
) );
142 pO
->SetSnapRect(aR1
);
144 OSL_FAIL("SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect");
151 std::vector
< std::unique_ptr
<SdrUndoAction
> > SdrEditView::CreateConnectorUndo( const SdrObject
& rO
)
153 std::vector
< std::unique_ptr
<SdrUndoAction
> > vUndoActions
;
155 if ( rO
.GetBroadcaster() )
157 const SdrPage
* pPage
= rO
.getSdrPageFromSdrObject();
160 SdrObjListIter
aIter(pPage
, SdrIterMode::DeepWithGroups
);
161 while( aIter
.IsMore() )
163 SdrObject
* pPartObj
= aIter
.Next();
164 if ( dynamic_cast<const SdrEdgeObj
*>( pPartObj
) != nullptr )
166 if ( ( pPartObj
->GetConnectedNode( false ) == &rO
) ||
167 ( pPartObj
->GetConnectedNode( true ) == &rO
) )
169 vUndoActions
.push_back(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pPartObj
));
178 void SdrEditView::AddUndoActions( std::vector
< std::unique_ptr
<SdrUndoAction
> > aUndoActions
)
180 for (auto & rAction
: aUndoActions
)
181 AddUndo( std::move(rAction
) );
184 void SdrEditView::MoveMarkedObj(const Size
& rSiz
, bool bCopy
)
186 const bool bUndo
= IsUndoEnabled();
187 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
191 EndTextEditCurrentView();
192 OUString
aStr(SvxResId(STR_EditMove
));
194 aStr
+= SvxResId(STR_EditWithCopy
);
195 // needs its own UndoGroup because of its parameters
196 BegUndo(aStr
,rMarkList
.GetMarkDescription(),SdrRepeatFunc::Move
);
202 const size_t nMarkCount
=rMarkList
.GetMarkCount();
203 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
205 SdrMark
* pM
=rMarkList
.GetMark(nm
);
206 SdrObject
* pO
=pM
->GetMarkedSdrObj();
209 AddUndoActions( CreateConnectorUndo( *pO
) );
210 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoMoveObject(*pO
,rSiz
));
219 bool SdrEditView::IsMarkedObjSizeValid(Size
& aTargetSize
)
221 SdrMark
* pM
=GetMarkedObjectList().GetMark(0);
222 SdrObject
* pO
=pM
->GetMarkedSdrObj();
223 if (!pO
->IsSizeValid(aTargetSize
))
228 void SdrEditView::ResizeMarkedObj(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bCopy
)
230 const bool bUndo
= IsUndoEnabled();
233 EndTextEditCurrentView();
234 OUString aStr
{ImpGetDescriptionString(STR_EditResize
)};
236 aStr
+=SvxResId(STR_EditWithCopy
);
243 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
244 const size_t nMarkCount
=rMarkList
.GetMarkCount();
245 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
247 SdrMark
* pM
=rMarkList
.GetMark(nm
);
248 SdrObject
* pO
=pM
->GetMarkedSdrObj();
251 AddUndoActions( CreateConnectorUndo( *pO
) );
252 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
254 pO
->Resize(rRef
,xFact
,yFact
);
260 void SdrEditView::ResizeMultMarkedObj(const Point
& rRef
,
261 const Fraction
& xFact
,
262 const Fraction
& yFact
,
266 const bool bUndo
= IsUndoEnabled();
269 EndTextEditCurrentView();
270 BegUndo(ImpGetDescriptionString(STR_EditResize
));
273 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
274 const size_t nMarkCount
=rMarkList
.GetMarkCount();
275 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
277 SdrMark
* pM
=rMarkList
.GetMark(nm
);
278 SdrObject
* pO
=pM
->GetMarkedSdrObj();
281 AddUndoActions( CreateConnectorUndo( *pO
) );
282 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
286 if (bWdh
&& xFact
.IsValid() && bHgt
&& yFact
.IsValid())
287 pO
->Resize(rRef
, xFact
, yFact
);
288 else if (bWdh
&& xFact
.IsValid())
289 pO
->Resize(rRef
, xFact
, aFrac
);
290 else if (bHgt
&& yFact
.IsValid())
291 pO
->Resize(rRef
, aFrac
, yFact
);
297 Degree100
SdrEditView::GetMarkedObjRotate() const
299 Degree100
nRetval(0);
301 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
302 if(rMarkList
.GetMarkCount())
304 SdrMark
* pM
= rMarkList
.GetMark(0);
305 SdrObject
* pO
= pM
->GetMarkedSdrObj();
307 nRetval
= pO
->GetRotateAngle();
313 void SdrEditView::RotateMarkedObj(const Point
& rRef
, Degree100 nAngle
, bool bCopy
)
315 const bool bUndo
= IsUndoEnabled();
318 EndTextEditCurrentView();
319 OUString aStr
{ImpGetDescriptionString(STR_EditRotate
)};
320 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
327 double nSin
= sin(toRadians(nAngle
));
328 double nCos
= cos(toRadians(nAngle
));
329 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
330 const size_t nMarkCount(rMarkList
.GetMarkCount());
334 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
336 for(size_t nm
= 0; nm
< nMarkCount
; ++nm
)
338 SdrMark
* pM
= rMarkList
.GetMark(nm
);
339 SdrObject
* pO
= pM
->GetMarkedSdrObj();
343 // extra undo actions for changed connector which now may hold its laid out path (SJ)
344 AddUndoActions( CreateConnectorUndo( *pO
) );
346 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
349 // set up a scene updater if object is a 3d object
350 if(DynCastE3dObject(pO
))
352 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pO
));
355 pO
->Rotate(rRef
,nAngle
,nSin
,nCos
);
358 // fire scene updaters
359 while(!aUpdaters
.empty())
361 delete aUpdaters
.back();
362 aUpdaters
.pop_back();
370 void SdrEditView::MirrorMarkedObj(const Point
& rRef1
, const Point
& rRef2
, bool bCopy
)
372 const bool bUndo
= IsUndoEnabled();
376 EndTextEditCurrentView();
378 Point
aDif(rRef2
-rRef1
);
380 aStr
= ImpGetDescriptionString(STR_EditMirrorHori
);
381 else if (aDif
.Y()==0)
382 aStr
= ImpGetDescriptionString(STR_EditMirrorVert
);
383 else if (std::abs(aDif
.X()) == std::abs(aDif
.Y()))
384 aStr
= ImpGetDescriptionString(STR_EditMirrorDiag
);
386 aStr
= ImpGetDescriptionString(STR_EditMirrorFree
);
387 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
394 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
395 const size_t nMarkCount(rMarkList
.GetMarkCount());
399 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
401 for(size_t nm
= 0; nm
< nMarkCount
; ++nm
)
403 SdrMark
* pM
= rMarkList
.GetMark(nm
);
404 SdrObject
* pO
= pM
->GetMarkedSdrObj();
408 // extra undo actions for changed connector which now may hold its laid out path (SJ)
409 AddUndoActions( CreateConnectorUndo( *pO
) );
411 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
414 // set up a scene updater if object is a 3d object
415 if(DynCastE3dObject(pO
))
417 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pO
));
420 pO
->Mirror(rRef1
,rRef2
);
423 // fire scene updaters
424 while(!aUpdaters
.empty())
426 delete aUpdaters
.back();
427 aUpdaters
.pop_back();
435 void SdrEditView::MirrorMarkedObjHorizontal()
437 Point
aCenter(GetMarkedObjRect().Center());
440 MirrorMarkedObj(aCenter
,aPt2
);
443 void SdrEditView::MirrorMarkedObjVertical()
445 Point
aCenter(GetMarkedObjRect().Center());
448 MirrorMarkedObj(aCenter
,aPt2
);
451 Degree100
SdrEditView::GetMarkedObjShear() const
456 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
457 const size_t nMarkCount
=rMarkList
.GetMarkCount();
458 for (size_t nm
=0; nm
<nMarkCount
&& bOk
; ++nm
) {
459 SdrMark
* pM
=rMarkList
.GetMark(nm
);
460 SdrObject
* pO
=pM
->GetMarkedSdrObj();
461 Degree100 nAngle2
=pO
->GetShearAngle();
462 if (b1st
) nAngle
=nAngle2
;
463 else if (nAngle2
!=nAngle
) bOk
=false;
466 if (nAngle
>SDRMAXSHEAR
) nAngle
=SDRMAXSHEAR
;
467 if (nAngle
<-SDRMAXSHEAR
) nAngle
=-SDRMAXSHEAR
;
468 if (!bOk
) nAngle
=0_deg100
;
472 void SdrEditView::ShearMarkedObj(const Point
& rRef
, Degree100 nAngle
, bool bVShear
, bool bCopy
)
474 const bool bUndo
= IsUndoEnabled();
478 EndTextEditCurrentView();
479 OUString aStr
{ImpGetDescriptionString(STR_EditShear
)};
481 aStr
+=SvxResId(STR_EditWithCopy
);
488 double nTan
= tan(toRadians(nAngle
));
489 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
490 const size_t nMarkCount
=rMarkList
.GetMarkCount();
491 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
493 SdrMark
* pM
=rMarkList
.GetMark(nm
);
494 SdrObject
* pO
=pM
->GetMarkedSdrObj();
497 AddUndoActions( CreateConnectorUndo( *pO
) );
498 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
500 pO
->Shear(rRef
,nAngle
,nTan
,bVShear
);
507 void SdrEditView::ImpCrookObj(SdrObject
* pO
, const Point
& rRef
, const Point
& rRad
,
508 SdrCrookMode eMode
, bool bVertical
, bool bNoContortion
, bool bRotate
, const tools::Rectangle
& rMarkRect
)
510 SdrPathObj
* pPath
=dynamic_cast<SdrPathObj
*>( pO
);
513 if(pPath
!=nullptr && !bNoContortion
)
515 XPolyPolygon
aXPP(pPath
->GetPathPoly());
517 case SdrCrookMode::Rotate
: CrookRotatePoly (aXPP
,rRef
,rRad
,bVertical
); break;
518 case SdrCrookMode::Slant
: CrookSlantPoly (aXPP
,rRef
,rRad
,bVertical
); break;
519 case SdrCrookMode::Stretch
: CrookStretchPoly(aXPP
,rRef
,rRad
,bVertical
,rMarkRect
); break;
521 pPath
->SetPathPoly(aXPP
.getB2DPolyPolygon());
525 if(!bDone
&& !pPath
&& pO
->IsPolyObj() && 0 != pO
->GetPointCount())
527 // for PolyObj's, but NOT for SdrPathObj's, e.g. the measurement object
528 sal_uInt32
nPointCount(pO
->GetPointCount());
529 XPolygon
aXP(static_cast<sal_uInt16
>(nPointCount
));
532 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
534 Point
aPt(pO
->GetPoint(nPtNum
));
535 aXP
[static_cast<sal_uInt16
>(nPtNum
)]=aPt
;
540 case SdrCrookMode::Rotate
: CrookRotatePoly (aXP
,rRef
,rRad
,bVertical
); break;
541 case SdrCrookMode::Slant
: CrookSlantPoly (aXP
,rRef
,rRad
,bVertical
); break;
542 case SdrCrookMode::Stretch
: CrookStretchPoly(aXP
,rRef
,rRad
,bVertical
,rMarkRect
); break;
545 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
547 // broadcasting could be optimized here, but for the
548 // current two points of the measurement object, it's fine
549 pO
->SetPoint(aXP
[static_cast<sal_uInt16
>(nPtNum
)],nPtNum
);
558 // for all others or if bNoContortion
559 Point
aCtr0(pO
->GetSnapRect().Center());
562 double nSin(0.0), nCos(1.0);
565 if(0 != rRad
.X() && 0 != rRad
.Y())
571 case SdrCrookMode::Rotate
: nAngle
=CrookRotateXPoint (aCtr1
,nullptr,nullptr,rRef
,rRad
,nSin
,nCos
,bVertical
); bRotOk
=bRotate
; break;
572 case SdrCrookMode::Slant
: nAngle
=CrookSlantXPoint (aCtr1
,nullptr,nullptr,rRef
,rRad
,nSin
,nCos
,bVertical
); break;
573 case SdrCrookMode::Stretch
: nAngle
=CrookStretchXPoint(aCtr1
,nullptr,nullptr,rRef
,rRad
,nSin
,nCos
,bVertical
,rMarkRect
); break;
580 pO
->Rotate(aCtr0
, Degree100(basegfx::fround(basegfx::rad2deg
<100>(nAngle
))), nSin
, nCos
);
582 pO
->Move(Size(aCtr1
.X(),aCtr1
.Y()));
585 void SdrEditView::CrookMarkedObj(const Point
& rRef
, const Point
& rRad
, SdrCrookMode eMode
,
586 bool bVertical
, bool bNoContortion
, bool bCopy
)
588 tools::Rectangle
aMarkRect(GetMarkedObjRect());
589 const bool bUndo
= IsUndoEnabled();
591 bool bRotate
=bNoContortion
&& eMode
==SdrCrookMode::Rotate
&& IsRotateAllowed();
595 EndTextEditCurrentView();
596 OUString aStr
{ImpGetDescriptionString(bNoContortion
? STR_EditCrook
: STR_EditCrookContortion
)};
598 aStr
+=SvxResId(STR_EditWithCopy
);
605 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
606 const size_t nMarkCount
=rMarkList
.GetMarkCount();
607 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
609 SdrMark
* pM
=rMarkList
.GetMark(nm
);
610 SdrObject
* pO
=pM
->GetMarkedSdrObj();
612 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
614 const SdrObjList
* pOL
=pO
->GetSubList();
615 if (bNoContortion
|| pOL
==nullptr) {
616 ImpCrookObj(pO
,rRef
,rRad
,eMode
,bVertical
,bNoContortion
,bRotate
,aMarkRect
);
618 SdrObjListIter
aIter(pOL
,SdrIterMode::DeepNoGroups
);
619 while (aIter
.IsMore()) {
620 SdrObject
* pO1
=aIter
.Next();
621 ImpCrookObj(pO1
,rRef
,rRad
,eMode
,bVertical
,bNoContortion
,bRotate
,aMarkRect
);
630 void SdrEditView::ImpDistortObj(SdrObject
* pO
, const tools::Rectangle
& rRef
, const XPolygon
& rDistortedRect
, bool bNoContortion
)
632 SdrPathObj
* pPath
= dynamic_cast<SdrPathObj
*>( pO
);
634 if(!bNoContortion
&& pPath
)
636 XPolyPolygon
aXPP(pPath
->GetPathPoly());
637 aXPP
.Distort(rRef
, rDistortedRect
);
638 pPath
->SetPathPoly(aXPP
.getB2DPolyPolygon());
640 else if(pO
->IsPolyObj())
642 // e. g. for the measurement object
643 sal_uInt32
nPointCount(pO
->GetPointCount());
644 XPolygon
aXP(static_cast<sal_uInt16
>(nPointCount
));
647 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
649 Point
aPt(pO
->GetPoint(nPtNum
));
650 aXP
[static_cast<sal_uInt16
>(nPtNum
)]=aPt
;
653 aXP
.Distort(rRef
, rDistortedRect
);
655 for(nPtNum
= 0; nPtNum
< nPointCount
; nPtNum
++)
657 // broadcasting could be optimized here, but for the
658 // current two points of the measurement object it's fine
659 pO
->SetPoint(aXP
[static_cast<sal_uInt16
>(nPtNum
)],nPtNum
);
664 void SdrEditView::DistortMarkedObj(const tools::Rectangle
& rRef
, const XPolygon
& rDistortedRect
, bool bNoContortion
, bool bCopy
)
666 const bool bUndo
= IsUndoEnabled();
670 EndTextEditCurrentView();
671 OUString aStr
{ImpGetDescriptionString(STR_EditDistort
)};
673 aStr
+=SvxResId(STR_EditWithCopy
);
680 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
681 const size_t nMarkCount
=rMarkList
.GetMarkCount();
682 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
684 SdrMark
* pM
=rMarkList
.GetMark(nm
);
685 SdrObject
* pO
=pM
->GetMarkedSdrObj();
687 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pO
));
689 tools::Rectangle
aRefRect(rRef
);
690 const SdrObjList
* pOL
=pO
->GetSubList();
691 if (bNoContortion
|| pOL
==nullptr) {
692 ImpDistortObj(pO
,aRefRect
,rDistortedRect
,bNoContortion
);
694 SdrObjListIter
aIter(pOL
,SdrIterMode::DeepNoGroups
);
695 while (aIter
.IsMore()) {
696 SdrObject
* pO1
=aIter
.Next();
697 ImpDistortObj(pO1
,aRefRect
,rDistortedRect
,bNoContortion
);
706 void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet
& rAttr
)
708 // bReplaceAll has no effect here
709 tools::Rectangle
aAllSnapRect(GetMarkedObjRect());
710 if (const SdrTransformRef1XItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF1X
))
712 tools::Long n
= pPoolItem
->GetValue();
713 SetRef1(Point(n
,GetRef1().Y()));
715 if (const SdrTransformRef1YItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF1Y
))
717 tools::Long n
= pPoolItem
->GetValue();
718 SetRef1(Point(GetRef1().X(),n
));
720 if (const SdrTransformRef2XItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF2X
))
722 tools::Long n
= pPoolItem
->GetValue();
723 SetRef2(Point(n
,GetRef2().Y()));
725 if (const SdrTransformRef2YItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_TRANSFORMREF2Y
))
727 tools::Long n
= pPoolItem
->GetValue();
728 SetRef2(Point(GetRef2().X(),n
));
730 tools::Long nAllPosX
=0; bool bAllPosX
=false;
731 tools::Long nAllPosY
=0; bool bAllPosY
=false;
732 tools::Long nAllWdt
=0; bool bAllWdt
=false;
733 tools::Long nAllHgt
=0; bool bAllHgt
=false;
735 if (const SdrAllPositionXItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLPOSITIONX
))
737 nAllPosX
= pPoolItem
->GetValue();
738 bAllPosX
=true; bDoIt
=true;
740 if (const SdrAllPositionYItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLPOSITIONY
))
742 nAllPosY
= pPoolItem
->GetValue();
743 bAllPosY
=true; bDoIt
=true;
745 if (const SdrAllSizeWidthItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLSIZEWIDTH
))
747 nAllWdt
= pPoolItem
->GetValue();
748 bAllWdt
=true; bDoIt
=true;
750 if (const SdrAllSizeHeightItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ALLSIZEHEIGHT
))
752 nAllHgt
= pPoolItem
->GetValue();
753 bAllHgt
=true; bDoIt
=true;
756 tools::Rectangle
aRect(aAllSnapRect
); // TODO: change this for PolyPt's and GluePt's!!!
757 if (bAllPosX
) aRect
.Move(nAllPosX
-aRect
.Left(),0);
758 if (bAllPosY
) aRect
.Move(0,nAllPosY
-aRect
.Top());
759 if (bAllWdt
) aRect
.SetRight(aAllSnapRect
.Left()+nAllWdt
);
760 if (bAllHgt
) aRect
.SetBottom(aAllSnapRect
.Top()+nAllHgt
);
761 SetMarkedObjRect(aRect
);
763 if (const SdrResizeXAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_RESIZEXALL
))
765 Fraction aXFact
= pPoolItem
->GetValue();
766 ResizeMarkedObj(aAllSnapRect
.TopLeft(),aXFact
,Fraction(1,1));
768 if (const SdrResizeYAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_RESIZEYALL
))
770 Fraction aYFact
= pPoolItem
->GetValue();
771 ResizeMarkedObj(aAllSnapRect
.TopLeft(),Fraction(1,1),aYFact
);
773 if (const SdrRotateAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_ROTATEALL
))
775 Degree100 nAngle
= pPoolItem
->GetValue();
776 RotateMarkedObj(aAllSnapRect
.Center(),nAngle
);
778 if (const SdrHorzShearAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_HORZSHEARALL
))
780 Degree100 nAngle
= pPoolItem
->GetValue();
781 ShearMarkedObj(aAllSnapRect
.Center(),nAngle
);
783 if (const SdrVertShearAllItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_VERTSHEARALL
))
785 Degree100 nAngle
= pPoolItem
->GetValue();
786 ShearMarkedObj(aAllSnapRect
.Center(),nAngle
,true);
789 const bool bUndo
= IsUndoEnabled();
791 // TODO: check if WhichRange is necessary.
792 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
793 const size_t nMarkCount
=rMarkList
.GetMarkCount();
794 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
796 const SdrMark
* pM
=rMarkList
.GetMark(nm
);
797 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
799 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
801 pObj
->ApplyNotPersistAttr(rAttr
);
805 void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet
& rAttr
) const
807 // TODO: Take into account the origin and PvPos.
808 tools::Rectangle
aAllSnapRect(GetMarkedObjRect()); // TODO: change this for PolyPt's and GluePt's!!!
809 tools::Long nAllSnapPosX
=aAllSnapRect
.Left();
810 tools::Long nAllSnapPosY
=aAllSnapRect
.Top();
811 tools::Long nAllSnapWdt
=aAllSnapRect
.GetWidth()-1;
812 tools::Long nAllSnapHgt
=aAllSnapRect
.GetHeight()-1;
813 // TODO: could go into CheckPossibilities
814 bool bMovProtect
= false, bMovProtectDC
= false;
815 bool bSizProtect
= false, bSizProtectDC
= false;
816 bool bPrintable
= true, bPrintableDC
= false;
817 bool bVisible
= true, bVisibleDC
= false;
818 SdrLayerID
nLayerId(0);
820 tools::Long nSnapPosX
=0; bool bSnapPosXDC
=false;
821 tools::Long nSnapPosY
=0; bool bSnapPosYDC
=false;
822 tools::Long nSnapWdt
=0; bool bSnapWdtDC
=false;
823 tools::Long nSnapHgt
=0; bool bSnapHgtDC
=false;
824 tools::Long nLogicWdt
=0; bool bLogicWdtDC
=false,bLogicWdtDiff
=false;
825 tools::Long nLogicHgt
=0; bool bLogicHgtDC
=false,bLogicHgtDiff
=false;
826 Degree100
nRotAngle(0); bool bRotAngleDC
=false;
827 Degree100
nShrAngle(0); bool bShrAngleDC
=false;
828 tools::Rectangle aSnapRect
;
829 tools::Rectangle aLogicRect
;
830 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
831 const size_t nMarkCount
=rMarkList
.GetMarkCount();
832 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
833 const SdrMark
* pM
=rMarkList
.GetMark(nm
);
834 const SdrObject
* pObj
=pM
->GetMarkedSdrObj();
836 nLayerId
=pObj
->GetLayer();
837 bMovProtect
=pObj
->IsMoveProtect();
838 bSizProtect
=pObj
->IsResizeProtect();
839 bPrintable
=pObj
->IsPrintable();
840 bVisible
= pObj
->IsVisible();
841 tools::Rectangle
aSnapRect2(pObj
->GetSnapRect());
842 tools::Rectangle
aLogicRect2(pObj
->GetLogicRect());
843 nSnapPosX
=aSnapRect2
.Left();
844 nSnapPosY
=aSnapRect2
.Top();
845 nSnapWdt
=aSnapRect2
.GetWidth()-1;
846 nSnapHgt
=aSnapRect2
.GetHeight()-1;
847 nLogicWdt
=aLogicRect2
.GetWidth()-1;
848 nLogicHgt
=aLogicRect2
.GetHeight()-1;
849 bLogicWdtDiff
=nLogicWdt
!=nSnapWdt
;
850 bLogicHgtDiff
=nLogicHgt
!=nSnapHgt
;
851 nRotAngle
=pObj
->GetRotateAngle();
852 nShrAngle
=pObj
->GetShearAngle();
854 if (!bLayerDC
&& nLayerId
!=pObj
->GetLayer()) bLayerDC
= true;
855 if (!bMovProtectDC
&& bMovProtect
!=pObj
->IsMoveProtect()) bMovProtectDC
= true;
856 if (!bSizProtectDC
&& bSizProtect
!=pObj
->IsResizeProtect()) bSizProtectDC
= true;
857 if (!bPrintableDC
&& bPrintable
!=pObj
->IsPrintable()) bPrintableDC
= true;
858 if (!bVisibleDC
&& bVisible
!=pObj
->IsVisible()) bVisibleDC
=true;
859 if (!bRotAngleDC
&& nRotAngle
!=pObj
->GetRotateAngle()) bRotAngleDC
=true;
860 if (!bShrAngleDC
&& nShrAngle
!=pObj
->GetShearAngle()) bShrAngleDC
=true;
861 if (!bSnapWdtDC
|| !bSnapHgtDC
|| !bSnapPosXDC
|| !bSnapPosYDC
|| !bLogicWdtDiff
|| !bLogicHgtDiff
) {
862 aSnapRect
=pObj
->GetSnapRect();
863 if (nSnapPosX
!=aSnapRect
.Left()) bSnapPosXDC
=true;
864 if (nSnapPosY
!=aSnapRect
.Top()) bSnapPosYDC
=true;
865 if (nSnapWdt
!=aSnapRect
.GetWidth()-1) bSnapWdtDC
=true;
866 if (nSnapHgt
!=aSnapRect
.GetHeight()-1) bSnapHgtDC
=true;
868 if (!bLogicWdtDC
|| !bLogicHgtDC
|| !bLogicWdtDiff
|| !bLogicHgtDiff
) {
869 aLogicRect
=pObj
->GetLogicRect();
870 if (nLogicWdt
!=aLogicRect
.GetWidth()-1) bLogicWdtDC
=true;
871 if (nLogicHgt
!=aLogicRect
.GetHeight()-1) bLogicHgtDC
=true;
872 if (!bLogicWdtDiff
&& aSnapRect
.GetWidth()!=aLogicRect
.GetWidth()) bLogicWdtDiff
=true;
873 if (!bLogicHgtDiff
&& aSnapRect
.GetHeight()!=aLogicRect
.GetHeight()) bLogicHgtDiff
=true;
878 if (bSnapPosXDC
|| nAllSnapPosX
!=nSnapPosX
) rAttr
.Put(SdrAllPositionXItem(nAllSnapPosX
));
879 if (bSnapPosYDC
|| nAllSnapPosY
!=nSnapPosY
) rAttr
.Put(SdrAllPositionYItem(nAllSnapPosY
));
880 if (bSnapWdtDC
|| nAllSnapWdt
!=nSnapWdt
) rAttr
.Put(SdrAllSizeWidthItem(nAllSnapWdt
));
881 if (bSnapHgtDC
|| nAllSnapHgt
!=nSnapHgt
) rAttr
.Put(SdrAllSizeHeightItem(nAllSnapHgt
));
883 // items for pure transformations
884 rAttr
.Put(SdrMoveXItem());
885 rAttr
.Put(SdrMoveYItem());
886 rAttr
.Put(SdrResizeXOneItem());
887 rAttr
.Put(SdrResizeYOneItem());
888 rAttr
.Put(SdrRotateOneItem());
889 rAttr
.Put(SdrHorzShearOneItem());
890 rAttr
.Put(SdrVertShearOneItem());
893 rAttr
.Put(SdrResizeXAllItem());
894 rAttr
.Put(SdrResizeYAllItem());
895 rAttr
.Put(SdrRotateAllItem());
896 rAttr
.Put(SdrHorzShearAllItem());
897 rAttr
.Put(SdrVertShearAllItem());
900 if(meDragMode
== SdrDragMode::Rotate
|| meDragMode
== SdrDragMode::Mirror
)
902 rAttr
.Put(SdrTransformRef1XItem(GetRef1().X()));
903 rAttr
.Put(SdrTransformRef1YItem(GetRef1().Y()));
906 if(meDragMode
== SdrDragMode::Mirror
)
908 rAttr
.Put(SdrTransformRef2XItem(GetRef2().X()));
909 rAttr
.Put(SdrTransformRef2YItem(GetRef2().Y()));
913 SfxItemSet
SdrEditView::GetAttrFromMarked(bool bOnlyHardAttr
) const
915 SfxItemSet
aSet(GetModel().GetItemPool());
916 MergeAttrFromMarked(aSet
,bOnlyHardAttr
);
917 //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there)
918 //so we do not set them here
920 // Do not disable, but clear the items.
921 aSet
.ClearItem(EE_FEATURE_TAB
);
922 aSet
.ClearItem(EE_FEATURE_LINEBR
);
923 aSet
.ClearItem(EE_FEATURE_NOTCONV
);
924 aSet
.ClearItem(EE_FEATURE_FIELD
);
929 void SdrEditView::MergeAttrFromMarked(SfxItemSet
& rAttr
, bool bOnlyHardAttr
) const
931 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
932 const size_t nMarkCount(rMarkList
.GetMarkCount());
934 for(size_t a
= 0; a
< nMarkCount
; ++a
)
936 // #80277# merging was done wrong in the prev version
937 SdrObject
*pObj
= rMarkList
.GetMark(a
)->GetMarkedSdrObj();
943 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
944 SfxWhichIter
aIter(rSet
);
945 sal_uInt16
nWhich(aIter
.FirstWhich());
951 if(SfxItemState::INVALID
== aIter
.GetItemState(false))
952 rAttr
.InvalidateItem(nWhich
);
954 rAttr
.MergeValue(rSet
.Get(nWhich
));
956 else if(SfxItemState::SET
== aIter
.GetItemState(false))
958 const SfxPoolItem
& rItem
= rSet
.Get(nWhich
);
959 rAttr
.MergeValue(rItem
);
962 if (comphelper::LibreOfficeKit::isActive())
967 case XATTR_LINECOLOR
:
969 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_LINECOLOR
);
972 Color aColor
= static_cast<const XLineColorItem
*>(pItem
)->GetColorValue();
973 sPayload
= OUString::number(static_cast<sal_uInt32
>(aColor
));
975 sPayload
= ".uno:XLineColor=" + sPayload
;
980 case XATTR_FILLCOLOR
:
982 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_FILLCOLOR
);
985 Color aColor
= static_cast<const XFillColorItem
*>(pItem
)->GetColorValue();
986 sPayload
= OUString::number(static_cast<sal_uInt32
>(aColor
));
988 sPayload
= ".uno:FillColor=" + sPayload
;
993 case XATTR_FILLTRANSPARENCE
:
995 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_FILLTRANSPARENCE
);
998 sal_uInt16 nTransparency
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
999 sPayload
= OUString::number(nTransparency
);
1001 sPayload
= ".uno:FillTransparence=" + sPayload
;
1006 case XATTR_LINETRANSPARENCE
:
1008 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_LINETRANSPARENCE
);
1011 sal_uInt16 nTransparency
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1012 sPayload
= OUString::number(nTransparency
);
1014 sPayload
= ".uno:LineTransparence=" + sPayload
;
1019 case XATTR_LINEWIDTH
:
1021 const SfxPoolItem
* pItem
= rSet
.GetItem(XATTR_LINEWIDTH
);
1024 sal_uInt32 nWidth
= static_cast<const XLineWidthItem
*>(pItem
)->GetValue();
1025 sPayload
= OUString::number(nWidth
);
1027 sPayload
= ".uno:LineWidth=" + sPayload
;
1032 case SDRATTR_SHADOWTRANSPARENCE
:
1034 const SfxPoolItem
* pItem
= rSet
.GetItem(SDRATTR_SHADOWTRANSPARENCE
);
1037 sal_uInt16 nWidth
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1038 sPayload
= OUString::number(nWidth
);
1040 sPayload
= ".uno:FillShadowTransparency=" + sPayload
;
1046 if (!sPayload
.isEmpty())
1048 if (SfxViewShell
* pViewShell
= GetSfxViewShell())
1050 pViewShell
->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED
,
1051 OUStringToOString(sPayload
, RTL_TEXTENCODING_ASCII_US
));
1056 nWhich
= aIter
.NextWhich();
1061 std::vector
<sal_uInt16
> GetAllCharPropIds(const SfxItemSet
& rSet
)
1063 std::vector
<sal_uInt16
> aCharWhichIds
;
1065 SfxItemIter
aIter(rSet
);
1066 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
1068 if (!IsInvalidItem(pItem
))
1070 sal_uInt16 nWhich
= pItem
->Which();
1071 if (nWhich
>=EE_CHAR_START
&& nWhich
<=EE_CHAR_END
)
1072 aCharWhichIds
.push_back( nWhich
);
1076 return aCharWhichIds
;
1079 std::vector
<sal_uInt16
> GetAllCharPropIds(std::span
< const SfxPoolItem
* const > aChangedItems
)
1081 std::vector
<sal_uInt16
> aCharWhichIds
;
1082 for (const SfxPoolItem
* pItem
: aChangedItems
)
1084 sal_uInt16 nWhich
= pItem
->Which();
1085 if (nWhich
>=EE_CHAR_START
&& nWhich
<=EE_CHAR_END
)
1086 aCharWhichIds
.push_back( nWhich
);
1088 return aCharWhichIds
;
1091 void SdrEditView::SetAttrToMarked(const SfxItemSet
& rAttr
, bool bReplaceAll
)
1093 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1094 if (rMarkList
.GetMarkCount() == 0)
1099 bool bHasEEFeatureItems
=false;
1100 SfxItemIter
aIter(rAttr
);
1101 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); !bHasEEFeatureItems
&& pItem
;
1102 pItem
= aIter
.NextItem())
1104 if (!IsInvalidItem(pItem
)) {
1105 sal_uInt16 nW
=pItem
->Which();
1106 if (nW
>=EE_FEATURE_START
&& nW
<=EE_FEATURE_END
) bHasEEFeatureItems
=true;
1109 if(bHasEEFeatureItems
)
1111 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(nullptr,
1112 VclMessageType::Info
, VclButtonsType::Ok
,
1113 u
"SdrEditView::SetAttrToMarked(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents."_ustr
));
1119 // #103836# if the user sets character attributes to the complete shape,
1120 // we want to remove all hard set character attributes with same
1121 // which ids from the text. We do that later but here we remember
1122 // all character attribute which id's that are set.
1123 std::vector
<sal_uInt16
> aCharWhichIds(GetAllCharPropIds(rAttr
));
1125 // To make Undo reconstruct text attributes correctly after Format.Standard
1126 bool bHasEEItems
=SearchOutlinerItems(rAttr
,bReplaceAll
);
1128 // save additional geometry information when paragraph or character attributes
1129 // are changed and the geometrical shape of the text object might be changed
1130 bool bPossibleGeomChange(false);
1131 SfxWhichIter
aIter(rAttr
);
1132 sal_uInt16 nWhich
= aIter
.FirstWhich();
1133 while(!bPossibleGeomChange
&& nWhich
)
1135 SfxItemState eState
= aIter
.GetItemState();
1136 if(eState
== SfxItemState::SET
)
1138 if((nWhich
>= SDRATTR_TEXT_MINFRAMEHEIGHT
&& nWhich
<= SDRATTR_TEXT_CONTOURFRAME
)
1139 || nWhich
== SDRATTR_3DOBJ_PERCENT_DIAGONAL
1140 || nWhich
== SDRATTR_3DOBJ_BACKSCALE
1141 || nWhich
== SDRATTR_3DOBJ_DEPTH
1142 || nWhich
== SDRATTR_3DOBJ_END_ANGLE
1143 || nWhich
== SDRATTR_3DSCENE_DISTANCE
)
1145 bPossibleGeomChange
= true;
1148 nWhich
= aIter
.NextWhich();
1151 const bool bUndo
= IsUndoEnabled();
1154 EndTextEditCurrentView();
1155 BegUndo(ImpGetDescriptionString(STR_EditSetAttributes
));
1158 const size_t nMarkCount(rMarkList
.GetMarkCount());
1159 std::vector
< E3DModifySceneSnapRectUpdater
* > aUpdaters
;
1161 // create ItemSet without SfxItemState::INVALID. Put()
1162 // uses its second parameter (bInvalidAsDefault) to
1163 // remove all such items to set them to default.
1164 SfxItemSet
aAttr(*rAttr
.GetPool(), rAttr
.GetRanges());
1168 bool bResetAnimationTimer(false);
1170 const bool bLineStartWidthExplicitChange(SfxItemState::SET
1171 == aAttr
.GetItemState(XATTR_LINESTARTWIDTH
));
1172 const bool bLineEndWidthExplicitChange(SfxItemState::SET
1173 == aAttr
.GetItemState(XATTR_LINEENDWIDTH
));
1174 // check if LineWidth is part of the change
1175 const bool bAdaptStartEndWidths(!(bLineStartWidthExplicitChange
&& bLineEndWidthExplicitChange
)
1176 && SfxItemState::SET
== aAttr
.GetItemState(XATTR_LINEWIDTH
));
1177 sal_Int32
nNewLineWidth(0);
1179 if(bAdaptStartEndWidths
)
1181 nNewLineWidth
= aAttr
.Get(XATTR_LINEWIDTH
).GetValue();
1184 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1186 SdrMark
* pM
=rMarkList
.GetMark(nm
);
1187 SdrObject
* pObj
= pM
->GetMarkedSdrObj();
1191 SdrEdgeObj
* pEdgeObj
= dynamic_cast< SdrEdgeObj
* >( pObj
);
1193 bPossibleGeomChange
= true;
1195 AddUndoActions( CreateConnectorUndo( *pObj
) );
1198 // new geometry undo
1199 if(bPossibleGeomChange
&& bUndo
)
1201 // save position and size of object, too
1202 AddUndo( GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
1208 // If this is a text object also rescue the OutlinerParaObject since
1209 // applying attributes to the object may change text layout when
1210 // multiple portions exist with multiple formats. If an OutlinerParaObject
1211 // really exists and needs to be rescued is evaluated in the undo
1212 // implementation itself.
1213 const bool bRescueText
= DynCastSdrTextObj(pObj
) != nullptr;
1215 // add attribute undo
1216 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pObj
,false,bHasEEItems
|| bPossibleGeomChange
|| bRescueText
));
1219 // set up a scene updater if object is a 3d object
1220 if(DynCastE3dObject(pObj
))
1222 aUpdaters
.push_back(new E3DModifySceneSnapRectUpdater(pObj
));
1225 sal_Int32
nOldLineWidth(0);
1226 if (bAdaptStartEndWidths
)
1228 nOldLineWidth
= pObj
->GetMergedItem(XATTR_LINEWIDTH
).GetValue();
1231 // set attributes at object
1232 pObj
->SetMergedItemSetAndBroadcast(aAttr
, bReplaceAll
);
1234 if(bAdaptStartEndWidths
)
1236 const SfxItemSet
& rSet
= pObj
->GetMergedItemSet();
1238 if(nOldLineWidth
!= nNewLineWidth
)
1240 if(SfxItemState::INVALID
!= rSet
.GetItemState(XATTR_LINESTARTWIDTH
))
1242 const sal_Int32
nValAct(rSet
.Get(XATTR_LINESTARTWIDTH
).GetValue());
1243 const sal_Int32
nValNewStart(std::max(sal_Int32(0), nValAct
+ (((nNewLineWidth
- nOldLineWidth
) * 15) / 10)));
1245 pObj
->SetMergedItem(XLineStartWidthItem(nValNewStart
));
1248 if(SfxItemState::INVALID
!= rSet
.GetItemState(XATTR_LINEENDWIDTH
))
1250 const sal_Int32
nValAct(rSet
.Get(XATTR_LINEENDWIDTH
).GetValue());
1251 const sal_Int32
nValNewEnd(std::max(sal_Int32(0), nValAct
+ (((nNewLineWidth
- nOldLineWidth
) * 15) / 10)));
1253 pObj
->SetMergedItem(XLineEndWidthItem(nValNewEnd
));
1258 if(auto pTextObj
= DynCastSdrTextObj( pObj
))
1260 if(!aCharWhichIds
.empty())
1262 tools::Rectangle aOldBoundRect
= pTextObj
->GetLastBoundRect();
1264 // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect());
1265 pTextObj
->RemoveOutlinerCharacterAttribs( aCharWhichIds
);
1267 // object has changed, should be called from
1268 // RemoveOutlinerCharacterAttribs. This will change when the text
1269 // object implementation changes.
1270 pTextObj
->SetChanged();
1272 pTextObj
->BroadcastObjectChange();
1273 pTextObj
->SendUserCall(SdrUserCallType::ChangeAttr
, aOldBoundRect
);
1278 if(!bResetAnimationTimer
)
1280 if(pObj
->GetViewContact().isAnimatedInAnyViewObjectContact())
1282 bResetAnimationTimer
= true;
1287 // fire scene updaters
1288 while(!aUpdaters
.empty())
1290 delete aUpdaters
.back();
1291 aUpdaters
.pop_back();
1295 if(bResetAnimationTimer
)
1297 SetAnimationTimer(0);
1300 // better check before what to do:
1301 // pObj->SetAttr() or SetNotPersistAttr()
1302 // TODO: missing implementation!
1303 SetNotPersistAttrToMarked(rAttr
);
1309 SfxStyleSheet
* SdrEditView::GetStyleSheetFromMarked() const
1311 SfxStyleSheet
* pRet
=nullptr;
1313 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1314 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1315 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
1316 SdrMark
* pM
=rMarkList
.GetMark(nm
);
1317 SfxStyleSheet
* pSS
=pM
->GetMarkedSdrObj()->GetStyleSheet();
1319 else if (pRet
!=pSS
) return nullptr; // different stylesheets
1325 void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1327 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1328 if (rMarkList
.GetMarkCount() == 0)
1331 const bool bUndo
= IsUndoEnabled();
1335 EndTextEditCurrentView();
1337 if (pStyleSheet
!=nullptr)
1338 aStr
= ImpGetDescriptionString(STR_EditSetStylesheet
);
1340 aStr
= ImpGetDescriptionString(STR_EditDelStylesheet
);
1344 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1345 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1347 SdrMark
* pM
=rMarkList
.GetMark(nm
);
1350 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pM
->GetMarkedSdrObj()));
1351 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoAttrObject(*pM
->GetMarkedSdrObj(),true,true));
1353 pM
->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1361 void SdrEditView::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
1363 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1364 if(rMarkList
.GetMarkCount())
1366 rTargetSet
.Put(GetAttrFromMarked(bOnlyHardAttr
), false);
1370 SdrMarkView::GetAttributes(rTargetSet
, bOnlyHardAttr
);
1374 void SdrEditView::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
1376 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1377 if (rMarkList
.GetMarkCount()!=0) {
1378 SetAttrToMarked(rSet
,bReplaceAll
);
1380 SdrMarkView::SetAttributes(rSet
,bReplaceAll
);
1384 SfxStyleSheet
* SdrEditView::GetStyleSheet() const
1386 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1387 if (rMarkList
.GetMarkCount()!=0) {
1388 return GetStyleSheetFromMarked();
1390 return SdrMarkView::GetStyleSheet();
1394 void SdrEditView::SetStyleSheet(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1396 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1397 if (rMarkList
.GetMarkCount()!=0) {
1398 SetStyleSheetToMarked(pStyleSheet
,bDontRemoveHardAttr
);
1400 SdrMarkView::SetStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1405 SfxItemSet
SdrEditView::GetGeoAttrFromMarked() const
1408 GetModel().GetItemPool(),
1409 svl::Items
< // SID_ATTR_TRANSFORM_... from s:svxids.hrc
1410 SDRATTR_CORNER_RADIUS
, SDRATTR_CORNER_RADIUS
,
1411 SID_ATTR_TRANSFORM_POS_X
, SID_ATTR_TRANSFORM_ANGLE
,
1412 SID_ATTR_TRANSFORM_PROTECT_POS
, SID_ATTR_TRANSFORM_AUTOHEIGHT
>);
1414 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1415 if (rMarkList
.GetMarkCount() != 0)
1417 SfxItemSet
aMarkAttr(GetAttrFromMarked(false)); // because of AutoGrowHeight and corner radius
1418 tools::Rectangle
aRect(GetMarkedObjRect());
1420 if(GetSdrPageView())
1422 GetSdrPageView()->LogicToPagePos(aRect
);
1426 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X
,aRect
.Left()));
1427 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y
,aRect
.Top()));
1430 tools::Long nResizeRefX
=aRect
.Left();
1431 tools::Long nResizeRefY
=aRect
.Top();
1432 if (meDragMode
==SdrDragMode::Rotate
) { // use rotation axis as a reference for resizing, too
1433 nResizeRefX
=maRef1
.X();
1434 nResizeRefY
=maRef1
.Y();
1436 aRetSet
.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH
,aRect
.Right()-aRect
.Left()));
1437 aRetSet
.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT
,aRect
.Bottom()-aRect
.Top()));
1438 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X
,nResizeRefX
));
1439 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y
,nResizeRefY
));
1441 Point
aRotateAxe(maRef1
);
1443 if(GetSdrPageView())
1445 GetSdrPageView()->LogicToPagePos(aRotateAxe
);
1449 tools::Long nRotateRefX
=aRect
.Center().X();
1450 tools::Long nRotateRefY
=aRect
.Center().Y();
1451 if (meDragMode
==SdrDragMode::Rotate
) {
1452 nRotateRefX
=aRotateAxe
.X();
1453 nRotateRefY
=aRotateAxe
.Y();
1455 aRetSet
.Put(SdrAngleItem(SID_ATTR_TRANSFORM_ANGLE
,GetMarkedObjRotate()));
1456 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X
,nRotateRefX
));
1457 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y
,nRotateRefY
));
1460 tools::Long nShearRefX
=aRect
.Left();
1461 tools::Long nShearRefY
=aRect
.Bottom();
1462 if (meDragMode
==SdrDragMode::Rotate
) { // use rotation axis as a reference for shearing, too
1463 nShearRefX
=aRotateAxe
.X();
1464 nShearRefY
=aRotateAxe
.Y();
1466 aRetSet
.Put(SdrAngleItem(SID_ATTR_TRANSFORM_SHEAR
,GetMarkedObjShear()));
1467 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X
,nShearRefX
));
1468 aRetSet
.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y
,nShearRefY
));
1470 // check every object whether it is protected
1471 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1472 SdrObject
* pObj
=rMarkList
.GetMark(0)->GetMarkedSdrObj();
1473 bool bPosProt
=pObj
->IsMoveProtect();
1474 bool bSizProt
=pObj
->IsResizeProtect();
1475 bool bPosProtDontCare
=false;
1476 bool bSizProtDontCare
=false;
1477 for (size_t i
=1; i
<nMarkCount
&& (!bPosProtDontCare
|| !bSizProtDontCare
); ++i
)
1479 pObj
=rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1480 if (bPosProt
!=pObj
->IsMoveProtect()) bPosProtDontCare
=true;
1481 if (bSizProt
!=pObj
->IsResizeProtect()) bSizProtDontCare
=true;
1484 // InvalidateItem sets item to DONT_CARE
1485 if (bPosProtDontCare
) {
1486 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS
);
1488 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS
,bPosProt
));
1490 if (bSizProtDontCare
) {
1491 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE
);
1493 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE
,bSizProt
));
1496 SfxItemState eState
=aMarkAttr
.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH
);
1497 bool bAutoGrow
=aMarkAttr
.Get(SDRATTR_TEXT_AUTOGROWWIDTH
).GetValue();
1498 if (eState
==SfxItemState::INVALID
) {
1499 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH
);
1500 } else if (eState
==SfxItemState::SET
) {
1501 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH
,bAutoGrow
));
1504 eState
=aMarkAttr
.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT
);
1505 bAutoGrow
=aMarkAttr
.Get(SDRATTR_TEXT_AUTOGROWHEIGHT
).GetValue();
1506 if (eState
==SfxItemState::INVALID
) {
1507 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT
);
1508 } else if (eState
==SfxItemState::SET
) {
1509 aRetSet
.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT
,bAutoGrow
));
1512 eState
=aMarkAttr
.GetItemState(SDRATTR_CORNER_RADIUS
);
1513 tools::Long nRadius
=aMarkAttr
.Get(SDRATTR_CORNER_RADIUS
).GetValue();
1514 if (eState
==SfxItemState::INVALID
) {
1515 aRetSet
.InvalidateItem(SDRATTR_CORNER_RADIUS
);
1516 } else if (eState
==SfxItemState::SET
) {
1517 aRetSet
.Put(makeSdrEckenradiusItem(nRadius
));
1520 basegfx::B2DHomMatrix aTransformation
;
1524 // multiple objects, range is collected in aRect
1525 aTransformation
= basegfx::utils::createScaleTranslateB2DHomMatrix(
1526 aRect
.Left(), aRect
.Top(),
1527 aRect
.getOpenWidth(), aRect
.getOpenHeight());
1531 // single object, get homogen transformation
1532 basegfx::B2DPolyPolygon aPolyPolygon
;
1534 pObj
->TRGetBaseGeometry(aTransformation
, aPolyPolygon
);
1537 if(aTransformation
.isIdentity())
1539 aRetSet
.InvalidateItem(SID_ATTR_TRANSFORM_MATRIX
);
1543 css::geometry::AffineMatrix2D aAffineMatrix2D
;
1544 Point
aPageOffset(0, 0);
1546 if(GetSdrPageView())
1548 aPageOffset
= GetSdrPageView()->GetPageOrigin();
1551 aAffineMatrix2D
.m00
= aTransformation
.get(0, 0);
1552 aAffineMatrix2D
.m01
= aTransformation
.get(0, 1);
1553 aAffineMatrix2D
.m02
= aTransformation
.get(0, 2) - aPageOffset
.X();
1554 aAffineMatrix2D
.m10
= aTransformation
.get(1, 0);
1555 aAffineMatrix2D
.m11
= aTransformation
.get(1, 1);
1556 aAffineMatrix2D
.m12
= aTransformation
.get(1, 2) - aPageOffset
.Y();
1558 aRetSet
.Put(AffineMatrixItem(&aAffineMatrix2D
));
1565 static Point
ImpGetPoint(const tools::Rectangle
& rRect
, RectPoint eRP
)
1568 case RectPoint::LT
: return rRect
.TopLeft();
1569 case RectPoint::MT
: return rRect
.TopCenter();
1570 case RectPoint::RT
: return rRect
.TopRight();
1571 case RectPoint::LM
: return rRect
.LeftCenter();
1572 case RectPoint::MM
: return rRect
.Center();
1573 case RectPoint::RM
: return rRect
.RightCenter();
1574 case RectPoint::LB
: return rRect
.BottomLeft();
1575 case RectPoint::MB
: return rRect
.BottomCenter();
1576 case RectPoint::RB
: return rRect
.BottomRight();
1578 return Point(); // Should not happen!
1581 void SdrEditView::SetGeoAttrToMarked(const SfxItemSet
& rAttr
, bool addPageMargin
)
1583 const bool bTiledRendering
= comphelper::LibreOfficeKit::isActive();
1585 tools::Rectangle
aRect(GetMarkedObjRect());
1587 if(GetSdrPageView())
1591 SdrPage
* pPage
= GetSdrPageView()->GetPage();
1592 Point
upperLeft(pPage
->GetLeftBorder(), pPage
->GetUpperBorder());
1593 aRect
.Move(upperLeft
.getX(), upperLeft
.getY());
1595 GetSdrPageView()->LogicToPagePos(aRect
);
1598 Degree100 nOldRotateAngle
=GetMarkedObjRotate();
1599 Degree100 nOldShearAngle
=GetMarkedObjShear();
1600 const SdrMarkList
& rMarkList
=GetMarkedObjectList();
1601 SdrObject
* pObj
=nullptr;
1603 RectPoint eSizePoint
=RectPoint::MM
;
1604 tools::Long nPosDX
=0;
1605 tools::Long nPosDY
=0;
1606 tools::Long nSizX
=0;
1607 tools::Long nSizY
=0;
1608 Degree100
nRotateAngle(0);
1610 bool bModeIsRotate(meDragMode
== SdrDragMode::Rotate
);
1611 tools::Long
nRotateX(0);
1612 tools::Long
nRotateY(0);
1613 tools::Long
nOldRotateX(0);
1614 tools::Long
nOldRotateY(0);
1617 Point
aRotateAxe(maRef1
);
1619 if(GetSdrPageView())
1621 GetSdrPageView()->LogicToPagePos(aRotateAxe
);
1624 nRotateX
= nOldRotateX
= aRotateAxe
.X();
1625 nRotateY
= nOldRotateY
= aRotateAxe
.Y();
1628 Degree100
nShearAngle(0);
1629 tools::Long nShearX
=0;
1630 tools::Long nShearY
=0;
1631 bool bShearVert
=false;
1640 bool bSetAttr
=false;
1641 SfxItemSet
aSetAttr(GetModel().GetItemPool());
1644 if (const SfxInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_POS_X
))
1646 nPosDX
= pPoolItem
->GetValue() - aRect
.Left();
1649 if (const SfxInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_POS_Y
))
1651 nPosDY
= pPoolItem
->GetValue() - aRect
.Top();
1655 if (const SfxUInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_WIDTH
))
1657 nSizX
= pPoolItem
->GetValue();
1661 if (const SfxUInt32Item
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_HEIGHT
))
1663 nSizY
= pPoolItem
->GetValue();
1668 if (bTiledRendering
&& SfxItemState::SET
!= rAttr
.GetItemState(SID_ATTR_TRANSFORM_SIZE_POINT
))
1669 eSizePoint
= RectPoint::LT
;
1671 eSizePoint
= static_cast<RectPoint
>(rAttr
.Get(SID_ATTR_TRANSFORM_SIZE_POINT
).GetValue());
1675 if (const SdrAngleItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_DELTA_ANGLE
))
1677 nRotateAngle
= pPoolItem
->GetValue();
1678 bRotate
= (nRotateAngle
!= 0_deg100
);
1682 if (const SdrAngleItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_ANGLE
))
1684 nRotateAngle
= pPoolItem
->GetValue() - nOldRotateAngle
;
1685 bRotate
= (nRotateAngle
!= 0_deg100
);
1688 // position rotation point x
1689 if(bRotate
|| rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_ROT_X
))
1690 nRotateX
= rAttr
.Get(SID_ATTR_TRANSFORM_ROT_X
).GetValue();
1692 // position rotation point y
1693 if(bRotate
|| rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_ROT_Y
))
1694 nRotateY
= rAttr
.Get(SID_ATTR_TRANSFORM_ROT_Y
).GetValue();
1697 if (const SdrAngleItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_SHEAR
))
1699 Degree100 nNewShearAngle
=pPoolItem
->GetValue();
1700 if (nNewShearAngle
>SDRMAXSHEAR
) nNewShearAngle
=SDRMAXSHEAR
;
1701 if (nNewShearAngle
<-SDRMAXSHEAR
) nNewShearAngle
=-SDRMAXSHEAR
;
1702 if (nNewShearAngle
!=nOldShearAngle
) {
1703 bShearVert
= rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL
).GetValue();
1705 nShearAngle
=nNewShearAngle
;
1707 if (nNewShearAngle
!=0_deg100
&& nOldShearAngle
!=0_deg100
) {
1709 double nOld
= tan(toRadians(nOldShearAngle
));
1710 double nNew
= tan(toRadians(nNewShearAngle
));
1712 nNew
= basegfx::rad2deg
<100>(atan(nNew
));
1713 nShearAngle
= Degree100(basegfx::fround(nNew
));
1715 nShearAngle
=nNewShearAngle
-nOldShearAngle
;
1718 bShear
=nShearAngle
!=0_deg100
;
1720 nShearX
= rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_X
).GetValue();
1721 nShearY
= rAttr
.Get(SID_ATTR_TRANSFORM_SHEAR_Y
).GetValue();
1727 if (const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_AUTOWIDTH
))
1729 bool bAutoGrow
= pPoolItem
->GetValue();
1730 aSetAttr
.Put(makeSdrTextAutoGrowWidthItem(bAutoGrow
));
1734 if (const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_AUTOHEIGHT
))
1736 bool bAutoGrow
= pPoolItem
->GetValue();
1737 aSetAttr
.Put(makeSdrTextAutoGrowHeightItem(bAutoGrow
));
1742 if (m_bEdgeRadiusAllowed
)
1743 if (const SdrMetricItem
*pPoolItem
= rAttr
.GetItemIfSet(SDRATTR_CORNER_RADIUS
))
1745 tools::Long nRadius
= pPoolItem
->GetValue();
1746 aSetAttr
.Put(makeSdrEckenradiusItem(nRadius
));
1750 ForcePossibilities();
1752 BegUndo(SvxResId(STR_EditTransform
),rMarkList
.GetMarkDescription());
1755 SetAttrToMarked(aSetAttr
,false);
1758 // change size and height
1759 if (bChgSiz
&& (m_bResizeFreeAllowed
|| m_bResizePropAllowed
)) {
1760 Fraction
aWdt(nSizX
,aRect
.Right()-aRect
.Left());
1761 Fraction
aHgt(nSizY
,aRect
.Bottom()-aRect
.Top());
1762 Point
aRef(ImpGetPoint(aRect
,eSizePoint
));
1764 if(GetSdrPageView())
1766 GetSdrPageView()->PagePosToLogic(aRef
);
1769 ResizeMultMarkedObj(aRef
, aWdt
, aHgt
, bChgWdh
, bChgHgt
);
1773 if (bRotate
&& (m_bRotateFreeAllowed
|| m_bRotate90Allowed
)) {
1774 Point
aRef(nRotateX
,nRotateY
);
1776 if(GetSdrPageView())
1778 GetSdrPageView()->PagePosToLogic(aRef
);
1781 RotateMarkedObj(aRef
,nRotateAngle
);
1784 // set rotation point position
1785 if(bModeIsRotate
&& (nRotateX
!= nOldRotateX
|| nRotateY
!= nOldRotateY
))
1787 Point
aNewRef1(nRotateX
, nRotateY
);
1789 if(GetSdrPageView())
1791 GetSdrPageView()->PagePosToLogic(aNewRef1
);
1798 if (bShear
&& m_bShearAllowed
) {
1799 Point
aRef(nShearX
,nShearY
);
1801 if(GetSdrPageView())
1803 GetSdrPageView()->PagePosToLogic(aRef
);
1806 ShearMarkedObj(aRef
,nShearAngle
,bShearVert
);
1809 // ShearMarkedObj creates a linear combination of the existing transformation and
1810 // the new shear to apply. If the object is already transformed (e.g. rotated) the
1811 // linear combination will not decompose to the same start values again, but to a
1812 // new combination. Thus it makes no sense to check if the wanted shear is reached
1813 // or not. Taking out.
1817 if (bChgPos
&& m_bMoveAllowed
) {
1818 MoveMarkedObj(Size(nPosDX
,nPosDY
));
1821 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1823 if(const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_PROTECT_POS
))
1825 const bool bProtPos(pPoolItem
->GetValue());
1826 bool bChanged(false);
1828 for(size_t i
= 0; i
< nMarkCount
; ++i
)
1830 pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1832 if(pObj
->IsMoveProtect() != bProtPos
)
1835 pObj
->SetMoveProtect(bProtPos
);
1839 pObj
->SetResizeProtect(true);
1846 m_bMoveProtect
= bProtPos
;
1850 m_bResizeProtect
= true;
1853 // #i77187# there is no simple method to get the toolbars updated
1854 // in the application. The App is listening to selection change and i
1855 // will use it here (even if not true). It's acceptable since changing
1856 // this model data is pretty rare and only possible using the F4 dialog
1857 MarkListHasChanged();
1864 if(const SfxBoolItem
*pPoolItem
= rAttr
.GetItemIfSet(SID_ATTR_TRANSFORM_PROTECT_SIZE
))
1866 const bool bProtSize(pPoolItem
->GetValue());
1867 bool bChanged(false);
1869 for(size_t i
= 0; i
< nMarkCount
; ++i
)
1871 pObj
= rMarkList
.GetMark(i
)->GetMarkedSdrObj();
1873 if(pObj
->IsResizeProtect() != bProtSize
)
1876 pObj
->SetResizeProtect(bProtSize
);
1882 m_bResizeProtect
= bProtSize
;
1884 // #i77187# see above
1885 MarkListHasChanged();
1894 bool SdrEditView::IsAlignPossible() const
1895 { // at least two selected objects, at least one of them movable
1896 ForcePossibilities();
1897 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1898 const size_t nCount
=rMarkList
.GetMarkCount();
1899 if (nCount
==0) return false; // nothing selected!
1900 if (nCount
==1) return m_bMoveAllowed
; // align single object to page
1901 return m_bOneOrMoreMovable
; // otherwise: MarkCount>=2
1904 void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor
, SdrVertAlign eVert
)
1906 if (eHor
==SdrHorAlign::NONE
&& eVert
==SdrVertAlign::NONE
)
1909 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
1910 rMarkList
.ForceSort();
1911 if (!rMarkList
.GetMarkCount())
1914 const bool bUndo
= IsUndoEnabled();
1917 EndTextEditCurrentView();
1918 OUString
aStr(rMarkList
.GetMarkDescription());
1919 if (eHor
==SdrHorAlign::NONE
)
1923 case SdrVertAlign::Top
:
1924 aStr
= ImpGetDescriptionString(STR_EditAlignVTop
);
1926 case SdrVertAlign::Bottom
:
1927 aStr
= ImpGetDescriptionString(STR_EditAlignVBottom
);
1929 case SdrVertAlign::Center
:
1930 aStr
= ImpGetDescriptionString(STR_EditAlignVCenter
);
1935 else if (eVert
==SdrVertAlign::NONE
)
1939 case SdrHorAlign::Left
:
1940 aStr
= ImpGetDescriptionString(STR_EditAlignHLeft
);
1942 case SdrHorAlign::Right
:
1943 aStr
= ImpGetDescriptionString(STR_EditAlignHRight
);
1945 case SdrHorAlign::Center
:
1946 aStr
= ImpGetDescriptionString(STR_EditAlignHCenter
);
1951 else if (eHor
==SdrHorAlign::Center
&& eVert
==SdrVertAlign::Center
)
1953 aStr
= ImpGetDescriptionString(STR_EditAlignCenter
);
1957 aStr
= ImpGetDescriptionString(STR_EditAlign
);
1962 tools::Rectangle aBound
;
1963 const size_t nMarkCount
=rMarkList
.GetMarkCount();
1964 bool bHasFixed
=false;
1965 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
1967 SdrMark
* pM
=rMarkList
.GetMark(nm
);
1968 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
1969 SdrObjTransformInfoRec aInfo
;
1970 pObj
->TakeObjInfo(aInfo
);
1971 if (!aInfo
.bMoveAllowed
|| pObj
->IsMoveProtect())
1973 tools::Rectangle
aObjRect(pObj
->GetSnapRect());
1974 aBound
.Union(aObjRect
);
1981 { // align single object to page
1982 const SdrObject
* pObj
=rMarkList
.GetMark(0)->GetMarkedSdrObj();
1983 const SdrPage
* pPage
=pObj
->getSdrPageFromSdrObject();
1984 const SdrPageGridFrameList
* pGFL
=pPage
->GetGridFrameList(rMarkList
.GetMark(0)->GetPageView(),&(pObj
->GetSnapRect()));
1985 const SdrPageGridFrame
* pFrame
=nullptr;
1986 if (pGFL
!=nullptr && pGFL
->GetCount()!=0)
1988 pFrame
=&((*pGFL
)[0]);
1991 if (pFrame
!=nullptr)
1993 aBound
=pFrame
->GetUserArea();
1997 aBound
=tools::Rectangle(pPage
->GetLeftBorder(),pPage
->GetUpperBorder(),
1998 pPage
->GetWidth()-pPage
->GetRightBorder(),
1999 pPage
->GetHeight()-pPage
->GetLowerBorder());
2004 aBound
=GetMarkedObjRect();
2007 Point
aCenter(aBound
.Center());
2008 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
2010 SdrMark
* pM
=rMarkList
.GetMark(nm
);
2011 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
2012 SdrObjTransformInfoRec aInfo
;
2013 pObj
->TakeObjInfo(aInfo
);
2014 if (aInfo
.bMoveAllowed
&& !pObj
->IsMoveProtect())
2016 tools::Long nXMov
=0;
2017 tools::Long nYMov
=0;
2018 tools::Rectangle
aObjRect(pObj
->GetSnapRect());
2021 case SdrVertAlign::Top
: nYMov
=aBound
.Top() -aObjRect
.Top() ; break;
2022 case SdrVertAlign::Bottom
: nYMov
=aBound
.Bottom()-aObjRect
.Bottom() ; break;
2023 case SdrVertAlign::Center
: nYMov
=aCenter
.Y() -aObjRect
.Center().Y(); break;
2028 case SdrHorAlign::Left
: nXMov
=aBound
.Left() -aObjRect
.Left() ; break;
2029 case SdrHorAlign::Right
: nXMov
=aBound
.Right() -aObjRect
.Right() ; break;
2030 case SdrHorAlign::Center
: nXMov
=aCenter
.X() -aObjRect
.Center().X(); break;
2033 if (nXMov
!=0 || nYMov
!=0)
2035 // SdrEdgeObj needs an extra SdrUndoGeoObj since the
2036 // connections may need to be saved
2039 if( dynamic_cast<SdrEdgeObj
*>(pObj
) )
2041 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
2044 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoMoveObject(*pObj
,Size(nXMov
,nYMov
)));
2047 pObj
->Move(Size(nXMov
,nYMov
));
2056 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */