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 SdrMarkList
& rMarkList
= GetMarkedObjectList();
45 const size_t nMarkCount
=rMarkList
.GetMarkCount();
46 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
47 SdrMark
* pM
=rMarkList
.GetMark(nm
);
48 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
49 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
52 SdrGluePointList
* pGPL
=nullptr;
54 const SdrGluePointList
* pConstGPL
=pObj
->GetGluePointList();
55 pGPL
=const_cast<SdrGluePointList
*>(pConstGPL
);
57 pGPL
=pObj
->ForceGluePointList();
61 if(!bConst
&& IsUndoEnabled() )
62 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
64 for(sal_uInt16 nPtId
: rPts
)
66 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
67 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
69 SdrGluePoint
& rGP
=(*pGPL
)[nGlueIdx
];
70 (*pDoFunc
)(rGP
,pObj
,p1
,p2
,p3
,p4
);
76 pObj
->BroadcastObjectChange();
81 if (!bConst
&& nMarkCount
!=0)
82 GetModel().SetChanged();
86 static void ImpGetEscDir(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pnThisEsc
, const void* pnRet
, const void*)
88 TriState
& nRet
=*const_cast<TriState
*>(static_cast<TriState
const *>(pnRet
));
89 if (nRet
!=TRISTATE_INDET
) {
90 SdrEscapeDirection nEsc
= rGP
.GetEscDir();
91 bool bOn
= bool(nEsc
& *static_cast<SdrEscapeDirection
const *>(pnThisEsc
));
92 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
94 nRet
= bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
;
97 else if (nRet
!= (bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
)) nRet
=TRISTATE_INDET
;
101 TriState
SdrGlueEditView::IsMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc
) const
103 ForceUndirtyMrkPnt();
105 TriState nRet
=TRISTATE_FALSE
;
106 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetEscDir
,true,&bFirst
,&nThisEsc
,&nRet
);
110 static void ImpSetEscDir(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pnThisEsc
, const void* pbOn
, const void*, const void*)
112 SdrEscapeDirection nEsc
=rGP
.GetEscDir();
113 if (*static_cast<bool const *>(pbOn
))
114 nEsc
|= *static_cast<SdrEscapeDirection
const *>(pnThisEsc
);
116 nEsc
&= ~*static_cast<SdrEscapeDirection
const *>(pnThisEsc
);
120 void SdrGlueEditView::SetMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc
, bool bOn
)
122 ForceUndirtyMrkPnt();
123 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
124 BegUndo(SvxResId(STR_EditSetGlueEscDir
),rMarkList
.GetGluePointMarkDescription());
125 ImpDoMarkedGluePoints(ImpSetEscDir
,false,&nThisEsc
,&bOn
);
130 static void ImpGetPercent(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pnRet
, const void*, const void*)
132 TriState
& nRet
=*const_cast<TriState
*>(static_cast<TriState
const *>(pnRet
));
133 if (nRet
!=TRISTATE_INDET
) {
134 bool bOn
=rGP
.IsPercent();
135 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
137 nRet
= bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
;
140 else if ((nRet
!=TRISTATE_FALSE
)!=bOn
)
145 TriState
SdrGlueEditView::IsMarkedGluePointsPercent() const
147 ForceUndirtyMrkPnt();
149 TriState nRet
= TRISTATE_TRUE
;
150 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetPercent
,true,&bFirst
,&nRet
);
154 static void ImpSetPercent(SdrGluePoint
& rGP
, const SdrObject
* pObj
, const void* pbOn
, const void*, const void*, const void*)
156 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
157 rGP
.SetPercent(*static_cast<bool const *>(pbOn
));
158 rGP
.SetAbsolutePos(aPos
,*pObj
);
161 void SdrGlueEditView::SetMarkedGluePointsPercent(bool bOn
)
163 ForceUndirtyMrkPnt();
164 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
165 BegUndo(SvxResId(STR_EditSetGluePercent
),rMarkList
.GetGluePointMarkDescription());
166 ImpDoMarkedGluePoints(ImpSetPercent
,false,&bOn
);
171 static void ImpGetAlign(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pbDontCare
, const void* pbVert
, const void* pnRet
)
173 SdrAlign
& nRet
=*const_cast<SdrAlign
*>(static_cast<SdrAlign
const *>(pnRet
));
174 bool& bDontCare
=*const_cast<bool *>(static_cast<bool const *>(pbDontCare
));
175 bool bVert
=*static_cast<bool const *>(pbVert
);
179 SdrAlign nAlg
=SdrAlign::NONE
;
181 nAlg
=rGP
.GetVertAlign();
183 nAlg
=rGP
.GetHorzAlign();
185 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
186 if (bFirst
) { nRet
=nAlg
; bFirst
=false; }
187 else if (nRet
!=nAlg
) {
189 nRet
=SdrAlign::VERT_DONTCARE
;
191 nRet
=SdrAlign::HORZ_DONTCARE
;
197 SdrAlign
SdrGlueEditView::GetMarkedGluePointsAlign(bool bVert
) const
199 ForceUndirtyMrkPnt();
201 bool bDontCare
=false;
202 SdrAlign nRet
=SdrAlign::NONE
;
203 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetAlign
,true,&bFirst
,&bDontCare
,&bVert
,&nRet
);
207 static void ImpSetAlign(SdrGluePoint
& rGP
, const SdrObject
* pObj
, const void* pbVert
, const void* pnAlign
, const void*, const void*)
209 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
210 if (*static_cast<bool const *>(pbVert
)) { // bVert?
211 rGP
.SetVertAlign(*static_cast<SdrAlign
const *>(pnAlign
));
213 rGP
.SetHorzAlign(*static_cast<SdrAlign
const *>(pnAlign
));
215 rGP
.SetAbsolutePos(aPos
,*pObj
);
218 void SdrGlueEditView::SetMarkedGluePointsAlign(bool bVert
, SdrAlign nAlign
)
220 ForceUndirtyMrkPnt();
221 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
222 BegUndo(SvxResId(STR_EditSetGlueAlign
),rMarkList
.GetGluePointMarkDescription());
223 ImpDoMarkedGluePoints(ImpSetAlign
,false,&bVert
,&nAlign
);
227 void SdrGlueEditView::DeleteMarkedGluePoints()
230 ForceUndirtyMrkPnt();
231 const bool bUndo
= IsUndoEnabled();
232 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
234 BegUndo(SvxResId(STR_EditDelete
),rMarkList
.GetGluePointMarkDescription(),SdrRepeatFunc::Delete
);
236 const size_t nMarkCount
=rMarkList
.GetMarkCount();
237 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
239 SdrMark
* pM
=rMarkList
.GetMark(nm
);
240 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
241 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
244 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
248 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
250 for(sal_uInt16 nPtId
: rPts
)
252 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
253 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
255 pGPL
->Delete(nGlueIdx
);
259 pObj
->BroadcastObjectChange();
265 UnmarkAllGluePoints();
267 GetModel().SetChanged();
271 void SdrGlueEditView::ImpCopyMarkedGluePoints()
273 const bool bUndo
= IsUndoEnabled();
278 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
279 const size_t nMarkCount
=rMarkList
.GetMarkCount();
280 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
282 SdrMark
* pM
=rMarkList
.GetMark(nm
);
283 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
284 SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
285 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
286 if (!rPts
.empty() && pGPL
!=nullptr)
289 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
291 SdrUShortCont aIdsToErase
;
292 SdrUShortCont aIdsToInsert
;
293 for(sal_uInt16 nPtId
: rPts
)
295 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
296 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
298 SdrGluePoint
aNewGP((*pGPL
)[nGlueIdx
]); // clone GluePoint
299 sal_uInt16 nNewIdx
=pGPL
->Insert(aNewGP
); // and insert it
300 sal_uInt16 nNewId
=(*pGPL
)[nNewIdx
].GetId(); // retrieve ID of new GluePoints
301 aIdsToErase
.insert(nPtId
); // select it (instead of the old one)
302 aIdsToInsert
.insert(nNewId
);
305 for(const auto& rId
: aIdsToErase
)
307 rPts
.insert(aIdsToInsert
);
314 GetModel().SetChanged();
318 void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc
, const void* p1
, const void* p2
, const void* p3
, const void* p4
)
320 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
321 const size_t nMarkCount
=rMarkList
.GetMarkCount();
322 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
323 SdrMark
* pM
=rMarkList
.GetMark(nm
);
324 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
325 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
327 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
330 if( IsUndoEnabled() )
331 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
333 for(sal_uInt16 nPtId
: rPts
)
335 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
336 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
) {
337 SdrGluePoint
& rGP
=(*pGPL
)[nGlueIdx
];
338 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
339 (*pTrFunc
)(aPos
,p1
,p2
,p3
,p4
);
340 rGP
.SetAbsolutePos(aPos
,*pObj
);
344 pObj
->BroadcastObjectChange();
349 GetModel().SetChanged();
353 static void ImpMove(Point
& rPt
, const void* p1
, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/)
355 rPt
.AdjustX(static_cast<const Size
*>(p1
)->Width() );
356 rPt
.AdjustY(static_cast<const Size
*>(p1
)->Height() );
359 void SdrGlueEditView::MoveMarkedGluePoints(const Size
& rSiz
, bool bCopy
)
361 ForceUndirtyMrkPnt();
362 OUString
aStr(SvxResId(STR_EditMove
));
363 if (bCopy
) aStr
+= SvxResId(STR_EditWithCopy
);
364 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
365 BegUndo(aStr
,rMarkList
.GetGluePointMarkDescription(),SdrRepeatFunc::Move
);
366 if (bCopy
) ImpCopyMarkedGluePoints();
367 ImpTransformMarkedGluePoints(ImpMove
,&rSiz
);
373 static void ImpResize(Point
& rPt
, const void* p1
, const void* p2
, const void* p3
, const void* /*p4*/)
375 ResizePoint(rPt
,*static_cast<const Point
*>(p1
),*static_cast<const Fraction
*>(p2
),*static_cast<const Fraction
*>(p3
));
378 void SdrGlueEditView::ResizeMarkedGluePoints(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bCopy
)
380 ForceUndirtyMrkPnt();
381 OUString
aStr(SvxResId(STR_EditResize
));
382 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
383 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
384 BegUndo(aStr
,rMarkList
.GetGluePointMarkDescription(),SdrRepeatFunc::Resize
);
385 if (bCopy
) ImpCopyMarkedGluePoints();
386 ImpTransformMarkedGluePoints(ImpResize
,&rRef
,&xFact
,&yFact
);
392 static void ImpRotate(Point
& rPt
, const void* p1
, const void* /*p2*/, const void* p3
, const void* p4
)
394 RotatePoint(rPt
,*static_cast<const Point
*>(p1
),*static_cast<const double*>(p3
),*static_cast<const double*>(p4
));
397 void SdrGlueEditView::RotateMarkedGluePoints(const Point
& rRef
, Degree100 nAngle
, bool bCopy
)
399 ForceUndirtyMrkPnt();
400 OUString
aStr(SvxResId(STR_EditRotate
));
401 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
402 const SdrMarkList
& rMarkList
= GetMarkedObjectList();
403 BegUndo(aStr
,rMarkList
.GetGluePointMarkDescription(),SdrRepeatFunc::Rotate
);
404 if (bCopy
) ImpCopyMarkedGluePoints();
405 double nSin
= sin(toRadians(nAngle
));
406 double nCos
= cos(toRadians(nAngle
));
407 ImpTransformMarkedGluePoints(ImpRotate
,&rRef
,&nAngle
,&nSin
,&nCos
);
412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */