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_sd.hxx"
26 
27 
28 #include <com/sun/star/util/XChangesNotifier.hpp>
29 
30 #include <basegfx/matrix/b2dhommatrix.hxx>
31 #include <basegfx/polygon/b2dpolygontools.hxx>
32 #include <basegfx/matrix/b2dhommatrixtools.hxx>
33 
34 #include <sfx2/viewfrm.hxx>
35 #include <sfx2/dispatch.hxx>
36 
37 #include <svx/sdr/overlay/overlaymanager.hxx>
38 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
39 #include <svx/svdpagv.hxx>
40 #include <svx/sdrpagewindow.hxx>
41 #include <svx/sdrpaintwindow.hxx>
42 #include <svx/svdopath.hxx>
43 #include <svx/xlndsit.hxx>
44 #include <svx/xlnclit.hxx>
45 #include <svx/xlnstit.hxx>
46 #include <svx/xlnedit.hxx>
47 #include <svx/xlnstwit.hxx>
48 #include <svx/xlnedwit.hxx>
49 #include <svx/xlnstcit.hxx>
50 #include <svx/xlnedcit.hxx>
51 #include <svx/xlntrit.hxx>
52 #include <svx/svxids.hrc>
53 #include <svx/polypolygoneditor.hxx>
54 #include <svx/svddrgmt.hxx>
55 
56 #include "CustomAnimationPane.hxx"
57 #include "View.hxx"
58 #include "motionpathtag.hxx"
59 #include "sdpage.hxx"
60 #include "ViewShell.hxx"
61 #include "app.hrc"
62 #include "Window.hxx"
63 
64 #include <svx/sdr/contact/viewcontact.hxx>
65 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
66 
67 using ::rtl::OUString;
68 using ::sdr::PolyPolygonEditor;
69 using namespace ::com::sun::star::uno;
70 using namespace ::com::sun::star::lang;
71 using namespace ::com::sun::star::util;
72 using namespace ::com::sun::star::drawing;
73 
74 namespace sd
75 {
76 
77 const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32;
78 static const int DRGPIX     = 2;                               // Drag MinMove in Pixel
79 
80 // --------------------------------------------------------------------
81 
82 class PathDragMove : public SdrDragMove
83 {
84 private:
85 	basegfx::B2DPolyPolygon			maPathPolyPolygon;
86 
87 protected:
88     virtual void createSdrDragEntries();
89 
90 public:
PathDragMove(SdrDragView & rNewView,const rtl::Reference<MotionPathTag> & xTag,const basegfx::B2DPolyPolygon & rPathPolyPolygon)91 	PathDragMove(SdrDragView& rNewView,
92 		const rtl::Reference <MotionPathTag >& xTag,
93 		const basegfx::B2DPolyPolygon& rPathPolyPolygon)
94 	:	SdrDragMove(rNewView),
95 		maPathPolyPolygon(rPathPolyPolygon),
96 		mxTag( xTag )
97 	{}
98 
PathDragMove(SdrDragView & rNewView,const rtl::Reference<MotionPathTag> & xTag)99 	PathDragMove(SdrDragView& rNewView,
100 		const rtl::Reference <MotionPathTag >& xTag)
101 	:	SdrDragMove(rNewView),
102 		maPathPolyPolygon(),
103 		mxTag( xTag )
104 	{}
105 
106 	virtual bool BeginSdrDrag();
107 	virtual bool EndSdrDrag(bool bCopy);
108 
109 	rtl::Reference <MotionPathTag > mxTag;
110 };
111 
createSdrDragEntries()112 void PathDragMove::createSdrDragEntries()
113 {
114 	// call parent
115 	SdrDragMove::createSdrDragEntries();
116 
117 	if(maPathPolyPolygon.count())
118 	{
119 	    addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
120 	}
121 }
122 
BeginSdrDrag()123 bool PathDragMove::BeginSdrDrag()
124 {
125 	if( mxTag.is() )
126 	{
127 		SdrPathObj* pPathObj = mxTag->getPathObj();
128 		if( pPathObj )
129 		{
130 			DragStat().SetActionRect(pPathObj->GetCurrentBoundRect());
131 		}
132 	}
133 	Show();
134 	return sal_True;
135 }
136 
EndSdrDrag(bool)137 bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
138 {
139 	Hide();
140 	if( mxTag.is() )
141 		mxTag->MovePath( DragStat().GetDX(), DragStat().GetDY() );
142 	return sal_True;
143 }
144 // --------------------------------------------------------------------
145 
146 class PathDragResize : public SdrDragResize
147 {
148 private:
149 	basegfx::B2DPolyPolygon			maPathPolyPolygon;
150 
151 protected:
152     virtual void createSdrDragEntries();
153 
154 public:
PathDragResize(SdrDragView & rNewView,const rtl::Reference<MotionPathTag> & xTag,const basegfx::B2DPolyPolygon & rPathPolyPolygon)155 	PathDragResize(SdrDragView& rNewView,
156 		const rtl::Reference <MotionPathTag >& xTag,
157 		const basegfx::B2DPolyPolygon& rPathPolyPolygon)
158 	:	SdrDragResize(rNewView),
159 		maPathPolyPolygon(rPathPolyPolygon),
160 		mxTag( xTag )
161 	{}
162 
PathDragResize(SdrDragView & rNewView,const rtl::Reference<MotionPathTag> & xTag)163 	PathDragResize(SdrDragView& rNewView,
164 		const rtl::Reference <MotionPathTag >& xTag)
165 	:	SdrDragResize(rNewView),
166 		maPathPolyPolygon(),
167 		mxTag( xTag )
168 	{}
169 
170 	virtual bool EndSdrDrag(bool bCopy);
171 	rtl::Reference <MotionPathTag > mxTag;
172 };
173 
createSdrDragEntries()174 void PathDragResize::createSdrDragEntries()
175 {
176 	// call parent
177 	SdrDragResize::createSdrDragEntries();
178 
179 	if(maPathPolyPolygon.count())
180 	{
181 	    addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
182 	}
183 }
184 
EndSdrDrag(bool)185 bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
186 {
187 	Hide();
188 	if( mxTag.is() )
189 	{
190 		SdrPathObj* pPathObj = mxTag->getPathObj();
191 		if( pPathObj )
192 		{
193 			const Point aRef( DragStat().Ref1() );
194             basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-aRef.X(), -aRef.Y()));
195 			aTrans.scale(double(aXFact), double(aYFact));
196 			aTrans.translate(aRef.X(), aRef.Y());
197 			basegfx::B2DPolyPolygon aDragPoly(pPathObj->GetPathPoly());
198 			aDragPoly.transform(aTrans);
199 			pPathObj->SetPathPoly( aDragPoly );
200 		}
201 	}
202 	return sal_True;
203 }
204 
205 // --------------------------------------------------------------------
206 
207 class PathDragObjOwn : public SdrDragObjOwn
208 {
209 private:
210 	basegfx::B2DPolyPolygon			maPathPolyPolygon;
211 
212 protected:
213     virtual void createSdrDragEntries();
214 
215 public:
PathDragObjOwn(SdrDragView & rNewView,const basegfx::B2DPolyPolygon & rPathPolyPolygon)216 	PathDragObjOwn(SdrDragView& rNewView,
217 		const basegfx::B2DPolyPolygon& rPathPolyPolygon)
218 	:	SdrDragObjOwn(rNewView),
219 		maPathPolyPolygon(rPathPolyPolygon)
220 	{}
221 
PathDragObjOwn(SdrDragView & rNewView)222 	PathDragObjOwn(SdrDragView& rNewView)
223 	:	SdrDragObjOwn(rNewView),
224 		maPathPolyPolygon()
225 	{}
226 
227 	virtual bool EndSdrDrag(bool bCopy);
228 };
229 
createSdrDragEntries()230 void PathDragObjOwn::createSdrDragEntries()
231 {
232 	// call parent
233 	SdrDragObjOwn::createSdrDragEntries();
234 
235 	if(maPathPolyPolygon.count())
236 	{
237 	    addSdrDragEntry(new SdrDragEntryPolyPolygon(maPathPolyPolygon));
238 	}
239 }
240 
EndSdrDrag(bool)241 bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
242 {
243 	Hide();
244 
245     SdrObject* pObj = GetDragObj();
246 
247     if(pObj)
248     {
249 		return pObj->applySpecialDrag(DragStat());
250     }
251 	else
252     {
253 		return false;
254     }
255 }
256 
257 // --------------------------------------------------------------------
258 
259 class SdPathHdl : public SmartHdl
260 {
261 public:
262 	SdPathHdl( const SmartTagReference& xTag, SdrPathObj* mpPathObj );
263 	virtual ~SdPathHdl();
264 	virtual void CreateB2dIAObject();
265 	virtual sal_Bool IsFocusHdl() const;
266 	virtual Pointer GetSdrDragPointer() const;
267 	virtual bool isMarkable() const;
268 
269 private:
270 	SdrPathObj* mpPathObj;
271 	rtl::Reference< MotionPathTag > mxTag;
272 };
273 
274 // --------------------------------------------------------------------
275 
SdPathHdl(const SmartTagReference & xTag,SdrPathObj * pPathObj)276 SdPathHdl::SdPathHdl( const SmartTagReference& xTag, SdrPathObj* pPathObj )
277 : SmartHdl( xTag, pPathObj->GetCurrentBoundRect().TopLeft() )
278 , mpPathObj( pPathObj )
279 , mxTag( dynamic_cast< MotionPathTag* >( xTag.get() ) )
280 {
281 }
282 
283 // --------------------------------------------------------------------
284 
~SdPathHdl()285 SdPathHdl::~SdPathHdl()
286 {
287 }
288 
289 // --------------------------------------------------------------------
290 
CreateB2dIAObject()291 void SdPathHdl::CreateB2dIAObject()
292 {
293 	// first throw away old one
294 	GetRidOfIAObject();
295 
296 	if(pHdlList)
297 	{
298 		SdrMarkView* pView = pHdlList->GetView();
299 
300 		if(pView && !pView->areMarkHandlesHidden())
301 		{
302 			SdrPageView* pPageView = pView->GetSdrPageView();
303 
304 			if(pPageView)
305 			{
306 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
307 				{
308 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
309 
310 					if(rPageWindow.GetPaintWindow().OutputToWindow())
311 					{
312 						if(rPageWindow.GetOverlayManager() && mpPathObj)
313 						{
314 							const sdr::contact::ViewContact& rVC = mpPathObj->GetViewContact();
315 							const drawinglayer::primitive2d::Primitive2DSequence aSequence = rVC.getViewIndependentPrimitive2DSequence();
316 							sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence);
317 
318 							rPageWindow.GetOverlayManager()->add(*pNew);
319 							maOverlayGroup.append(*pNew);
320 						}
321 					}
322 				}
323 			}
324 		}
325 	}
326 }
327 
328 // --------------------------------------------------------------------
329 
IsFocusHdl() const330 sal_Bool SdPathHdl::IsFocusHdl() const
331 {
332 	return sal_False;
333 }
334 
335 // --------------------------------------------------------------------
336 
isMarkable() const337 bool SdPathHdl::isMarkable() const
338 {
339 	return false;
340 }
341 
342 // --------------------------------------------------------------------
343 
GetSdrDragPointer() const344 Pointer SdPathHdl::GetSdrDragPointer() const
345 {
346 	PointerStyle eStyle = POINTER_NOTALLOWED;
347 	if( mxTag.is() )
348 	{
349 		if( mxTag->isSelected() )
350 		{
351 			if( !mxTag->getView().IsFrameDragSingles() && mxTag->getView().IsInsObjPointMode() )
352 				eStyle = POINTER_CROSS;
353 			else
354 				eStyle = POINTER_MOVE;
355 		}
356 		else
357 		{
358 			eStyle = POINTER_ARROW;
359 
360 		}
361 	}
362 	return Pointer( eStyle );
363 }
364 
365 // ====================================================================
366 
MotionPathTag(CustomAnimationPane & rPane,::sd::View & rView,const CustomAnimationEffectPtr & pEffect)367 MotionPathTag::MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect )
368 : SmartTag( rView )
369 , mrPane( rPane )
370 , mpEffect( pEffect )
371 , mxOrigin( pEffect->getTargetShape() )
372 , msLastPath( pEffect->getPath() )
373 , mbInUpdatePath( false )
374 {
375 	mpPathObj = mpEffect->createSdrPathObjFromPath();
376 	mxPolyPoly = mpPathObj->GetPathPoly();
377 	maOriginPos = mxOrigin->getPosition();
378 
379 	SdrPage* pPage = mrView.GetSdrPageView()->GetPage();
380 	if( pPage )
381 	{
382 		mpPathObj->SetPage( pPage );
383 		mpPathObj->SetObjList( pPage );
384 	}
385 
386 	XDash aDash( XDASH_RECT, 1, 80, 1, 80, 80);
387 	String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") );
388 	mpPathObj->SetMergedItem( XLineDashItem( aEmpty, aDash ) );
389 	mpPathObj->SetMergedItem( XLineStyleItem( XLINE_DASH ) );
390 	mpPathObj->SetMergedItem( XLineColorItem(aEmpty, ::Color(COL_GRAY)) );
391 	mpPathObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) );
392 
393 	::basegfx::B2DPolygon aStartArrow;
394 	aStartArrow.append(::basegfx::B2DPoint(20.0, 0.0));
395 	aStartArrow.append(::basegfx::B2DPoint(0.0,  0.0));
396 	aStartArrow.append(::basegfx::B2DPoint(10.0, 30.0));
397 	aStartArrow.setClosed(true);
398 	mpPathObj->SetMergedItem(XLineStartItem(aEmpty,::basegfx::B2DPolyPolygon(aStartArrow)));
399 	mpPathObj->SetMergedItem(XLineStartWidthItem(400));
400 	mpPathObj->SetMergedItem(XLineStartCenterItem(sal_True));
401 
402 	updatePathAttributes();
403 
404 	mpPathObj->SetMergedItem(XLineTransparenceItem(50));
405 
406 	mpMark = new SdrMark( mpPathObj, mrView.GetSdrPageView() );
407 
408 	mpPathObj->AddListener( *this );
409 
410 	Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY );
411 	if( xNotifier.is() )
412 	{
413 		Reference< XChangesListener > xListener( this );
414 		xNotifier->addChangesListener( this );
415 	}
416 }
417 
418 // --------------------------------------------------------------------
419 
~MotionPathTag()420 MotionPathTag::~MotionPathTag()
421 {
422 	DBG_ASSERT( mpPathObj == 0, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
423 	Dispose();
424 }
425 
426 // --------------------------------------------------------------------
427 
updatePathAttributes()428 void MotionPathTag::updatePathAttributes()
429 {
430 	String aEmpty( RTL_CONSTASCII_USTRINGPARAM("?") );
431 
432 	::basegfx::B2DPolygon aCandidate;
433 	if( mxPolyPoly.count() )
434 	{
435 		aCandidate = mxPolyPoly.getB2DPolygon(0);
436 		::basegfx::tools::checkClosed( aCandidate );
437 	}
438 
439 	if( !aCandidate.isClosed() )
440 	{
441 		::basegfx::B2DPolygon aEndArrow;
442 		aEndArrow.append(::basegfx::B2DPoint(10.0, 0.0));
443 		aEndArrow.append(::basegfx::B2DPoint(0.0, 30.0));
444 		aEndArrow.append(::basegfx::B2DPoint(20.0, 30.0));
445 		aEndArrow.setClosed(true);
446 		mpPathObj->SetMergedItem(XLineEndItem(aEmpty,::basegfx::B2DPolyPolygon(aEndArrow)));
447 		mpPathObj->SetMergedItem(XLineEndWidthItem(400));
448 		mpPathObj->SetMergedItem(XLineEndCenterItem(sal_True));
449 	}
450 	else
451 	{
452 		mpPathObj->SetMergedItem(XLineEndItem());
453 	}
454 }
455 
456 // --------------------------------------------------------------------
457 
Notify(SfxBroadcaster &,const SfxHint & rHint)458 void MotionPathTag::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
459 {
460 	if( mpPathObj && !mbInUpdatePath && dynamic_cast< const SdrHint* >( &rHint ) && (mpEffect.get() != 0) )
461 	{
462 		if( mxPolyPoly != mpPathObj->GetPathPoly() )
463 		{
464 			mbInUpdatePath = true;
465 			mxPolyPoly = mpPathObj->GetPathPoly();
466 			rtl::Reference< MotionPathTag > xTag( this );
467 			mrPane.updatePathFromMotionPathTag( xTag );
468 			msLastPath = mpEffect->getPath();
469 			updatePathAttributes();
470 			mbInUpdatePath = false;
471 		}
472 	}
473 }
474 
475 // --------------------------------------------------------------------
476 
MovePath(int nDX,int nDY)477 void MotionPathTag::MovePath( int nDX, int nDY )
478 {
479 	if( mpPathObj )
480 	{
481 		mpPathObj->Move( Size( nDX, nDY ) );
482 		mrView.updateHandles();
483 	}
484 }
485 
486 // --------------------------------------------------------------------
487 
488 /** returns true if the MotionPathTag handled the event. */
MouseButtonDown(const MouseEvent & rMEvt,SmartHdl & rHdl)489 bool MotionPathTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& rHdl )
490 {
491 	if( !mpPathObj )
492 		return false;
493 
494 	if( !isSelected() )
495 	{
496 		SmartTagReference xTag( this );
497 		mrView.getSmartTags().select( xTag );
498         selectionChanged();
499 		return true;
500 	}
501 	else
502 	{
503 		if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) )
504 		{
505 			mrView.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT, SFX_CALLMODE_ASYNCHRON);
506 			return true;
507 		}
508 		else if( rMEvt.IsLeft() )
509 		{
510 			OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow();
511 			Point aMDPos( pOut->PixelToLogic( rMEvt.GetPosPixel() ) );
512 
513 			if( !mrView.IsFrameDragSingles() && mrView.IsInsObjPointMode() && (rHdl.GetObjHdlNum() == SMART_TAG_HDL_NUM) )
514 			{
515 				// insert a point in edit mode
516 				const bool bNewObj = rMEvt.IsMod1();
517 
518 				mrView.BrkAction();
519 
520 				Point aPt(aMDPos); // - pMarkedPV->GetOffset());
521 
522 				if(bNewObj)
523 					aPt = mrView.GetSnapPos(aPt,mrView.GetSdrPageView());
524 
525 				sal_Bool bClosed0(mpPathObj->IsClosedObj());
526 
527 				sal_uInt32 nInsPointNum = mpPathObj->NbcInsPointOld(aPt, bNewObj, sal_True);
528 
529 				if(bClosed0 != mpPathObj->IsClosedObj())
530 				{
531 					// Obj was closed implicit
532 					// object changed
533 					mpPathObj->SetChanged();
534 					mpPathObj->BroadcastObjectChange();
535 				}
536 
537 				if(0xffffffff != nInsPointNum)
538 				{
539 					mrView.UnmarkAllPoints();
540 					mrView.updateHandles();
541 
542 					bool bRet = mrView.BegDragObj(aMDPos, pOut, mrView.GetHdl(nInsPointNum+1), 0, new PathDragObjOwn( mrView ) );
543 
544 					if (bRet)
545 					{
546 						const_cast< SdrDragStat* >( &mrView.GetDragStat() )->SetMinMoved();
547 						mrView.MovDragObj(aMDPos);
548 					}
549 				}
550 				return true;
551 			}
552 			else
553 			{
554 				SmartHdl* pHdl = &rHdl;
555 				if (!mrView.IsPointMarked(pHdl) || rMEvt.IsShift())
556 		        {
557 					if (!rMEvt.IsShift())
558 	                {
559 		                mrView.UnmarkAllPoints();
560 			            pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
561 				    }
562 					else
563 	                {
564 		                if (mrView.IsPointMarked(pHdl) )
565 			            {
566 				            mrView.UnmarkPoint(*pHdl);
567 					        pHdl = NULL;
568 	                    }
569 		                else
570 			            {
571 				            pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
572 					    }
573 					}
574 
575 		            if (pHdl)
576 				        mrView.MarkPoint(*pHdl);
577                 }
578 
579 
580 				if( pHdl && !rMEvt.IsRight() )
581 				{
582 					mrView.BrkAction();
583 					const sal_uInt16 nDrgLog = (sal_uInt16)pOut->PixelToLogic(Size(DRGPIX,0)).Width();
584 
585 					rtl::Reference< MotionPathTag > xTag( this );
586 					SdrDragMethod* pDragMethod;
587 
588 					// #i95646# add DragPoly as geometry to each local SdrDragMethod to be able
589 					// to create the needed local SdrDragEntry for it in createSdrDragEntries()
590 					const basegfx::B2DPolyPolygon aDragPoly(mpPathObj->GetPathPoly());
591 
592 					if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) )
593 					{
594 						pDragMethod = new PathDragMove( mrView, xTag, aDragPoly );
595 						pHdl->SetPos( aMDPos );
596 					}
597 					else if( pHdl->GetKind() == HDL_POLY )
598 					{
599 						pDragMethod = new PathDragObjOwn( mrView, aDragPoly );
600 					}
601 					else
602 					{
603 						pDragMethod = new PathDragResize( mrView, xTag, aDragPoly );
604 					}
605 
606 					mrView.BegDragObj(aMDPos, NULL, pHdl, nDrgLog, pDragMethod );
607 				}
608 				return true;
609 			}
610 		}
611 	}
612 
613 	return false;
614 }
615 
616 // --------------------------------------------------------------------
617 
618 /** returns true if the SmartTag consumes this event. */
KeyInput(const KeyEvent & rKEvt)619 bool MotionPathTag::KeyInput( const KeyEvent& rKEvt )
620 {
621 	if( !mpPathObj )
622 		return false;
623 
624 	sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
625 	switch( nCode )
626 	{
627 	case KEY_DELETE:
628 		return OnDelete();
629 
630 	case KEY_DOWN:
631 	case KEY_UP:
632 	case KEY_LEFT:
633 	case KEY_RIGHT:
634 		return OnMove( rKEvt );
635 
636 	case KEY_ESCAPE:
637 	{
638 		SmartTagReference xThis( this );
639 		mrView.getSmartTags().deselect();
640 		return true;
641 	}
642 
643 	case KEY_TAB:
644 		return OnTabHandles( rKEvt );
645 
646 	case KEY_SPACE:
647 		return OnMarkHandle( rKEvt );
648 
649 	default:
650 		break;
651 	}
652 	return false;
653 }
654 
OnDelete()655 bool MotionPathTag::OnDelete()
656 {
657 	mrPane.remove( mpEffect );
658 	return true;
659 }
660 
OnTabHandles(const KeyEvent & rKEvt)661 bool MotionPathTag::OnTabHandles( const KeyEvent& rKEvt )
662 {
663 	if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
664 	{
665 		const SdrHdlList& rHdlList = mrView.GetHdlList();
666 		sal_Bool bForward(!rKEvt.GetKeyCode().IsShift());
667 
668 		((SdrHdlList&)rHdlList).TravelFocusHdl(bForward);
669 
670 		// guarantee visibility of focused handle
671 		SdrHdl* pHdl = rHdlList.GetFocusHdl();
672 
673 		if(pHdl)
674 		{
675 			Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
676 			if( pWindow )
677 			{
678 				Point aHdlPosition(pHdl->GetPos());
679 				Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
680 				mrView.MakeVisible(aVisRect, *pWindow);
681 			}
682 		}
683 
684 		return true;
685 	}
686 
687 	return false;
688 }
689 
OnMarkHandle(const KeyEvent & rKEvt)690 bool MotionPathTag::OnMarkHandle( const KeyEvent& rKEvt )
691 {
692 	const SdrHdlList& rHdlList = mrView.GetHdlList();
693 	SdrHdl* pHdl = rHdlList.GetFocusHdl();
694 
695 	if(pHdl && pHdl->GetKind() == HDL_POLY )
696 	{
697 		// rescue ID of point with focus
698 		sal_uInt32 nPol(pHdl->GetPolyNum());
699 		sal_uInt32 nPnt(pHdl->GetPointNum());
700 
701 		if(mrView.IsPointMarked(pHdl))
702 		{
703 			if(rKEvt.GetKeyCode().IsShift())
704 			{
705 				mrView.UnmarkPoint(*pHdl);
706 			}
707 		}
708 		else
709 		{
710 			if(!rKEvt.GetKeyCode().IsShift())
711 			{
712 				mrView.UnmarkAllPoints();
713 			}
714 			mrView.MarkPoint(*pHdl);
715 		}
716 
717 		if(0L == rHdlList.GetFocusHdl())
718 		{
719 			// restore point with focus
720 			SdrHdl* pNewOne = 0L;
721 
722 			for(sal_uInt32 a(0); !pNewOne && a < rHdlList.GetHdlCount(); a++)
723 			{
724 				SdrHdl* pAct = rHdlList.GetHdl(a);
725 
726 				if(pAct && pAct->GetKind() == HDL_POLY && pAct->GetPolyNum() == nPol && pAct->GetPointNum() == nPnt)
727 					pNewOne = pAct;
728 			}
729 
730 			if(pNewOne)
731 				((SdrHdlList&)rHdlList).SetFocusHdl(pNewOne);
732 		}
733 	}
734 
735 	return true;
736 }
737 
OnMove(const KeyEvent & rKEvt)738 bool MotionPathTag::OnMove( const KeyEvent& rKEvt )
739 {
740 	long nX = 0;
741 	long nY = 0;
742 
743 	switch( rKEvt.GetKeyCode().GetCode() )
744 	{
745 	case KEY_UP:	nY = -1; break;
746 	case KEY_DOWN:	nY =  1; break;
747 	case KEY_LEFT:	nX = -1; break;
748 	case KEY_RIGHT:	nX =  1; break;
749 	default: break;
750 	}
751 
752 	if(rKEvt.GetKeyCode().IsMod2())
753 	{
754 		OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow();
755 		Size aLogicSizeOnePixel = (pOut) ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100);
756 		nX *= aLogicSizeOnePixel.Width();
757 		nY *= aLogicSizeOnePixel.Height();
758 	}
759 	else
760 	{
761 		// old, fixed move distance
762 		nX *= 100;
763 		nY *= 100;
764 	}
765 
766 	if( nX || nY )
767 	{
768 		// in point edit mode move the handle with the focus
769 		const SdrHdlList& rHdlList = mrView.GetHdlList();
770 		SdrHdl* pHdl = rHdlList.GetFocusHdl();
771 
772 		if(pHdl)
773 		{
774 			// now move the Handle (nX, nY)
775 			Point aStartPoint(pHdl->GetPos());
776 			Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
777 
778 			// start dragging
779 			rtl::Reference< MotionPathTag > xTag( this );
780 			SdrDragMethod* pDragMethod = 0;
781 			if( (pHdl->GetKind() == HDL_MOVE) || (pHdl->GetKind() == HDL_SMARTTAG) )
782 			{
783 				pDragMethod = new PathDragMove( mrView, xTag );
784 			}
785 			else if( pHdl->GetKind() == HDL_POLY )
786 			{
787 				pDragMethod = new PathDragObjOwn( mrView );
788 			}
789 			else if( pHdl->GetKind() != HDL_BWGT )
790 			{
791 				pDragMethod = new PathDragResize( mrView, xTag );
792 			}
793 			mrView.BegDragObj(aStartPoint, 0, pHdl, 0, pDragMethod);
794 
795 			if(mrView.IsDragObj())
796 			{
797 				FASTBOOL bWasNoSnap = mrView.GetDragStat().IsNoSnap();
798 				sal_Bool bWasSnapEnabled = mrView.IsSnapEnabled();
799 
800 				// switch snapping off
801 				if(!bWasNoSnap)
802 					((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(sal_True);
803 				if(bWasSnapEnabled)
804 					mrView.SetSnapEnabled(sal_False);
805 
806 				mrView.MovAction(aEndPoint);
807 				mrView.EndDragObj();
808 
809 				// restore snap
810 				if(!bWasNoSnap)
811 					((SdrDragStat&)mrView.GetDragStat()).SetNoSnap(bWasNoSnap);
812 				if(bWasSnapEnabled)
813 					mrView.SetSnapEnabled(bWasSnapEnabled);
814 			}
815 		}
816 		else
817 		{
818 			// move the path
819 			MovePath( nX, nY );
820 		}
821 	}
822 
823 	return true;
824 }
825 
826 // --------------------------------------------------------------------
827 
GetMarkablePointCount() const828 sal_uLong MotionPathTag::GetMarkablePointCount() const
829 {
830 	if( mpPathObj && isSelected() )
831 	{
832 		return mpPathObj->GetPointCount();
833 	}
834 	else
835 	{
836 		return 0;
837 	}
838 }
839 
840 // --------------------------------------------------------------------
841 
GetMarkedPointCount() const842 sal_uLong MotionPathTag::GetMarkedPointCount() const
843 {
844 	if( mpMark )
845 	{
846 		const SdrUShortCont* pPts=mpMark->GetMarkedPoints();
847 		return pPts ? pPts->GetCount() : 0;
848 	}
849 	else
850 	{
851 		return 0;
852 	}
853 }
854 
855 // --------------------------------------------------------------------
856 
MarkPoint(SdrHdl & rHdl,sal_Bool bUnmark)857 sal_Bool MotionPathTag::MarkPoint(SdrHdl& rHdl, sal_Bool bUnmark )
858 {
859 	sal_Bool bRet=sal_False;
860 	if( mpPathObj && mrView.IsPointMarkable( rHdl ) && (rHdl.GetKind() != HDL_SMARTTAG) )
861 	{
862 		SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( &rHdl );
863 		if( pSmartHdl && pSmartHdl->getTag().get() == this )
864 		{
865 			SdrUShortCont* pPts=mpMark->ForceMarkedPoints();
866 			pPts->ForceSort();
867 			if (mrView.MarkPointHelper(&rHdl,mpMark,bUnmark))
868 			{
869 				pPts->ForceSort();
870 				mrView.MarkListHasChanged();
871 				bRet=sal_True;
872 			}
873 		}
874 	}
875 	return bRet;
876 }
877 
878 // --------------------------------------------------------------------
879 
MarkPoints(const Rectangle * pRect,sal_Bool bUnmark)880 sal_Bool MotionPathTag::MarkPoints(const Rectangle* pRect, sal_Bool bUnmark )
881 {
882 	sal_Bool bChgd=sal_False;
883 
884 	if( mpPathObj && isSelected() )
885 	{
886 		sal_Int32 nHdlNum = mrView.GetHdlList().GetHdlCount() - 1;
887 		while( nHdlNum > 0 )
888 		{
889 			SmartHdl* pHdl = dynamic_cast< SmartHdl* >( mrView.GetHdl( sal::static_int_cast< sal_uLong >( nHdlNum-- ) ) );
890 
891 			if( pHdl && (pHdl->getTag().get() == this) && mrView.IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark)
892 			{
893 				Point aPos(pHdl->GetPos());
894 				if( pRect==NULL || pRect->IsInside(aPos))
895 				{
896 					if( mrView.MarkPointHelper(pHdl,mpMark,bUnmark) )
897 						bChgd=sal_True;
898 				}
899 			}
900 		}
901 
902 		if(bChgd)
903 			mrView.MarkListHasChanged();
904 	}
905 
906 	return bChgd;
907 }
908 
909 // --------------------------------------------------------------------
910 
getContext(SdrViewContext & rContext)911 bool MotionPathTag::getContext( SdrViewContext& rContext )
912 {
913 	if( mpPathObj && isSelected() && !mrView.IsFrameDragSingles() )
914 	{
915 		rContext = SDRCONTEXT_POINTEDIT;
916 		return true;
917 	}
918 	else
919 	{
920 		return false;
921 	}
922 }
923 
924 // --------------------------------------------------------------------
925 
CheckPossibilities()926 void MotionPathTag::CheckPossibilities()
927 {
928 	if( mpPathObj )
929 	{
930 		if( isSelected() )
931 		{
932 			mrView.SetMoveAllowed( true );
933 			mrView.SetMoveProtected( false );
934 			mrView.SetResizeFreeAllowed( true );
935 			mrView.SetResizePropAllowed( true );
936 			mrView.SetResizeProtected( false );
937 
938             if( !mrView.IsFrameDragSingles() )
939 			{
940 				bool b1stSmooth(true);
941 				bool b1stSegm(true);
942 				bool bCurve(false);
943 				bool bSmoothFuz(false);
944 				bool bSegmFuz(false);
945 				basegfx::B2VectorContinuity eSmooth = basegfx::CONTINUITY_NONE;
946 
947 				mrView.CheckPolyPossibilitiesHelper( mpMark, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth );
948 			}
949 		}
950 	}
951 }
952 
953 // --------------------------------------------------------------------
954 
addCustomHandles(SdrHdlList & rHandlerList)955 void MotionPathTag::addCustomHandles( SdrHdlList& rHandlerList )
956 {
957 	if( mpPathObj )
958 	{
959 		::com::sun::star::awt::Point aPos( mxOrigin->getPosition() );
960 		if( (aPos.X != maOriginPos.X) || (aPos.Y != maOriginPos.Y) )
961 		{
962             const basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
963                 aPos.X - maOriginPos.X, aPos.Y - maOriginPos.Y));
964 			mxPolyPoly.transform( aTransform );
965 			mpPathObj->SetPathPoly( mxPolyPoly );
966 			maOriginPos = aPos;
967 		}
968 
969 		SmartTagReference xThis( this );
970 		SdPathHdl* pHdl = new SdPathHdl( xThis, mpPathObj );
971 		pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM );
972 		pHdl->SetPageView( mrView.GetSdrPageView() );
973 
974 
975 		pHdl->SetObj(mpPathObj);
976 		rHandlerList.AddHdl( pHdl );
977 
978 		if( isSelected() )
979 		{
980 			mrView.GetSdrPageView()->SetHasMarkedObj(sal_True);
981 
982 			if( !mrView.IsFrameDragSingles() )
983 			{
984 				SdrHdlList aTemp( rHandlerList.GetView() );
985 				mpPathObj->AddToHdlList( aTemp );
986 				const SdrUShortCont* pMrkPnts=mpMark->GetMarkedPoints();
987 
988 				sal_uInt32 nHandle;
989 				for( nHandle = 0; nHandle < aTemp.GetHdlCount(); ++nHandle )
990 				{
991 					SdrHdl* pTempHdl = aTemp.GetHdl( nHandle );
992 
993 					SmartHdl* pSmartHdl = new SmartHdl( xThis, mpPathObj, pTempHdl->GetPos(), pTempHdl->GetKind() );
994 					pSmartHdl->SetObjHdlNum( nHandle );
995 					pSmartHdl->SetPolyNum( pTempHdl->GetPolyNum() );
996 					pSmartHdl->SetPointNum( pTempHdl->GetPointNum() );
997 					pSmartHdl->SetPlusHdl(  pTempHdl->IsPlusHdl() );
998 					pSmartHdl->SetSourceHdlNum( pTempHdl->GetSourceHdlNum() );
999 					pSmartHdl->SetPageView( mrView.GetSdrPageView() );
1000 
1001 					rHandlerList.AddHdl( pSmartHdl );
1002 
1003 					const bool bSelected= pMrkPnts && pMrkPnts->Exist(sal::static_int_cast< sal_uInt16 >(nHandle));
1004 					pSmartHdl->SetSelected(bSelected);
1005 
1006 					if( mrView.IsPlusHandlesAlwaysVisible() || bSelected )
1007 					{
1008 						sal_uInt32 nPlusAnz=mpPathObj->GetPlusHdlCount(*pSmartHdl);
1009 						for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
1010 						{
1011 							SdrHdl* pPlusHdl = mpPathObj->GetPlusHdl(*pSmartHdl,nPlusNum);
1012 							if (pPlusHdl!=NULL)
1013 							{
1014 								pPlusHdl->SetObj(mpPathObj);
1015 								pPlusHdl->SetPageView(mrView.GetSdrPageView());
1016 								pPlusHdl->SetPlusHdl(sal_True);
1017 								rHandlerList.AddHdl(pPlusHdl);
1018 							}
1019 						}
1020 					}
1021 				}
1022 			}
1023 			else
1024 			{
1025 				Rectangle aRect(mpPathObj->GetCurrentBoundRect());
1026 
1027 				if(!aRect.IsEmpty())
1028 				{
1029 					sal_uLong nCount = rHandlerList.GetHdlCount();
1030 
1031 					sal_Bool bWdt0=aRect.Left()==aRect.Right();
1032 					sal_Bool bHgt0=aRect.Top()==aRect.Bottom();
1033 					if (bWdt0 && bHgt0)
1034 					{
1035 						rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft(),HDL_UPLFT));
1036 					}
1037 					else if (bWdt0 || bHgt0)
1038 					{
1039 						rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft()    ,HDL_UPLFT));
1040 						rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight(),HDL_LWRGT));
1041 					}
1042 					else
1043 					{
1044 						if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopLeft()     ,HDL_UPLFT));
1045 						if (          !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopCenter()   ,HDL_UPPER));
1046 						if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.TopRight()    ,HDL_UPRGT));
1047 						if (!bWdt0          ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.LeftCenter()  ,HDL_LEFT ));
1048 						if (!bWdt0          ) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.RightCenter() ,HDL_RIGHT));
1049 						if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomLeft()  ,HDL_LWLFT));
1050 						if (          !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomCenter(),HDL_LOWER));
1051 						if (!bWdt0 && !bHgt0) rHandlerList.AddHdl(new SmartHdl( xThis, mpPathObj, aRect.BottomRight() ,HDL_LWRGT));
1052 					}
1053 
1054 					while( nCount < rHandlerList.GetHdlCount() )
1055 					{
1056 						rHandlerList.GetHdl(nCount++)->SetPageView( mrView.GetSdrPageView() );
1057 					}
1058 				}
1059 			}
1060 		}
1061 	}
1062 }
1063 
1064 // --------------------------------------------------------------------
1065 
disposing()1066 void MotionPathTag::disposing()
1067 {
1068 	Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY );
1069 	if( xNotifier.is() )
1070 	{
1071 		Reference< XChangesListener > xListener( this );
1072 		xNotifier->removeChangesListener( this );
1073 	}
1074 
1075 	if( mpPathObj )
1076 	{
1077 		SdrPathObj* pPathObj = mpPathObj;
1078 		mpPathObj = 0;
1079 		mrView.updateHandles();
1080 		delete pPathObj;
1081 	}
1082 
1083 	if( mpMark )
1084 	{
1085 		delete mpMark;
1086 		mpMark = 0;
1087 	}
1088 
1089 	SmartTag::disposing();
1090 }
1091 
1092 // --------------------------------------------------------------------
1093 
deselect()1094 void MotionPathTag::deselect()
1095 {
1096 	SmartTag::deselect();
1097 
1098 	if( mpMark )
1099 	{
1100 		SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1101 
1102 		if( pPts )
1103 			pPts->Clear();
1104 	}
1105 
1106     selectionChanged();
1107 }
1108 
selectionChanged()1109 void MotionPathTag::selectionChanged()
1110 {
1111     if( mrView.GetViewShell() && mrView.GetViewShell()->GetViewFrame() )
1112     {
1113         SfxBindings& rBindings = mrView.GetViewShell()->GetViewFrame()->GetBindings();
1114         rBindings.InvalidateAll(sal_True);
1115     }
1116 }
1117 // --------------------------------------------------------------------
1118 // IPolyPolygonEditorController
1119 // --------------------------------------------------------------------
1120 
DeleteMarkedPoints()1121 void MotionPathTag::DeleteMarkedPoints()
1122 {
1123 	if( mpPathObj && IsDeleteMarkedPointsPossible() )
1124 	{
1125 		mrView.BrkAction();
1126 
1127 		// Description
1128 //		BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE);
1129 
1130 		SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1131 
1132 		if( pPts )
1133 		{
1134 			PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() );
1135 			if( aEditor.DeletePoints( pPts->getContainer() ) )
1136 			{
1137 				if( aEditor.GetPolyPolygon().count() )
1138 				{
1139 //					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath ));
1140 					mpPathObj->SetPathPoly( aEditor.GetPolyPolygon() );
1141 				}
1142 				else
1143 				{
1144 //					AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) );
1145 //					pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum());
1146 				}
1147 
1148 				mrView.UnmarkAllPoints();
1149 				mrView.MarkListHasChanged();
1150 				mrView.updateHandles();
1151 			}
1152 		}
1153 
1154 //		EndUndo();
1155 	}
1156 }
1157 
IsDeleteMarkedPointsPossible() const1158 sal_Bool MotionPathTag::IsDeleteMarkedPointsPossible() const
1159 {
1160 	return mpPathObj && isSelected() && (GetMarkedPointCount() != 0);
1161 }
1162 
RipUpAtMarkedPoints()1163 void MotionPathTag::RipUpAtMarkedPoints()
1164 {
1165 	// not supported for motion path
1166 }
1167 
IsRipUpAtMarkedPointsPossible() const1168 bool MotionPathTag::IsRipUpAtMarkedPointsPossible() const
1169 {
1170 	// not supported for motion path
1171 	return false;
1172 }
1173 
IsSetMarkedSegmentsKindPossible() const1174 sal_Bool MotionPathTag::IsSetMarkedSegmentsKindPossible() const
1175 {
1176 	if( mpPathObj )
1177 		return mrView.IsSetMarkedSegmentsKindPossible();
1178 	else
1179 		return sal_False;
1180 }
1181 
GetMarkedSegmentsKind() const1182 SdrPathSegmentKind MotionPathTag::GetMarkedSegmentsKind() const
1183 {
1184 	if( mpPathObj )
1185 		return mrView.GetMarkedSegmentsKind();
1186 	else
1187 		return SDRPATHSEGMENT_LINE;
1188 }
1189 
SetMarkedSegmentsKind(SdrPathSegmentKind eKind)1190 void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind)
1191 {
1192 	if(mpPathObj && isSelected() && (GetMarkedPointCount() != 0))
1193 	{
1194 		SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1195 		if(pPts)
1196 		{
1197 			PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() );
1198 			if(aEditor.SetSegmentsKind( eKind, pPts->getContainer()) )
1199 			{
1200 //				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
1201 				mpPathObj->SetPathPoly(aEditor.GetPolyPolygon());
1202 				mrView.MarkListHasChanged();
1203 				mrView.updateHandles();
1204 			}
1205 		}
1206 	}
1207 }
1208 
IsSetMarkedPointsSmoothPossible() const1209 sal_Bool MotionPathTag::IsSetMarkedPointsSmoothPossible() const
1210 {
1211 	if( mpPathObj )
1212 		return mrView.IsSetMarkedPointsSmoothPossible();
1213 	else
1214 		return sal_False;
1215 }
1216 
GetMarkedPointsSmooth() const1217 SdrPathSmoothKind MotionPathTag::GetMarkedPointsSmooth() const
1218 {
1219 	if( mpPathObj )
1220 		return mrView.GetMarkedPointsSmooth();
1221 	else
1222 		return SDRPATHSMOOTH_ANGULAR;
1223 }
1224 
SetMarkedPointsSmooth(SdrPathSmoothKind eKind)1225 void MotionPathTag::SetMarkedPointsSmooth(SdrPathSmoothKind eKind)
1226 {
1227 	basegfx::B2VectorContinuity eFlags;
1228 
1229 	if(SDRPATHSMOOTH_ANGULAR == eKind)
1230 	{
1231 		eFlags = basegfx::CONTINUITY_NONE;
1232 	}
1233 	else if(SDRPATHSMOOTH_ASYMMETRIC == eKind)
1234 	{
1235 		eFlags = basegfx::CONTINUITY_C1;
1236 	}
1237 	else if(SDRPATHSMOOTH_SYMMETRIC == eKind)
1238 	{
1239 		eFlags = basegfx::CONTINUITY_C2;
1240 	}
1241 	else
1242 	{
1243 		return;
1244 	}
1245 
1246 	if(mpPathObj && mpMark && isSelected() && (GetMarkedPointCount() != 0))
1247 	{
1248 		SdrUShortCont* pPts = mpMark->GetMarkedPoints();
1249 		if(pPts)
1250 		{
1251 			PolyPolygonEditor aEditor( mpPathObj->GetPathPoly(), mpPathObj->IsClosed() );
1252 			if(aEditor.SetPointsSmooth( eFlags, pPts->getContainer() ) )
1253 			{
1254 //				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath));
1255 				mpPathObj->SetPathPoly(aEditor.GetPolyPolygon());
1256 				mrView.MarkListHasChanged();
1257 				mrView.updateHandles();
1258 			}
1259 		}
1260 	}
1261 }
1262 
CloseMarkedObjects(sal_Bool,sal_Bool)1263 void MotionPathTag::CloseMarkedObjects(sal_Bool /*bToggle*/, sal_Bool /*bOpen*/ )
1264 {
1265 	// not supported for motion path
1266 }
1267 
IsOpenCloseMarkedObjectsPossible() const1268 bool MotionPathTag::IsOpenCloseMarkedObjectsPossible() const
1269 {
1270 	// not supported for motion path
1271 	return false;
1272 }
1273 
GetMarkedObjectsClosedState() const1274 SdrObjClosedKind MotionPathTag::GetMarkedObjectsClosedState() const
1275 {
1276 	// not supported for motion path
1277 	return SDROBJCLOSED_OPEN;
1278 }
1279 
1280 // XChangesListener
changesOccurred(const ChangesEvent &)1281 void SAL_CALL MotionPathTag::changesOccurred( const ChangesEvent& /*Event*/ ) throw (RuntimeException)
1282 {
1283 	if( mpPathObj && !mbInUpdatePath && (mpEffect->getPath() != msLastPath) )
1284 	{
1285 		mbInUpdatePath =true;
1286 		msLastPath = mpEffect->getPath();
1287 		mpEffect->updateSdrPathObjFromPath( *mpPathObj );
1288 		mbInUpdatePath = false;
1289 		updatePathAttributes();
1290 		mrView.updateHandles();
1291 	}
1292 }
1293 
disposing(const EventObject &)1294 void SAL_CALL MotionPathTag::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
1295 {
1296 	if( mpPathObj )
1297 		Dispose();
1298 }
1299 
queryInterface(const::com::sun::star::uno::Type & aType)1300 Any SAL_CALL MotionPathTag::queryInterface( const ::com::sun::star::uno::Type& aType ) throw (RuntimeException)
1301 {
1302 	if( aType == XChangesListener::static_type() )
1303 		return Any( Reference< XChangesListener >( this ) );
1304 	if( aType == XEventListener::static_type() )
1305 		return Any( Reference< XEventListener >( this ) );
1306 	if( aType == XInterface::static_type() )
1307 		return Any( Reference< XInterface >( this ) );
1308 
1309 	return Any();
1310 }
1311 
acquire()1312 void SAL_CALL MotionPathTag::acquire() throw ()
1313 {
1314 	SimpleReferenceComponent::acquire();
1315 }
1316 
release()1317 void SAL_CALL MotionPathTag::release(  ) throw ()
1318 {
1319 	SimpleReferenceComponent::release();
1320 }
1321 
1322 } // end of namespace sd
1323 
1324