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