Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <svx/svdpoev.hxx>
22 : #include <math.h>
23 : #include <svx/svdpagv.hxx>
24 : #include <svx/svdpage.hxx>
25 : #include <svx/svdopath.hxx>
26 : #include <svx/svdundo.hxx>
27 : #include "svx/svdstr.hrc"
28 : #include "svdglob.hxx"
29 : #include <svx/svdtrans.hxx>
30 : #include <basegfx/polygon/b2dpolygon.hxx>
31 : #include <basegfx/polygon/b2dpolygontools.hxx>
32 : #include <tools/helpers.hxx>
33 :
34 : #include <svx/polypolygoneditor.hxx>
35 :
36 : using namespace sdr;
37 :
38 :
39 :
40 11826 : void SdrPolyEditView::ImpResetPolyPossibilityFlags()
41 : {
42 11826 : eMarkedPointsSmooth=SDRPATHSMOOTH_DONTCARE;
43 11826 : eMarkedSegmentsKind=SDRPATHSEGMENT_DONTCARE;
44 11826 : bSetMarkedPointsSmoothPossible=false;
45 11826 : bSetMarkedSegmentsKindPossible=false;
46 11826 : }
47 :
48 9504 : void SdrPolyEditView::ImpClearVars()
49 : {
50 9504 : ImpResetPolyPossibilityFlags();
51 9504 : }
52 :
53 9504 : SdrPolyEditView::SdrPolyEditView(SdrModel* pModel1, OutputDevice* pOut):
54 9504 : SdrEditView(pModel1,pOut)
55 : {
56 9504 : ImpClearVars();
57 9504 : }
58 :
59 9438 : SdrPolyEditView::~SdrPolyEditView()
60 : {
61 9438 : }
62 :
63 2322 : void SdrPolyEditView::ImpCheckPolyPossibilities()
64 : {
65 2322 : ImpResetPolyPossibilityFlags();
66 2322 : const size_t nMarkCount(GetMarkedObjectCount());
67 :
68 2322 : if(nMarkCount && !ImpIsFrameHandles())
69 : {
70 3 : bool b1stSmooth(true);
71 3 : bool b1stSegm(true);
72 3 : bool bCurve(false);
73 3 : bool bSmoothFuz(false);
74 3 : bool bSegmFuz(false);
75 3 : basegfx::B2VectorContinuity eSmooth = basegfx::B2VectorContinuity::NONE;
76 :
77 6 : for(size_t nMarkNum = 0; nMarkNum < nMarkCount; ++nMarkNum)
78 : {
79 3 : SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
80 3 : CheckPolyPossibilitiesHelper( pM, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth );
81 : }
82 : }
83 2322 : }
84 :
85 3 : void SdrPolyEditView::CheckPolyPossibilitiesHelper( SdrMark* pM, bool& b1stSmooth, bool& b1stSegm, bool& bCurve, bool& bSmoothFuz, bool& bSegmFuz, basegfx::B2VectorContinuity& eSmooth )
86 : {
87 3 : SdrObject* pObj = pM->GetMarkedSdrObj();
88 3 : SdrUShortCont* pPts = pM->GetMarkedPoints();
89 3 : SdrPathObj* pPath = PTR_CAST(SdrPathObj,pObj);
90 :
91 3 : if(pPath && pPts)
92 : {
93 0 : const sal_uInt32 nMarkedPntAnz(pPts->size());
94 :
95 0 : if(nMarkedPntAnz)
96 : {
97 0 : bool bClosed(pPath->IsClosed());
98 0 : bSetMarkedPointsSmoothPossible = true;
99 :
100 0 : if(bClosed)
101 : {
102 0 : bSetMarkedSegmentsKindPossible = true;
103 : }
104 :
105 0 : for(SdrUShortCont::const_iterator it = pPts->begin(); it != pPts->end(); ++it)
106 : {
107 0 : sal_uInt32 nNum(*it);
108 : sal_uInt32 nPolyNum, nPntNum;
109 :
110 0 : if(PolyPolygonEditor::GetRelativePolyPoint(pPath->GetPathPoly(), nNum, nPolyNum, nPntNum))
111 : {
112 0 : const basegfx::B2DPolygon aLocalPolygon(pPath->GetPathPoly().getB2DPolygon(nPolyNum));
113 0 : bool bCanSegment(bClosed || nPntNum < aLocalPolygon.count() - 1L);
114 :
115 0 : if(!bSetMarkedSegmentsKindPossible && bCanSegment)
116 : {
117 0 : bSetMarkedSegmentsKindPossible = true;
118 : }
119 :
120 0 : if(!bSmoothFuz)
121 : {
122 0 : if (b1stSmooth)
123 : {
124 0 : b1stSmooth = false;
125 0 : eSmooth = basegfx::tools::getContinuityInPoint(aLocalPolygon, nPntNum);
126 : }
127 : else
128 : {
129 0 : bSmoothFuz = (eSmooth != basegfx::tools::getContinuityInPoint(aLocalPolygon, nPntNum));
130 : }
131 : }
132 :
133 0 : if(!bSegmFuz)
134 : {
135 0 : if(bCanSegment)
136 : {
137 0 : bool bCrv(aLocalPolygon.isNextControlPointUsed(nPntNum));
138 :
139 0 : if(b1stSegm)
140 : {
141 0 : b1stSegm = false;
142 0 : bCurve = bCrv;
143 : }
144 : else
145 : {
146 0 : bSegmFuz = (bCrv != bCurve);
147 : }
148 : }
149 0 : }
150 : }
151 : }
152 :
153 0 : if(!b1stSmooth && !bSmoothFuz)
154 : {
155 0 : if(basegfx::B2VectorContinuity::NONE == eSmooth)
156 : {
157 0 : eMarkedPointsSmooth = SDRPATHSMOOTH_ANGULAR;
158 : }
159 :
160 0 : if(basegfx::B2VectorContinuity::C1 == eSmooth)
161 : {
162 0 : eMarkedPointsSmooth = SDRPATHSMOOTH_ASYMMETRIC;
163 : }
164 :
165 0 : if(basegfx::B2VectorContinuity::C2 == eSmooth)
166 : {
167 0 : eMarkedPointsSmooth = SDRPATHSMOOTH_SYMMETRIC;
168 : }
169 : }
170 :
171 0 : if(!b1stSegm && !bSegmFuz)
172 : {
173 0 : eMarkedSegmentsKind = (bCurve) ? SDRPATHSEGMENT_CURVE : SDRPATHSEGMENT_LINE;
174 : }
175 : }
176 : }
177 3 : }
178 :
179 0 : void SdrPolyEditView::SetMarkedPointsSmooth(SdrPathSmoothKind eKind)
180 : {
181 : basegfx::B2VectorContinuity eFlags;
182 :
183 0 : if(SDRPATHSMOOTH_ANGULAR == eKind)
184 : {
185 0 : eFlags = basegfx::B2VectorContinuity::NONE;
186 : }
187 0 : else if(SDRPATHSMOOTH_ASYMMETRIC == eKind)
188 : {
189 0 : eFlags = basegfx::B2VectorContinuity::C1;
190 : }
191 0 : else if(SDRPATHSMOOTH_SYMMETRIC == eKind)
192 : {
193 0 : eFlags = basegfx::B2VectorContinuity::C2;
194 : }
195 : else
196 : {
197 0 : return;
198 : }
199 :
200 0 : if(HasMarkedPoints())
201 : {
202 0 : SortMarkedObjects();
203 :
204 0 : const bool bUndo = IsUndoEnabled();
205 0 : if( bUndo )
206 0 : BegUndo(ImpGetResStr(STR_EditSetPointsSmooth), GetDescriptionOfMarkedPoints());
207 0 : const size_t nMarkCount(GetMarkedObjectCount());
208 :
209 0 : for(size_t nMarkNum(nMarkCount); nMarkNum > 0;)
210 : {
211 0 : --nMarkNum;
212 0 : SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
213 0 : SdrUShortCont* pPts = pM->GetMarkedPoints();
214 0 : SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
215 :
216 0 : if(pPts && pPath)
217 : {
218 0 : PolyPolygonEditor aEditor( pPath->GetPathPoly(), pPath->IsClosed() );
219 0 : if(aEditor.SetPointsSmooth( eFlags, *pPts ) )
220 : {
221 0 : if( bUndo )
222 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
223 0 : pPath->SetPathPoly(aEditor.GetPolyPolygon());
224 0 : }
225 : }
226 : }
227 :
228 0 : if( bUndo )
229 0 : EndUndo();
230 : }
231 : }
232 :
233 0 : void SdrPolyEditView::SetMarkedSegmentsKind(SdrPathSegmentKind eKind)
234 : {
235 0 : if(HasMarkedPoints())
236 : {
237 0 : SortMarkedObjects();
238 :
239 0 : const bool bUndo = IsUndoEnabled();
240 0 : if( bUndo )
241 0 : BegUndo(ImpGetResStr(STR_EditSetSegmentsKind), GetDescriptionOfMarkedPoints());
242 0 : const size_t nMarkCount(GetMarkedObjectCount());
243 :
244 0 : for(size_t nMarkNum=nMarkCount; nMarkNum > 0;)
245 : {
246 0 : --nMarkNum;
247 0 : SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
248 0 : SdrUShortCont* pPts = pM->GetMarkedPoints();
249 0 : SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
250 :
251 0 : if(pPts && pPath)
252 : {
253 0 : PolyPolygonEditor aEditor( pPath->GetPathPoly(), pPath->IsClosed() );
254 0 : if(aEditor.SetSegmentsKind( eKind, *pPts ) )
255 : {
256 0 : if( bUndo )
257 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
258 0 : pPath->SetPathPoly(aEditor.GetPolyPolygon());
259 0 : }
260 : }
261 : }
262 :
263 0 : if( bUndo )
264 0 : EndUndo();
265 : }
266 0 : }
267 :
268 0 : bool SdrPolyEditView::IsSetMarkedPointsSmoothPossible() const
269 : {
270 0 : ForcePossibilities();
271 0 : return bSetMarkedPointsSmoothPossible;
272 : }
273 :
274 0 : SdrPathSmoothKind SdrPolyEditView::GetMarkedPointsSmooth() const
275 : {
276 0 : ForcePossibilities();
277 0 : return eMarkedPointsSmooth;
278 : }
279 :
280 0 : bool SdrPolyEditView::IsSetMarkedSegmentsKindPossible() const
281 : {
282 0 : ForcePossibilities();
283 0 : return bSetMarkedSegmentsKindPossible;
284 : }
285 :
286 0 : SdrPathSegmentKind SdrPolyEditView::GetMarkedSegmentsKind() const
287 : {
288 0 : ForcePossibilities();
289 0 : return eMarkedSegmentsKind;
290 : }
291 :
292 0 : bool SdrPolyEditView::IsDeleteMarkedPointsPossible() const
293 : {
294 0 : return HasMarkedPoints();
295 : }
296 :
297 0 : void SdrPolyEditView::DeleteMarkedPoints()
298 : {
299 0 : if (HasMarkedPoints())
300 : {
301 0 : BrkAction();
302 0 : SortMarkedObjects();
303 0 : const size_t nMarkCount=GetMarkedObjectCount();
304 :
305 0 : const bool bUndo = IsUndoEnabled();
306 0 : if( bUndo )
307 : {
308 : // Description
309 0 : BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE);
310 : }
311 :
312 0 : for (size_t nMarkNum=nMarkCount; nMarkNum>0;)
313 : {
314 0 : --nMarkNum;
315 0 : SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
316 0 : SdrUShortCont* pPts=pM->GetMarkedPoints();
317 0 : SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
318 :
319 0 : if( pPath && pPts )
320 : {
321 0 : PolyPolygonEditor aEditor( pPath->GetPathPoly(), pPath->IsClosed() );
322 0 : if( aEditor.DeletePoints( *pPts ) )
323 : {
324 0 : if( aEditor.GetPolyPolygon().count() )
325 : {
326 0 : if( bUndo )
327 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath ));
328 0 : pPath->SetPathPoly( aEditor.GetPolyPolygon() );
329 : }
330 : else
331 : {
332 0 : if( bUndo )
333 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) );
334 0 : pM->GetPageView()->GetObjList()->RemoveObject(pPath->GetOrdNum());
335 0 : if( !bUndo )
336 : {
337 0 : SdrObject* pObj = pPath;
338 0 : SdrObject::Free(pObj);
339 : }
340 : }
341 0 : }
342 : }
343 : }
344 :
345 0 : if( bUndo )
346 0 : EndUndo();
347 0 : UnmarkAllPoints();
348 0 : MarkListHasChanged();
349 : }
350 0 : }
351 :
352 0 : void SdrPolyEditView::RipUpAtMarkedPoints()
353 : {
354 0 : if(HasMarkedPoints())
355 : {
356 0 : SortMarkedObjects();
357 0 : const size_t nMarkCount(GetMarkedObjectCount());
358 :
359 0 : const bool bUndo = IsUndoEnabled();
360 0 : if( bUndo )
361 0 : BegUndo(ImpGetResStr(STR_EditRipUp), GetDescriptionOfMarkedPoints());
362 :
363 0 : for(size_t nMarkNum = nMarkCount; nMarkNum > 0;)
364 : {
365 0 : --nMarkNum;
366 0 : SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
367 0 : SdrUShortCont* pPts = pM->GetMarkedPoints();
368 0 : SdrPathObj* pObj = PTR_CAST(SdrPathObj, pM->GetMarkedSdrObj());
369 :
370 0 : if(pPts && pObj)
371 : {
372 0 : if( bUndo )
373 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
374 0 : bool bKorregFlag(false);
375 0 : sal_uInt32 nMax(pObj->GetHdlCount());
376 :
377 0 : for(SdrUShortCont::const_reverse_iterator it = pPts->rbegin(); it != pPts->rend(); ++it)
378 : {
379 0 : sal_uInt32 nNewPt0Idx(0L);
380 0 : SdrObject* pNeuObj = pObj->RipPoint(*it, nNewPt0Idx);
381 :
382 0 : if(pNeuObj)
383 : {
384 0 : SdrInsertReason aReason(SDRREASON_VIEWCALL, pObj);
385 0 : pM->GetPageView()->GetObjList()->InsertObject(pNeuObj, pObj->GetOrdNum() + 1, &aReason);
386 0 : if( bUndo )
387 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj));
388 0 : MarkObj(pNeuObj, pM->GetPageView(), false, true);
389 : }
390 :
391 0 : if(nNewPt0Idx)
392 : {
393 : // correction necessary?
394 : DBG_ASSERT(!bKorregFlag,"Multiple index corrections at SdrPolyEditView::RipUp().");
395 0 : if(!bKorregFlag)
396 : {
397 0 : bKorregFlag = true;
398 :
399 0 : SdrUShortCont aReplaceSet;
400 0 : for(SdrUShortCont::const_iterator it2 = pPts->begin(); it2 != pPts->end(); ++it2)
401 : {
402 0 : sal_uInt32 nPntNum(*it2);
403 0 : nPntNum += nNewPt0Idx;
404 :
405 0 : if(nPntNum >= nMax)
406 : {
407 0 : nPntNum -= nMax;
408 : }
409 :
410 0 : aReplaceSet.insert( (sal_uInt16)nPntNum );
411 : }
412 0 : pPts->swap(aReplaceSet);
413 :
414 0 : it = pPts->rbegin();
415 : }
416 : }
417 : }
418 : }
419 : }
420 :
421 0 : UnmarkAllPoints();
422 0 : if( bUndo )
423 0 : EndUndo();
424 0 : MarkListHasChanged();
425 : }
426 0 : }
427 :
428 0 : bool SdrPolyEditView::IsRipUpAtMarkedPointsPossible() const
429 : {
430 0 : bool bRetval(false);
431 0 : const size_t nMarkCount(GetMarkedObjectCount());
432 :
433 0 : for(size_t a = 0; a < nMarkCount; ++a)
434 : {
435 0 : const SdrMark* pMark = GetSdrMarkByIndex(a);
436 0 : const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
437 :
438 0 : if(pMarkedPathObject)
439 : {
440 0 : const SdrUShortCont* pSelectedPoints = pMark->GetMarkedPoints();
441 :
442 0 : if(pSelectedPoints && !pSelectedPoints->empty())
443 : {
444 0 : const basegfx::B2DPolyPolygon& rPathPolyPolygon = pMarkedPathObject->GetPathPoly();
445 :
446 0 : if(1 == rPathPolyPolygon.count())
447 : {
448 : // #i76617# Do not yet use basegfx::B2DPolygon since curve definitions
449 : // are different and methods need to be changed thoroughly with interaction rework
450 0 : const Polygon aPathPolygon(rPathPolyPolygon.getB2DPolygon(0));
451 0 : const sal_uInt16 nPointCount(aPathPolygon.GetSize());
452 :
453 0 : if(nPointCount >= 3)
454 : {
455 0 : bRetval = pMarkedPathObject->IsClosedObj(); // #i76617#
456 :
457 0 : for(SdrUShortCont::const_iterator it = pSelectedPoints->begin();
458 0 : !bRetval && it != pSelectedPoints->end(); ++it)
459 : {
460 0 : const sal_uInt16 nMarkedPointNum(*it);
461 :
462 0 : bRetval = (nMarkedPointNum > 0 && nMarkedPointNum < nPointCount - 1);
463 : }
464 0 : }
465 : }
466 : }
467 : }
468 : }
469 :
470 0 : return bRetval;
471 : }
472 :
473 0 : bool SdrPolyEditView::IsOpenCloseMarkedObjectsPossible() const
474 : {
475 0 : bool bRetval(false);
476 0 : const size_t nMarkCount(GetMarkedObjectCount());
477 :
478 0 : for(size_t a = 0; a < nMarkCount; ++a)
479 : {
480 0 : const SdrMark* pMark = GetSdrMarkByIndex(a);
481 0 : const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
482 :
483 0 : if(pMarkedPathObject)
484 : {
485 : // #i76617# Do not yet use basegfx::B2DPolygon since curve definitions
486 : // are different and methods need to be changed thoroughly with interaction rework
487 0 : const tools::PolyPolygon aPathPolyPolygon(pMarkedPathObject->GetPathPoly());
488 0 : const sal_uInt16 nPolygonCount(aPathPolyPolygon.Count());
489 :
490 0 : for(sal_uInt16 b(0); !bRetval && b < nPolygonCount; b++)
491 : {
492 0 : const Polygon& rPathPolygon = aPathPolyPolygon[b];
493 0 : const sal_uInt16 nPointCount(rPathPolygon.GetSize());
494 :
495 0 : bRetval = (nPointCount >= 3);
496 0 : }
497 : }
498 : }
499 :
500 0 : return bRetval;
501 : }
502 :
503 0 : SdrObjClosedKind SdrPolyEditView::GetMarkedObjectsClosedState() const
504 : {
505 0 : bool bOpen(false);
506 0 : bool bClosed(false);
507 0 : const size_t nMarkCount(GetMarkedObjectCount());
508 :
509 0 : for(size_t a = 0; !(bOpen && bClosed) && a < nMarkCount; ++a)
510 : {
511 0 : const SdrMark* pMark = GetSdrMarkByIndex(a);
512 0 : const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
513 :
514 0 : if(pMarkedPathObject)
515 : {
516 0 : if(pMarkedPathObject->IsClosedObj())
517 : {
518 0 : bClosed = true;
519 : }
520 : else
521 : {
522 0 : bOpen = true;
523 : }
524 : }
525 : }
526 :
527 0 : if(bOpen && bClosed)
528 : {
529 0 : return SDROBJCLOSED_DONTCARE;
530 : }
531 0 : else if(bOpen)
532 : {
533 0 : return SDROBJCLOSED_OPEN;
534 : }
535 : else
536 : {
537 0 : return SDROBJCLOSED_CLOSED;
538 : }
539 : }
540 :
541 0 : void SdrPolyEditView::CloseMarkedObjects(bool bToggle, bool bOpen)
542 : {
543 0 : if (AreObjectsMarked())
544 : {
545 0 : const bool bUndo = IsUndoEnabled();
546 0 : if( bUndo )
547 0 : BegUndo(ImpGetResStr(STR_EditShut),GetDescriptionOfMarkedPoints());
548 :
549 0 : bool bChg=false;
550 0 : const size_t nMarkCount=GetMarkedObjectCount();
551 0 : for (size_t nm=0; nm<nMarkCount; ++nm)
552 : {
553 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
554 0 : SdrObject* pO=pM->GetMarkedSdrObj();
555 0 : bool bClosed=pO->IsClosedObj();
556 0 : if ((pO->IsPolyObj() && (bClosed==bOpen)) || bToggle)
557 : {
558 0 : if( bUndo )
559 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
560 :
561 0 : SdrPathObj* pPathObj = dynamic_cast< SdrPathObj* >( pO );
562 0 : if(pPathObj)
563 0 : pPathObj->ToggleClosed();
564 0 : bChg=true;
565 : }
566 : }
567 :
568 0 : if( bUndo )
569 0 : EndUndo();
570 :
571 0 : if (bChg)
572 : {
573 0 : UnmarkAllPoints();
574 0 : MarkListHasChanged();
575 : }
576 : }
577 0 : }
578 :
579 :
580 :
581 0 : void SdrPolyEditView::ImpTransformMarkedPoints(PPolyTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
582 : {
583 0 : const bool bUndo = IsUndoEnabled();
584 :
585 0 : const size_t nMarkCount=GetMarkedObjectCount();
586 0 : for (size_t nm=0; nm<nMarkCount; ++nm)
587 : {
588 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
589 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
590 0 : const SdrUShortCont* pPts=pM->GetMarkedPoints();
591 0 : sal_uIntPtr nPointCount=pPts==NULL ? 0 : pPts->size();
592 0 : SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
593 0 : if (nPointCount!=0 && pPath!=NULL)
594 : {
595 0 : if( bUndo )
596 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
597 :
598 0 : basegfx::B2DPolyPolygon aXPP(pPath->GetPathPoly());
599 :
600 0 : for(SdrUShortCont::const_iterator it = pPts->begin(); it != pPts->end(); ++it)
601 : {
602 0 : sal_uInt32 nPt = *it;
603 : sal_uInt32 nPolyNum, nPointNum;
604 :
605 0 : if(PolyPolygonEditor::GetRelativePolyPoint(aXPP, nPt, nPolyNum, nPointNum))
606 : {
607 : //#i83671# used nLocalPointNum (which was the polygon point count)
608 : // instead of the point index (nPointNum). This of course leaded
609 : // to a wrong point access to the B2DPolygon.
610 0 : basegfx::B2DPolygon aNewXP(aXPP.getB2DPolygon(nPolyNum));
611 0 : Point aPos, aC1, aC2;
612 0 : bool bC1(false);
613 0 : bool bC2(false);
614 :
615 0 : const basegfx::B2DPoint aB2DPos(aNewXP.getB2DPoint(nPointNum));
616 0 : aPos = Point(FRound(aB2DPos.getX()), FRound(aB2DPos.getY()));
617 :
618 0 : if(aNewXP.isPrevControlPointUsed(nPointNum))
619 : {
620 0 : const basegfx::B2DPoint aB2DC1(aNewXP.getPrevControlPoint(nPointNum));
621 0 : aC1 = Point(FRound(aB2DC1.getX()), FRound(aB2DC1.getY()));
622 0 : bC1 = true;
623 : }
624 :
625 0 : if(aNewXP.isNextControlPointUsed(nPointNum))
626 : {
627 0 : const basegfx::B2DPoint aB2DC2(aNewXP.getNextControlPoint(nPointNum));
628 0 : aC2 = Point(FRound(aB2DC2.getX()), FRound(aB2DC2.getY()));
629 0 : bC2 = true;
630 : }
631 :
632 0 : (*pTrFunc)(aPos,&aC1,&aC2,p1,p2,p3,p4,p5);
633 0 : aNewXP.setB2DPoint(nPointNum, basegfx::B2DPoint(aPos.X(), aPos.Y()));
634 :
635 0 : if (bC1)
636 : {
637 0 : aNewXP.setPrevControlPoint(nPointNum, basegfx::B2DPoint(aC1.X(), aC1.Y()));
638 : }
639 :
640 0 : if (bC2)
641 : {
642 0 : aNewXP.setNextControlPoint(nPointNum, basegfx::B2DPoint(aC2.X(), aC2.Y()));
643 : }
644 :
645 0 : aXPP.setB2DPolygon(nPolyNum, aNewXP);
646 : }
647 : }
648 :
649 0 : pPath->SetPathPoly(aXPP);
650 : }
651 : }
652 0 : }
653 :
654 :
655 :
656 0 : static void ImpMove(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/, const void* /*p5*/)
657 : {
658 0 : MovePoint(rPt,*static_cast<const Size*>(p1));
659 0 : if (pC1!=NULL) MovePoint(*pC1,*static_cast<const Size*>(p1));
660 0 : if (pC2!=NULL) MovePoint(*pC2,*static_cast<const Size*>(p1));
661 0 : }
662 :
663 0 : void SdrPolyEditView::MoveMarkedPoints(const Size& rSiz)
664 : {
665 0 : ForceUndirtyMrkPnt();
666 0 : OUString aStr(ImpGetResStr(STR_EditMove));
667 0 : BegUndo(aStr,GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_MOVE);
668 0 : ImpTransformMarkedPoints(ImpMove,&rSiz);
669 0 : EndUndo();
670 0 : AdjustMarkHdl();
671 0 : }
672 :
673 0 : static void ImpResize(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* p2, const void* p3, const void* /*p4*/, const void* /*p5*/)
674 : {
675 0 : ResizePoint(rPt,*static_cast<const Point*>(p1),*static_cast<const Fraction*>(p2),*static_cast<const Fraction*>(p3));
676 0 : if (pC1!=NULL) ResizePoint(*pC1,*static_cast<const Point*>(p1),*static_cast<const Fraction*>(p2),*static_cast<const Fraction*>(p3));
677 0 : if (pC2!=NULL) ResizePoint(*pC2,*static_cast<const Point*>(p1),*static_cast<const Fraction*>(p2),*static_cast<const Fraction*>(p3));
678 0 : }
679 :
680 0 : void SdrPolyEditView::ResizeMarkedPoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
681 : {
682 0 : ForceUndirtyMrkPnt();
683 0 : OUString aStr(ImpGetResStr(STR_EditResize));
684 0 : BegUndo(aStr,GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_RESIZE);
685 0 : ImpTransformMarkedPoints(ImpResize,&rRef,&xFact,&yFact);
686 0 : EndUndo();
687 0 : AdjustMarkHdl();
688 0 : }
689 :
690 0 : static void ImpRotate(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* /*p2*/, const void* p3, const void* p4, const void* /*p5*/)
691 : {
692 0 : RotatePoint(rPt,*static_cast<const Point*>(p1),*static_cast<const double*>(p3),*static_cast<const double*>(p4));
693 0 : if (pC1!=NULL) RotatePoint(*pC1,*static_cast<const Point*>(p1),*static_cast<const double*>(p3),*static_cast<const double*>(p4));
694 0 : if (pC2!=NULL) RotatePoint(*pC2,*static_cast<const Point*>(p1),*static_cast<const double*>(p3),*static_cast<const double*>(p4));
695 0 : }
696 :
697 0 : void SdrPolyEditView::RotateMarkedPoints(const Point& rRef, long nAngle)
698 : {
699 0 : ForceUndirtyMrkPnt();
700 0 : OUString aStr(ImpGetResStr(STR_EditResize));
701 0 : BegUndo(aStr,GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_ROTATE);
702 0 : double nSin=sin(nAngle*nPi180);
703 0 : double nCos=cos(nAngle*nPi180);
704 0 : ImpTransformMarkedPoints(ImpRotate,&rRef,&nAngle,&nSin,&nCos);
705 0 : EndUndo();
706 0 : AdjustMarkHdl();
707 435 : }
708 :
709 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|