Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / svx / source / svdraw / svdglev.cxx
blob5a67e3685f8554f1ad8c4cb28aa51c3b052cd1de
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <math.h>
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(
32 SdrModel& rSdrModel,
33 OutputDevice* pOut)
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();
49 if (!rPts.empty())
51 SdrGluePointList* pGPL=nullptr;
52 if (bConst) {
53 const SdrGluePointList* pConstGPL=pObj->GetGluePointList();
54 pGPL=const_cast<SdrGluePointList*>(pConstGPL);
55 } else {
56 pGPL=pObj->ForceGluePointList();
58 if (pGPL!=nullptr)
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);
72 if (!bConst)
74 pObj->SetChanged();
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));
92 if (bFirst) {
93 nRet = bOn ? TRISTATE_TRUE : TRISTATE_FALSE;
94 bFirst = false;
96 else if (nRet != (bOn ? TRISTATE_TRUE : TRISTATE_FALSE)) nRet=TRISTATE_INDET;
100 TriState SdrGlueEditView::IsMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc) const
102 ForceUndirtyMrkPnt();
103 bool bFirst=true;
104 TriState nRet=TRISTATE_FALSE;
105 const_cast<SdrGlueEditView*>(this)->ImpDoMarkedGluePoints(ImpGetEscDir,true,&bFirst,&nThisEsc,&nRet);
106 return 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);
114 else
115 nEsc &= ~*static_cast<SdrEscapeDirection const *>(pnThisEsc);
116 rGP.SetEscDir(nEsc);
119 void SdrGlueEditView::SetMarkedGluePointsEscDir(SdrEscapeDirection nThisEsc, bool bOn)
121 ForceUndirtyMrkPnt();
122 BegUndo(SvxResId(STR_EditSetGlueEscDir),GetDescriptionOfMarkedGluePoints());
123 ImpDoMarkedGluePoints(ImpSetEscDir,false,&nThisEsc,&bOn);
124 EndUndo();
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));
134 if (bFirst) {
135 nRet = bOn ? TRISTATE_TRUE : TRISTATE_FALSE;
136 bFirst = false;
138 else if ((nRet!=TRISTATE_FALSE)!=bOn)
139 nRet=TRISTATE_INDET;
143 TriState SdrGlueEditView::IsMarkedGluePointsPercent() const
145 ForceUndirtyMrkPnt();
146 bool bFirst=true;
147 TriState nRet = TRISTATE_TRUE;
148 const_cast<SdrGlueEditView*>(this)->ImpDoMarkedGluePoints(ImpGetPercent,true,&bFirst,&nRet);
149 return 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);
164 EndUndo();
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);
173 if (bDontCare)
174 return;
176 SdrAlign nAlg=SdrAlign::NONE;
177 if (bVert) {
178 nAlg=rGP.GetVertAlign();
179 } else {
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) {
185 if (bVert) {
186 nRet=SdrAlign::VERT_DONTCARE;
187 } else {
188 nRet=SdrAlign::HORZ_DONTCARE;
190 bDontCare=true;
194 SdrAlign SdrGlueEditView::GetMarkedGluePointsAlign(bool bVert) const
196 ForceUndirtyMrkPnt();
197 bool bFirst=true;
198 bool bDontCare=false;
199 SdrAlign nRet=SdrAlign::NONE;
200 const_cast<SdrGlueEditView*>(this)->ImpDoMarkedGluePoints(ImpGetAlign,true,&bFirst,&bDontCare,&bVert,&nRet);
201 return 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));
209 } else {
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);
220 EndUndo();
223 void SdrGlueEditView::DeleteMarkedGluePoints()
225 BrkAction();
226 ForceUndirtyMrkPnt();
227 const bool bUndo = IsUndoEnabled();
228 if( bUndo )
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();
237 if (!rPts.empty())
239 SdrGluePointList* pGPL=pObj->ForceGluePointList();
240 if (pGPL!=nullptr)
242 if( bUndo )
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);
253 pObj->SetChanged();
254 pObj->BroadcastObjectChange();
258 if( bUndo )
259 EndUndo();
260 UnmarkAllGluePoints();
261 if (nMarkCount!=0)
262 GetModel().SetChanged();
266 void SdrGlueEditView::ImpCopyMarkedGluePoints()
268 const bool bUndo = IsUndoEnabled();
270 if( bUndo )
271 BegUndo();
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)
282 if( bUndo )
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)
300 rPts.erase(rId);
301 rPts.insert(aIdsToInsert);
304 if( bUndo )
305 EndUndo();
307 if (nMarkCount!=0)
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();
319 if (!rPts.empty()) {
320 SdrGluePointList* pGPL=pObj->ForceGluePointList();
321 if (pGPL!=nullptr)
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);
336 pObj->SetChanged();
337 pObj->BroadcastObjectChange();
341 if (nMarkCount!=0)
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);
360 EndUndo();
361 AdjustMarkHdl();
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);
378 EndUndo();
379 AdjustMarkHdl();
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);
398 EndUndo();
399 AdjustMarkHdl();
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */