xref: /aoo42x/main/svx/source/svdraw/svdpoev.cxx (revision cdf0e10c)
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