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 .
21 #include <svx/svdglev.hxx>
24 #include <svx/svdundo.hxx>
25 #include <svx/strings.hrc>
26 #include <svx/dialmgr.hxx>
27 #include <svx/svdglue.hxx>
28 #include <svx/svdtrans.hxx>
29 #include <svx/svdobj.hxx>
31 SdrGlueEditView::SdrGlueEditView(
34 : SdrPolyEditView(rSdrModel
, pOut
)
38 SdrGlueEditView::~SdrGlueEditView()
42 void SdrGlueEditView::ImpDoMarkedGluePoints(PGlueDoFunc pDoFunc
, bool bConst
, const void* p1
, const void* p2
, const void* p3
, const void* p4
)
44 const size_t nMarkCount
=GetMarkedObjectCount();
45 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
46 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
47 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
48 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
51 SdrGluePointList
* pGPL
=nullptr;
53 const SdrGluePointList
* pConstGPL
=pObj
->GetGluePointList();
54 pGPL
=const_cast<SdrGluePointList
*>(pConstGPL
);
56 pGPL
=pObj
->ForceGluePointList();
60 if(!bConst
&& IsUndoEnabled() )
61 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
63 for(sal_uInt16 nPtId
: rPts
)
65 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
66 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
68 SdrGluePoint
& rGP
=(*pGPL
)[nGlueIdx
];
69 (*pDoFunc
)(rGP
,pObj
,p1
,p2
,p3
,p4
);
75 pObj
->BroadcastObjectChange();
80 if (!bConst
&& nMarkCount
!=0)
81 GetModel().SetChanged();
85 static void ImpGetEscDir(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pnThisEsc
, const void* pnRet
, const void*)
87 TriState
& nRet
=*const_cast<TriState
*>(static_cast<TriState
const *>(pnRet
));
88 if (nRet
!=TRISTATE_INDET
) {
89 SdrEscapeDirection nEsc
= rGP
.GetEscDir();
90 bool bOn
= bool(nEsc
& *static_cast<SdrEscapeDirection
const *>(pnThisEsc
));
91 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
93 nRet
= bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
;
96 else if (nRet
!= (bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
)) nRet
=TRISTATE_INDET
;
100 TriState
SdrGlueEditView::IsMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc
) const
102 ForceUndirtyMrkPnt();
104 TriState nRet
=TRISTATE_FALSE
;
105 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetEscDir
,true,&bFirst
,&nThisEsc
,&nRet
);
109 static void ImpSetEscDir(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pnThisEsc
, const void* pbOn
, const void*, const void*)
111 SdrEscapeDirection nEsc
=rGP
.GetEscDir();
112 if (*static_cast<bool const *>(pbOn
))
113 nEsc
|= *static_cast<SdrEscapeDirection
const *>(pnThisEsc
);
115 nEsc
&= ~*static_cast<SdrEscapeDirection
const *>(pnThisEsc
);
119 void SdrGlueEditView::SetMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc
, bool bOn
)
121 ForceUndirtyMrkPnt();
122 BegUndo(SvxResId(STR_EditSetGlueEscDir
),GetDescriptionOfMarkedGluePoints());
123 ImpDoMarkedGluePoints(ImpSetEscDir
,false,&nThisEsc
,&bOn
);
128 static void ImpGetPercent(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pnRet
, const void*, const void*)
130 TriState
& nRet
=*const_cast<TriState
*>(static_cast<TriState
const *>(pnRet
));
131 if (nRet
!=TRISTATE_INDET
) {
132 bool bOn
=rGP
.IsPercent();
133 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
135 nRet
= bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
;
138 else if ((nRet
!=TRISTATE_FALSE
)!=bOn
)
143 TriState
SdrGlueEditView::IsMarkedGluePointsPercent() const
145 ForceUndirtyMrkPnt();
147 TriState nRet
= TRISTATE_TRUE
;
148 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetPercent
,true,&bFirst
,&nRet
);
152 static void ImpSetPercent(SdrGluePoint
& rGP
, const SdrObject
* pObj
, const void* pbOn
, const void*, const void*, const void*)
154 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
155 rGP
.SetPercent(*static_cast<bool const *>(pbOn
));
156 rGP
.SetAbsolutePos(aPos
,*pObj
);
159 void SdrGlueEditView::SetMarkedGluePointsPercent(bool bOn
)
161 ForceUndirtyMrkPnt();
162 BegUndo(SvxResId(STR_EditSetGluePercent
),GetDescriptionOfMarkedGluePoints());
163 ImpDoMarkedGluePoints(ImpSetPercent
,false,&bOn
);
168 static void ImpGetAlign(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pbDontCare
, const void* pbVert
, const void* pnRet
)
170 SdrAlign
& nRet
=*const_cast<SdrAlign
*>(static_cast<SdrAlign
const *>(pnRet
));
171 bool& bDontCare
=*const_cast<bool *>(static_cast<bool const *>(pbDontCare
));
172 bool bVert
=*static_cast<bool const *>(pbVert
);
176 SdrAlign nAlg
=SdrAlign::NONE
;
178 nAlg
=rGP
.GetVertAlign();
180 nAlg
=rGP
.GetHorzAlign();
182 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
183 if (bFirst
) { nRet
=nAlg
; bFirst
=false; }
184 else if (nRet
!=nAlg
) {
186 nRet
=SdrAlign::VERT_DONTCARE
;
188 nRet
=SdrAlign::HORZ_DONTCARE
;
194 SdrAlign
SdrGlueEditView::GetMarkedGluePointsAlign(bool bVert
) const
196 ForceUndirtyMrkPnt();
198 bool bDontCare
=false;
199 SdrAlign nRet
=SdrAlign::NONE
;
200 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetAlign
,true,&bFirst
,&bDontCare
,&bVert
,&nRet
);
204 static void ImpSetAlign(SdrGluePoint
& rGP
, const SdrObject
* pObj
, const void* pbVert
, const void* pnAlign
, const void*, const void*)
206 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
207 if (*static_cast<bool const *>(pbVert
)) { // bVert?
208 rGP
.SetVertAlign(*static_cast<SdrAlign
const *>(pnAlign
));
210 rGP
.SetHorzAlign(*static_cast<SdrAlign
const *>(pnAlign
));
212 rGP
.SetAbsolutePos(aPos
,*pObj
);
215 void SdrGlueEditView::SetMarkedGluePointsAlign(bool bVert
, SdrAlign nAlign
)
217 ForceUndirtyMrkPnt();
218 BegUndo(SvxResId(STR_EditSetGlueAlign
),GetDescriptionOfMarkedGluePoints());
219 ImpDoMarkedGluePoints(ImpSetAlign
,false,&bVert
,&nAlign
);
223 void SdrGlueEditView::DeleteMarkedGluePoints()
226 ForceUndirtyMrkPnt();
227 const bool bUndo
= IsUndoEnabled();
229 BegUndo(SvxResId(STR_EditDelete
),GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Delete
);
231 const size_t nMarkCount
=GetMarkedObjectCount();
232 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
234 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
235 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
236 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
239 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
243 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
245 for(sal_uInt16 nPtId
: rPts
)
247 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
248 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
250 pGPL
->Delete(nGlueIdx
);
254 pObj
->BroadcastObjectChange();
260 UnmarkAllGluePoints();
262 GetModel().SetChanged();
266 void SdrGlueEditView::ImpCopyMarkedGluePoints()
268 const bool bUndo
= IsUndoEnabled();
273 const size_t nMarkCount
=GetMarkedObjectCount();
274 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
276 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
277 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
278 SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
279 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
280 if (!rPts
.empty() && pGPL
!=nullptr)
283 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
285 SdrUShortCont aIdsToErase
;
286 SdrUShortCont aIdsToInsert
;
287 for(sal_uInt16 nPtId
: rPts
)
289 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
290 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
292 SdrGluePoint
aNewGP((*pGPL
)[nGlueIdx
]); // clone GluePoint
293 sal_uInt16 nNewIdx
=pGPL
->Insert(aNewGP
); // and insert it
294 sal_uInt16 nNewId
=(*pGPL
)[nNewIdx
].GetId(); // retrieve ID of new GluePoints
295 aIdsToErase
.insert(nPtId
); // select it (instead of the old one)
296 aIdsToInsert
.insert(nNewId
);
299 for(const auto& rId
: aIdsToErase
)
301 rPts
.insert(aIdsToInsert
);
308 GetModel().SetChanged();
312 void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc
, const void* p1
, const void* p2
, const void* p3
, const void* p4
)
314 const size_t nMarkCount
=GetMarkedObjectCount();
315 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
316 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
317 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
318 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
320 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
323 if( IsUndoEnabled() )
324 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
326 for(sal_uInt16 nPtId
: rPts
)
328 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
329 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
) {
330 SdrGluePoint
& rGP
=(*pGPL
)[nGlueIdx
];
331 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
332 (*pTrFunc
)(aPos
,p1
,p2
,p3
,p4
);
333 rGP
.SetAbsolutePos(aPos
,*pObj
);
337 pObj
->BroadcastObjectChange();
342 GetModel().SetChanged();
346 static void ImpMove(Point
& rPt
, const void* p1
, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/)
348 rPt
.AdjustX(static_cast<const Size
*>(p1
)->Width() );
349 rPt
.AdjustY(static_cast<const Size
*>(p1
)->Height() );
352 void SdrGlueEditView::MoveMarkedGluePoints(const Size
& rSiz
, bool bCopy
)
354 ForceUndirtyMrkPnt();
355 OUString
aStr(SvxResId(STR_EditMove
));
356 if (bCopy
) aStr
+= SvxResId(STR_EditWithCopy
);
357 BegUndo(aStr
,GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Move
);
358 if (bCopy
) ImpCopyMarkedGluePoints();
359 ImpTransformMarkedGluePoints(ImpMove
,&rSiz
);
365 static void ImpResize(Point
& rPt
, const void* p1
, const void* p2
, const void* p3
, const void* /*p4*/)
367 ResizePoint(rPt
,*static_cast<const Point
*>(p1
),*static_cast<const Fraction
*>(p2
),*static_cast<const Fraction
*>(p3
));
370 void SdrGlueEditView::ResizeMarkedGluePoints(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bCopy
)
372 ForceUndirtyMrkPnt();
373 OUString
aStr(SvxResId(STR_EditResize
));
374 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
375 BegUndo(aStr
,GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Resize
);
376 if (bCopy
) ImpCopyMarkedGluePoints();
377 ImpTransformMarkedGluePoints(ImpResize
,&rRef
,&xFact
,&yFact
);
383 static void ImpRotate(Point
& rPt
, const void* p1
, const void* /*p2*/, const void* p3
, const void* p4
)
385 RotatePoint(rPt
,*static_cast<const Point
*>(p1
),*static_cast<const double*>(p3
),*static_cast<const double*>(p4
));
388 void SdrGlueEditView::RotateMarkedGluePoints(const Point
& rRef
, Degree100 nAngle
, bool bCopy
)
390 ForceUndirtyMrkPnt();
391 OUString
aStr(SvxResId(STR_EditRotate
));
392 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
393 BegUndo(aStr
,GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Rotate
);
394 if (bCopy
) ImpCopyMarkedGluePoints();
395 double nSin
= sin(toRadians(nAngle
));
396 double nCos
= cos(toRadians(nAngle
));
397 ImpTransformMarkedGluePoints(ImpRotate
,&rRef
,&nAngle
,&nSin
,&nCos
);
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */