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) mpModel
->SetChanged();
84 static void ImpGetEscDir(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pnThisEsc
, const void* pnRet
, const void*)
86 TriState
& nRet
=*const_cast<TriState
*>(static_cast<TriState
const *>(pnRet
));
87 if (nRet
!=TRISTATE_INDET
) {
88 SdrEscapeDirection nEsc
= rGP
.GetEscDir();
89 bool bOn
= bool(nEsc
& *static_cast<SdrEscapeDirection
const *>(pnThisEsc
));
90 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
92 nRet
= bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
;
95 else if (nRet
!= (bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
)) nRet
=TRISTATE_INDET
;
99 TriState
SdrGlueEditView::IsMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc
) const
101 ForceUndirtyMrkPnt();
103 TriState nRet
=TRISTATE_FALSE
;
104 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetEscDir
,true,&bFirst
,&nThisEsc
,&nRet
);
108 static void ImpSetEscDir(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pnThisEsc
, const void* pbOn
, const void*, const void*)
110 SdrEscapeDirection nEsc
=rGP
.GetEscDir();
111 if (*static_cast<bool const *>(pbOn
))
112 nEsc
|= *static_cast<SdrEscapeDirection
const *>(pnThisEsc
);
114 nEsc
&= ~*static_cast<SdrEscapeDirection
const *>(pnThisEsc
);
118 void SdrGlueEditView::SetMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc
, bool bOn
)
120 ForceUndirtyMrkPnt();
121 BegUndo(SvxResId(STR_EditSetGlueEscDir
),GetDescriptionOfMarkedGluePoints());
122 ImpDoMarkedGluePoints(ImpSetEscDir
,false,&nThisEsc
,&bOn
);
127 static void ImpGetPercent(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pnRet
, const void*, const void*)
129 TriState
& nRet
=*const_cast<TriState
*>(static_cast<TriState
const *>(pnRet
));
130 if (nRet
!=TRISTATE_INDET
) {
131 bool bOn
=rGP
.IsPercent();
132 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
134 nRet
= bOn
? TRISTATE_TRUE
: TRISTATE_FALSE
;
137 else if ((nRet
!=TRISTATE_FALSE
)!=bOn
)
142 TriState
SdrGlueEditView::IsMarkedGluePointsPercent() const
144 ForceUndirtyMrkPnt();
146 TriState nRet
= TRISTATE_TRUE
;
147 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetPercent
,true,&bFirst
,&nRet
);
151 static void ImpSetPercent(SdrGluePoint
& rGP
, const SdrObject
* pObj
, const void* pbOn
, const void*, const void*, const void*)
153 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
154 rGP
.SetPercent(*static_cast<bool const *>(pbOn
));
155 rGP
.SetAbsolutePos(aPos
,*pObj
);
158 void SdrGlueEditView::SetMarkedGluePointsPercent(bool bOn
)
160 ForceUndirtyMrkPnt();
161 BegUndo(SvxResId(STR_EditSetGluePercent
),GetDescriptionOfMarkedGluePoints());
162 ImpDoMarkedGluePoints(ImpSetPercent
,false,&bOn
);
167 static void ImpGetAlign(SdrGluePoint
& rGP
, const SdrObject
* /*pObj*/, const void* pbFirst
, const void* pbDontCare
, const void* pbVert
, const void* pnRet
)
169 SdrAlign
& nRet
=*const_cast<SdrAlign
*>(static_cast<SdrAlign
const *>(pnRet
));
170 bool& bDontCare
=*const_cast<bool *>(static_cast<bool const *>(pbDontCare
));
171 bool bVert
=*static_cast<bool const *>(pbVert
);
175 SdrAlign nAlg
=SdrAlign::NONE
;
177 nAlg
=rGP
.GetVertAlign();
179 nAlg
=rGP
.GetHorzAlign();
181 bool& bFirst
=*const_cast<bool *>(static_cast<bool const *>(pbFirst
));
182 if (bFirst
) { nRet
=nAlg
; bFirst
=false; }
183 else if (nRet
!=nAlg
) {
185 nRet
=SdrAlign::VERT_DONTCARE
;
187 nRet
=SdrAlign::HORZ_DONTCARE
;
193 SdrAlign
SdrGlueEditView::GetMarkedGluePointsAlign(bool bVert
) const
195 ForceUndirtyMrkPnt();
197 bool bDontCare
=false;
198 SdrAlign nRet
=SdrAlign::NONE
;
199 const_cast<SdrGlueEditView
*>(this)->ImpDoMarkedGluePoints(ImpGetAlign
,true,&bFirst
,&bDontCare
,&bVert
,&nRet
);
203 static void ImpSetAlign(SdrGluePoint
& rGP
, const SdrObject
* pObj
, const void* pbVert
, const void* pnAlign
, const void*, const void*)
205 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
206 if (*static_cast<bool const *>(pbVert
)) { // bVert?
207 rGP
.SetVertAlign(*static_cast<SdrAlign
const *>(pnAlign
));
209 rGP
.SetHorzAlign(*static_cast<SdrAlign
const *>(pnAlign
));
211 rGP
.SetAbsolutePos(aPos
,*pObj
);
214 void SdrGlueEditView::SetMarkedGluePointsAlign(bool bVert
, SdrAlign nAlign
)
216 ForceUndirtyMrkPnt();
217 BegUndo(SvxResId(STR_EditSetGlueAlign
),GetDescriptionOfMarkedGluePoints());
218 ImpDoMarkedGluePoints(ImpSetAlign
,false,&bVert
,&nAlign
);
222 void SdrGlueEditView::DeleteMarkedGluePoints()
225 ForceUndirtyMrkPnt();
226 const bool bUndo
= IsUndoEnabled();
228 BegUndo(SvxResId(STR_EditDelete
),GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Delete
);
230 const size_t nMarkCount
=GetMarkedObjectCount();
231 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
233 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
234 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
235 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
238 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
242 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
244 for(sal_uInt16 nPtId
: rPts
)
246 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
247 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
249 pGPL
->Delete(nGlueIdx
);
253 pObj
->BroadcastObjectChange();
259 UnmarkAllGluePoints();
261 mpModel
->SetChanged();
265 void SdrGlueEditView::ImpCopyMarkedGluePoints()
267 const bool bUndo
= IsUndoEnabled();
272 const size_t nMarkCount
=GetMarkedObjectCount();
273 for (size_t nm
=0; nm
<nMarkCount
; ++nm
)
275 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
276 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
277 SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
278 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
279 if (!rPts
.empty() && pGPL
!=nullptr)
282 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
284 SdrUShortCont aIdsToErase
;
285 SdrUShortCont aIdsToInsert
;
286 for(sal_uInt16 nPtId
: rPts
)
288 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
289 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
)
291 SdrGluePoint
aNewGP((*pGPL
)[nGlueIdx
]); // clone GluePoint
292 sal_uInt16 nNewIdx
=pGPL
->Insert(aNewGP
); // and insert it
293 sal_uInt16 nNewId
=(*pGPL
)[nNewIdx
].GetId(); // retrieve ID of new GluePoints
294 aIdsToErase
.insert(nPtId
); // select it (instead of the old one)
295 aIdsToInsert
.insert(nNewId
);
298 for(const auto& rId
: aIdsToErase
)
300 rPts
.insert(aIdsToInsert
);
307 mpModel
->SetChanged();
311 void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc
, const void* p1
, const void* p2
, const void* p3
, const void* p4
)
313 const size_t nMarkCount
=GetMarkedObjectCount();
314 for (size_t nm
=0; nm
<nMarkCount
; ++nm
) {
315 SdrMark
* pM
=GetSdrMarkByIndex(nm
);
316 SdrObject
* pObj
=pM
->GetMarkedSdrObj();
317 const SdrUShortCont
& rPts
= pM
->GetMarkedGluePoints();
319 SdrGluePointList
* pGPL
=pObj
->ForceGluePointList();
322 if( IsUndoEnabled() )
323 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj
));
325 for(sal_uInt16 nPtId
: rPts
)
327 sal_uInt16 nGlueIdx
=pGPL
->FindGluePoint(nPtId
);
328 if (nGlueIdx
!=SDRGLUEPOINT_NOTFOUND
) {
329 SdrGluePoint
& rGP
=(*pGPL
)[nGlueIdx
];
330 Point
aPos(rGP
.GetAbsolutePos(*pObj
));
331 (*pTrFunc
)(aPos
,p1
,p2
,p3
,p4
);
332 rGP
.SetAbsolutePos(aPos
,*pObj
);
336 pObj
->BroadcastObjectChange();
340 if (nMarkCount
!=0) mpModel
->SetChanged();
344 static void ImpMove(Point
& rPt
, const void* p1
, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/)
346 rPt
.AdjustX(static_cast<const Size
*>(p1
)->Width() );
347 rPt
.AdjustY(static_cast<const Size
*>(p1
)->Height() );
350 void SdrGlueEditView::MoveMarkedGluePoints(const Size
& rSiz
, bool bCopy
)
352 ForceUndirtyMrkPnt();
353 OUString
aStr(SvxResId(STR_EditMove
));
354 if (bCopy
) aStr
+= SvxResId(STR_EditWithCopy
);
355 BegUndo(aStr
,GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Move
);
356 if (bCopy
) ImpCopyMarkedGluePoints();
357 ImpTransformMarkedGluePoints(ImpMove
,&rSiz
);
363 static void ImpResize(Point
& rPt
, const void* p1
, const void* p2
, const void* p3
, const void* /*p4*/)
365 ResizePoint(rPt
,*static_cast<const Point
*>(p1
),*static_cast<const Fraction
*>(p2
),*static_cast<const Fraction
*>(p3
));
368 void SdrGlueEditView::ResizeMarkedGluePoints(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bCopy
)
370 ForceUndirtyMrkPnt();
371 OUString
aStr(SvxResId(STR_EditResize
));
372 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
373 BegUndo(aStr
,GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Resize
);
374 if (bCopy
) ImpCopyMarkedGluePoints();
375 ImpTransformMarkedGluePoints(ImpResize
,&rRef
,&xFact
,&yFact
);
381 static void ImpRotate(Point
& rPt
, const void* p1
, const void* /*p2*/, const void* p3
, const void* p4
)
383 RotatePoint(rPt
,*static_cast<const Point
*>(p1
),*static_cast<const double*>(p3
),*static_cast<const double*>(p4
));
386 void SdrGlueEditView::RotateMarkedGluePoints(const Point
& rRef
, tools::Long nAngle
, bool bCopy
)
388 ForceUndirtyMrkPnt();
389 OUString
aStr(SvxResId(STR_EditRotate
));
390 if (bCopy
) aStr
+=SvxResId(STR_EditWithCopy
);
391 BegUndo(aStr
,GetDescriptionOfMarkedGluePoints(),SdrRepeatFunc::Rotate
);
392 if (bCopy
) ImpCopyMarkedGluePoints();
393 double nSin
= sin(nAngle
* F_PI18000
);
394 double nCos
= cos(nAngle
* F_PI18000
);
395 ImpTransformMarkedGluePoints(ImpRotate
,&rRef
,&nAngle
,&nSin
,&nCos
);
400 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */