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