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