LibreOffice Module sd (master) 1
motionpathtag.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <com/sun/star/util/XChangesNotifier.hpp>
21
25
26#include <sfx2/viewfrm.hxx>
27#include <sfx2/dispatch.hxx>
28
29#include <svx/svdpagv.hxx>
30#include <svx/sdrpagewindow.hxx>
32#include <svx/svdopath.hxx>
33#include <svx/xfillit0.hxx>
34#include <svx/xlineit0.hxx>
35#include <svx/xlndsit.hxx>
36#include <svx/xlnclit.hxx>
37#include <svx/xlnstit.hxx>
38#include <svx/xlnedit.hxx>
39#include <svx/xlnstwit.hxx>
40#include <svx/xlnedwit.hxx>
41#include <svx/xlnstcit.hxx>
42#include <svx/xlnedcit.hxx>
43#include <svx/xlntrit.hxx>
44#include <svx/svxids.hrc>
46#include <svx/svddrgmt.hxx>
47
49#include <View.hxx>
50#include "motionpathtag.hxx"
51#include <ViewShell.hxx>
52#include <Window.hxx>
53
56#include <utility>
57
59using namespace ::com::sun::star;
60using namespace ::com::sun::star::uno;
61using namespace ::com::sun::star::lang;
62using namespace ::com::sun::star::util;
63using namespace ::com::sun::star::drawing;
64
65namespace sd
66{
67
69const int DRGPIX = 2; // Drag MinMove in Pixel
70
71namespace {
72
73class PathDragMove : public SdrDragMove
74{
75private:
76 basegfx::B2DPolyPolygon maPathPolyPolygon;
77
78protected:
79 virtual void createSdrDragEntries() override;
80
81public:
82 PathDragMove(SdrDragView& rNewView,
84 basegfx::B2DPolyPolygon aPathPolyPolygon)
85 : SdrDragMove(rNewView),
86 maPathPolyPolygon(std::move(aPathPolyPolygon)),
87 mxTag(std::move( xTag ))
88 {}
89
90 PathDragMove(SdrDragView& rNewView,
92 : SdrDragMove(rNewView),
93 mxTag(std::move( xTag ))
94 {}
95
96 virtual bool BeginSdrDrag() override;
97 virtual bool EndSdrDrag(bool bCopy) override;
98
100};
101
102}
103
104void PathDragMove::createSdrDragEntries()
105{
106 // call parent
108
109 if(maPathPolyPolygon.count())
110 {
111 addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntryPolyPolygon(maPathPolyPolygon)));
112 }
113}
114
115bool PathDragMove::BeginSdrDrag()
116{
117 if( mxTag.is() )
118 {
119 SdrPathObj* pPathObj = mxTag->getPathObj();
120 if( pPathObj )
121 {
122 DragStat().SetActionRect(pPathObj->GetCurrentBoundRect());
123 }
124 }
125 Show();
126 return true;
127}
128
129bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
130{
131 Hide();
132 if( mxTag.is() )
133 mxTag->MovePath( DragStat().GetDX(), DragStat().GetDY() );
134 return true;
135}
136
137namespace {
138
139class PathDragResize : public SdrDragResize
140{
141private:
142 basegfx::B2DPolyPolygon maPathPolyPolygon;
143
144protected:
145 virtual void createSdrDragEntries() override;
146
147public:
148 PathDragResize(SdrDragView& rNewView,
150 basegfx::B2DPolyPolygon aPathPolyPolygon)
151 : SdrDragResize(rNewView),
152 maPathPolyPolygon(std::move(aPathPolyPolygon)),
153 mxTag(std::move( xTag ))
154 {}
155
156 PathDragResize(SdrDragView& rNewView,
158 : SdrDragResize(rNewView),
159 mxTag(std::move( xTag ))
160 {}
161
162 virtual bool EndSdrDrag(bool bCopy) override;
164};
165
166}
167
168void PathDragResize::createSdrDragEntries()
169{
170 // call parent
172
173 if(maPathPolyPolygon.count())
174 {
175 addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntryPolyPolygon(maPathPolyPolygon)));
176 }
177}
178
179bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
180{
181 Hide();
182 if( mxTag.is() )
183 {
184 SdrPathObj* pPathObj = mxTag->getPathObj();
185 if( pPathObj )
186 {
187 const Point aRef( DragStat().GetRef1() );
189 aTrans.scale(double(aXFact), double(aYFact));
190 aTrans.translate(aRef.X(), aRef.Y());
191 basegfx::B2DPolyPolygon aDragPoly(pPathObj->GetPathPoly());
192 aDragPoly.transform(aTrans);
193 pPathObj->SetPathPoly( aDragPoly );
194 }
195 }
196 return true;
197}
198
199namespace {
200
201class PathDragObjOwn : public SdrDragObjOwn
202{
203private:
204 basegfx::B2DPolyPolygon maPathPolyPolygon;
205
206protected:
207 virtual void createSdrDragEntries() override;
208
209public:
210 PathDragObjOwn(SdrDragView& rNewView,
211 basegfx::B2DPolyPolygon aPathPolyPolygon)
212 : SdrDragObjOwn(rNewView),
213 maPathPolyPolygon(std::move(aPathPolyPolygon))
214 {}
215
216 explicit PathDragObjOwn(SdrDragView& rNewView)
217 : SdrDragObjOwn(rNewView)
218 {}
219
220 virtual bool EndSdrDrag(bool bCopy) override;
221};
222
223}
224
225void PathDragObjOwn::createSdrDragEntries()
226{
227 // call parent
229
230 if(maPathPolyPolygon.count())
231 {
232 addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntryPolyPolygon(maPathPolyPolygon)));
233 }
234}
235
236bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
237{
238 Hide();
239
240 SdrObject* pObj = GetDragObj();
241
242 if(pObj && pObj->applySpecialDrag(DragStat()))
243 {
244 pObj->SetChanged();
245 pObj->BroadcastObjectChange();
246 return true;
247 }
248 else
249 {
250 return false;
251 }
252}
253
254namespace {
255
256class SdPathHdl : public SmartHdl
257{
258public:
259 SdPathHdl( const SmartTagReference& xTag, SdrPathObj* mpPathObj );
260
261 virtual void CreateB2dIAObject() override;
262 virtual bool IsFocusHdl() const override;
263
264private:
265 SdrPathObj* mpPathObj;
266};
267
268}
269
270SdPathHdl::SdPathHdl( const SmartTagReference& xTag, SdrPathObj* pPathObj )
271: SmartHdl( xTag, pPathObj->GetCurrentBoundRect().TopLeft(), SdrHdlKind::SmartTag )
272, mpPathObj( pPathObj )
273{
274}
275
276void SdPathHdl::CreateB2dIAObject()
277{
278 // first throw away old one
279 GetRidOfIAObject();
280
281 if(!pHdlList)
282 return;
283
284 SdrMarkView* pView = pHdlList->GetView();
285
286 if(!pView || pView->areMarkHandlesHidden())
287 return;
288
289 SdrPageView* pPageView = pView->GetSdrPageView();
290
291 if(!pPageView)
292 return;
293
294 for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
295 {
296 const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
297
298 if(rPageWindow.GetPaintWindow().OutputToWindow())
299 {
301 if (xManager.is() && mpPathObj)
302 {
303 const sdr::contact::ViewContact& rVC = mpPathObj->GetViewContact();
306 std::unique_ptr<sdr::overlay::OverlayObject> pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(std::move(aSequence)));
307
308 // OVERLAYMANAGER
309 insertNewlyCreatedOverlayObjectForSdrHdl(
310 std::move(pNew),
311 rPageWindow.GetObjectContact(),
312 *xManager);
313 }
314 }
315 }
316}
317
318bool SdPathHdl::IsFocusHdl() const
319{
320 return false;
321}
322
323MotionPathTag::MotionPathTag( CustomAnimationPane& rPane, ::sd::View& rView, const CustomAnimationEffectPtr& pEffect )
324: SmartTag( rView )
325, mrPane( rPane )
326, mpEffect( pEffect )
327, mxOrigin( pEffect->getTargetShape() )
328, msLastPath( pEffect->getPath() )
329, mbInUpdatePath( false )
330{
331 mpPathObj = mpEffect->createSdrPathObjFromPath(rView.getSdrModelFromSdrView());
332 mxPolyPoly = mpPathObj->GetPathPoly();
333 if (mxOrigin.is())
334 maOriginPos = mxOrigin->getPosition();
335
336 XDash aDash( css::drawing::DashStyle_RECT, 1, 80, 1, 80, 80);
337 OUString aEmpty( "?" );
338 mpPathObj->SetMergedItem( XLineDashItem( aEmpty, aDash ) );
339 mpPathObj->SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH ) );
340 mpPathObj->SetMergedItem( XLineColorItem(aEmpty, COL_GRAY) );
341 mpPathObj->SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE ) );
342
343 ::basegfx::B2DPolygon aStartArrow;
344 aStartArrow.append(::basegfx::B2DPoint(20.0, 0.0));
345 aStartArrow.append(::basegfx::B2DPoint(0.0, 0.0));
346 aStartArrow.append(::basegfx::B2DPoint(10.0, 30.0));
347 aStartArrow.setClosed(true);
348 mpPathObj->SetMergedItem(XLineStartItem(aEmpty,::basegfx::B2DPolyPolygon(aStartArrow)));
349 mpPathObj->SetMergedItem(XLineStartWidthItem(400));
350 mpPathObj->SetMergedItem(XLineStartCenterItem(true));
351
353
354 mpPathObj->SetMergedItem(XLineTransparenceItem(50));
355
356 mpMark.reset(new SdrMark( mpPathObj.get(), mrView.GetSdrPageView() ));
357
358 mpPathObj->AddListener( *this );
359
360 Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY );
361 if( xNotifier.is() )
362 {
363 xNotifier->addChangesListener( this );
364 }
365}
366
368{
369 DBG_ASSERT( mpPathObj == nullptr, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
370 Dispose();
371}
372
374{
375 ::basegfx::B2DPolygon aCandidate;
376 if( mxPolyPoly.count() )
377 {
378 aCandidate = mxPolyPoly.getB2DPolygon(0);
379 ::basegfx::utils::checkClosed( aCandidate );
380 }
381
382 if( !aCandidate.isClosed() )
383 {
384 ::basegfx::B2DPolygon aEndArrow;
385 aEndArrow.append(::basegfx::B2DPoint(10.0, 0.0));
386 aEndArrow.append(::basegfx::B2DPoint(0.0, 30.0));
387 aEndArrow.append(::basegfx::B2DPoint(20.0, 30.0));
388 aEndArrow.setClosed(true);
389 mpPathObj->SetMergedItem(XLineEndItem("?",::basegfx::B2DPolyPolygon(aEndArrow)));
390 mpPathObj->SetMergedItem(XLineEndWidthItem(400));
391 mpPathObj->SetMergedItem(XLineEndCenterItem(true));
392 }
393 else
394 {
395 mpPathObj->SetMergedItem(XLineEndItem());
396 }
397}
398
399void MotionPathTag::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
400{
401 if( !(mpPathObj && !mbInUpdatePath && rHint.GetId() == SfxHintId::ThisIsAnSdrHint && mpEffect) )
402 return;
403
404 if( mxPolyPoly != mpPathObj->GetPathPoly() )
405 {
406 mbInUpdatePath = true;
407 mxPolyPoly = mpPathObj->GetPathPoly();
410 msLastPath = mpEffect->getPath();
412 mbInUpdatePath = false;
413 }
414}
415
416void MotionPathTag::MovePath( int nDX, int nDY )
417{
418 if( mpPathObj )
419 {
420 mpPathObj->Move( Size( nDX, nDY ) );
422 }
423}
424
427{
428 if( !mpPathObj )
429 return false;
430
431 if( !isSelected() )
432 {
433 SmartTagReference xTag( this );
434 mrView.getSmartTags().select( xTag );
436 return true;
437 }
438 else
439 {
440 if( rMEvt.IsLeft() && (rMEvt.GetClicks() == 2) )
441 {
442 mrView.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT, SfxCallMode::ASYNCHRON);
443 return true;
444 }
445 else if( rMEvt.IsLeft() )
446 {
448 Point aMDPos( pOut->PixelToLogic( rMEvt.GetPosPixel() ) );
449
451 {
452 // insert a point in edit mode
453 const bool bNewObj = rMEvt.IsMod1();
454
456
457 Point aPt(aMDPos); // - pMarkedPV->GetOffset());
458
459 if(bNewObj)
461
462 bool bClosed0(mpPathObj->IsClosedObj());
463
464 sal_uInt32 nInsPointNum = mpPathObj->NbcInsPointOld(aPt, bNewObj);
465
466 if(bClosed0 != mpPathObj->IsClosedObj())
467 {
468 // Obj was closed implicit
469 // object changed
470 mpPathObj->SetChanged();
471 mpPathObj->BroadcastObjectChange();
472 }
473
474 if(0xffffffff != nInsPointNum)
475 {
478
479 bool bRet = mrView.BegDragObj(aMDPos, pOut, mrView.GetHdl(nInsPointNum+1), 0, new PathDragObjOwn( mrView ) );
480
481 if (bRet)
482 {
483 const_cast< SdrDragStat* >( &mrView.GetDragStat() )->SetMinMoved();
484 mrView.MovDragObj(aMDPos);
485 }
486 }
487 return true;
488 }
489 else
490 {
491 SmartHdl* pHdl = &rHdl;
492 if (!mrView.IsPointMarked(*pHdl) || rMEvt.IsShift())
493 {
494 if (!rMEvt.IsShift())
495 {
497 pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
498 }
499 else
500 {
501 if (mrView.IsPointMarked(*pHdl) )
502 {
503 mrView.UnmarkPoint(*pHdl);
504 pHdl = nullptr;
505 }
506 else
507 {
508 pHdl = dynamic_cast< SmartHdl* >( mrView.PickHandle(aMDPos) );
509 }
510 }
511
512 if (pHdl)
513 mrView.MarkPoint(*pHdl);
514 }
515
516 if( pHdl && !rMEvt.IsRight() )
517 {
519 const sal_uInt16 nDrgLog = static_cast<sal_uInt16>(pOut->PixelToLogic(Size(DRGPIX,0)).Width());
520
522 SdrDragMethod* pDragMethod;
523
524 // #i95646# add DragPoly as geometry to each local SdrDragMethod to be able
525 // to create the needed local SdrDragEntry for it in createSdrDragEntries()
526 basegfx::B2DPolyPolygon aDragPoly(mpPathObj->GetPathPoly());
527
528 if( (pHdl->GetKind() == SdrHdlKind::Move) || (pHdl->GetKind() == SdrHdlKind::SmartTag) )
529 {
530 pDragMethod = new PathDragMove( mrView, xTag, aDragPoly );
531 pHdl->SetPos( aMDPos );
532 }
533 else if( pHdl->GetKind() == SdrHdlKind::Poly )
534 {
535 pDragMethod = new PathDragObjOwn( mrView, aDragPoly );
536 }
537 else
538 {
539 pDragMethod = new PathDragResize( mrView, xTag, std::move(aDragPoly) );
540 }
541
542 mrView.BegDragObj(aMDPos, nullptr, pHdl, nDrgLog, pDragMethod );
543 }
544 return true;
545 }
546 }
547 }
548
549 return false;
550}
551
554{
555 if( !mpPathObj )
556 return false;
557
558 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
559 switch( nCode )
560 {
561 case KEY_DELETE:
562 return OnDelete();
563
564 case KEY_DOWN:
565 case KEY_UP:
566 case KEY_LEFT:
567 case KEY_RIGHT:
568 return OnMove( rKEvt );
569
570 case KEY_ESCAPE:
571 {
572 SmartTagReference xThis( this );
574 return true;
575 }
576
577 case KEY_TAB:
578 return OnTabHandles( rKEvt );
579
580 case KEY_SPACE:
581 return OnMarkHandle( rKEvt );
582
583 default:
584 break;
585 }
586 return false;
587}
588
590{
592 return true;
593}
594
596{
597 if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
598 {
599 const SdrHdlList& rHdlList = mrView.GetHdlList();
600 bool bForward(!rKEvt.GetKeyCode().IsShift());
601
602 const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
603
604 // guarantee visibility of focused handle
605 SdrHdl* pHdl = rHdlList.GetFocusHdl();
606
607 if(pHdl)
608 {
610 if( pWindow )
611 {
612 Point aHdlPosition(pHdl->GetPos());
613 ::tools::Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
614 mrView.MakeVisible(aVisRect, *pWindow);
615 }
616 }
617
618 return true;
619 }
620
621 return false;
622}
623
625{
626 const SdrHdlList& rHdlList = mrView.GetHdlList();
627 SdrHdl* pHdl = rHdlList.GetFocusHdl();
628
629 if(pHdl && pHdl->GetKind() == SdrHdlKind::Poly )
630 {
631 // rescue ID of point with focus
632 sal_uInt32 nPol(pHdl->GetPolyNum());
633 sal_uInt32 nPnt(pHdl->GetPointNum());
634
635 if(mrView.IsPointMarked(*pHdl))
636 {
637 if(rKEvt.GetKeyCode().IsShift())
638 {
639 mrView.UnmarkPoint(*pHdl);
640 }
641 }
642 else
643 {
644 if(!rKEvt.GetKeyCode().IsShift())
645 {
647 }
648 mrView.MarkPoint(*pHdl);
649 }
650
651 if(nullptr == rHdlList.GetFocusHdl())
652 {
653 // restore point with focus
654 SdrHdl* pNewOne = nullptr;
655
656 for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a)
657 {
658 SdrHdl* pAct = rHdlList.GetHdl(a);
659
660 if(pAct && pAct->GetKind() == SdrHdlKind::Poly && pAct->GetPolyNum() == nPol && pAct->GetPointNum() == nPnt)
661 pNewOne = pAct;
662 }
663
664 if(pNewOne)
665 const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne);
666 }
667 }
668
669 return true;
670}
671
672bool MotionPathTag::OnMove( const KeyEvent& rKEvt )
673{
674 ::tools::Long nX = 0;
675 ::tools::Long nY = 0;
676
677 switch( rKEvt.GetKeyCode().GetCode() )
678 {
679 case KEY_UP: nY = -1; break;
680 case KEY_DOWN: nY = 1; break;
681 case KEY_LEFT: nX = -1; break;
682 case KEY_RIGHT: nX = 1; break;
683 default: break;
684 }
685
686 if(rKEvt.GetKeyCode().IsMod2())
687 {
689 Size aLogicSizeOnePixel = pOut ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100);
690 nX *= aLogicSizeOnePixel.Width();
691 nY *= aLogicSizeOnePixel.Height();
692 }
693 else
694 {
695 // old, fixed move distance
696 nX *= 100;
697 nY *= 100;
698 }
699
700 if( nX || nY )
701 {
702 // in point edit mode move the handle with the focus
703 const SdrHdlList& rHdlList = mrView.GetHdlList();
704 SdrHdl* pHdl = rHdlList.GetFocusHdl();
705
706 if(pHdl)
707 {
708 // now move the Handle (nX, nY)
709 Point aStartPoint(pHdl->GetPos());
710 Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
711
712 // start dragging
714 SdrDragMethod* pDragMethod = nullptr;
715 if( (pHdl->GetKind() == SdrHdlKind::Move) || (pHdl->GetKind() == SdrHdlKind::SmartTag) )
716 {
717 pDragMethod = new PathDragMove( mrView, xTag );
718 }
719 else if( pHdl->GetKind() == SdrHdlKind::Poly )
720 {
721 pDragMethod = new PathDragObjOwn( mrView );
722 }
723 else if( pHdl->GetKind() != SdrHdlKind::BezierWeight )
724 {
725 pDragMethod = new PathDragResize( mrView, xTag );
726 }
727 mrView.BegDragObj(aStartPoint, nullptr, pHdl, 0, pDragMethod);
728
729 if(mrView.IsDragObj())
730 {
731 bool bWasNoSnap = mrView.GetDragStat().IsNoSnap();
732 bool bWasSnapEnabled = mrView.IsSnapEnabled();
733
734 // switch snapping off
735 if(!bWasNoSnap)
736 const_cast<SdrDragStat&>(mrView.GetDragStat()).SetNoSnap();
737 if(bWasSnapEnabled)
738 mrView.SetSnapEnabled(false);
739
740 mrView.MovAction(aEndPoint);
742
743 // restore snap
744 if(!bWasNoSnap)
745 const_cast<SdrDragStat&>(mrView.GetDragStat()).SetNoSnap(bWasNoSnap);
746 if(bWasSnapEnabled)
747 mrView.SetSnapEnabled(bWasSnapEnabled);
748 }
749 }
750 else
751 {
752 // move the path
753 MovePath( nX, nY );
754 }
755 }
756
757 return true;
758}
759
761{
762 if( mpPathObj && isSelected() )
763 {
764 return mpPathObj->GetPointCount();
765 }
766 else
767 {
768 return 0;
769 }
770}
771
773{
774 if( mpMark )
775 {
776 const SdrUShortCont& rPts = mpMark->GetMarkedPoints();
777 return rPts.size();
778 }
779 else
780 {
781 return 0;
782 }
783}
784
785bool MotionPathTag::MarkPoint(SdrHdl& rHdl, bool bUnmark )
786{
787 bool bRet=false;
788 if( mpPathObj && mrView.IsPointMarkable( rHdl ) && (rHdl.GetKind() != SdrHdlKind::SmartTag) )
789 {
790 SmartHdl* pSmartHdl = dynamic_cast< SmartHdl* >( &rHdl );
791 if( pSmartHdl && pSmartHdl->getTag().get() == this )
792 {
793 if (mrView.MarkPointHelper(&rHdl,mpMark.get(),bUnmark))
794 {
796 bRet=true;
797 }
798 }
799 }
800 return bRet;
801}
802
803bool MotionPathTag::MarkPoints(const ::tools::Rectangle* pRect, bool bUnmark )
804{
805 bool bChgd=false;
806
807 if( mpPathObj && isSelected() )
808 {
809 size_t nHdlNum = mrView.GetHdlList().GetHdlCount();
810 if ( nHdlNum <= 1 )
811 return false;
812
813 while( --nHdlNum > 0 )
814 {
815 SmartHdl* pHdl = dynamic_cast< SmartHdl* >( mrView.GetHdl( nHdlNum ) );
816
817 if( pHdl && (pHdl->getTag().get() == this) && mrView.IsPointMarkable(*pHdl) && pHdl->IsSelected() == bUnmark)
818 {
819 Point aPos(pHdl->GetPos());
820 if( pRect==nullptr || pRect->Contains(aPos))
821 {
822 if( mrView.MarkPointHelper(pHdl,mpMark.get(),bUnmark) )
823 bChgd=true;
824 }
825 }
826 }
827
828 if(bChgd)
830 }
831
832 return bChgd;
833}
834
836{
838 {
839 rContext = SdrViewContext::PointEdit;
840 return true;
841 }
842 else
843 {
844 return false;
845 }
846}
847
849{
850 if( !(mpPathObj && isSelected()) )
851 return;
852
853 mrView.SetMoveAllowed( true );
854 mrView.SetMoveProtected( false );
857 mrView.SetResizeProtected( false );
858
860 {
861 bool b1stSmooth(true);
862 bool b1stSegm(true);
863 bool bCurve(false);
864 bool bSmoothFuz(false);
865 bool bSegmFuz(false);
867
868 mrView.CheckPolyPossibilitiesHelper( mpMark.get(), b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth );
869 }
870}
871
873{
874 if( !mpPathObj )
875 return;
876
877 css::awt::Point aPos;
878 if (mxOrigin.is())
879 aPos = mxOrigin->getPosition();
880 if( (aPos.X != maOriginPos.X) || (aPos.Y != maOriginPos.Y) )
881 {
883 aPos.X - maOriginPos.X, aPos.Y - maOriginPos.Y));
884 mxPolyPoly.transform( aTransform );
885 mpPathObj->SetPathPoly( mxPolyPoly );
886 maOriginPos = aPos;
887 }
888
889 SmartTagReference xThis( this );
890 std::unique_ptr<SdPathHdl> pHdl(new SdPathHdl( xThis, mpPathObj.get() ));
891 pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM );
892 pHdl->SetPageView( mrView.GetSdrPageView() );
893 pHdl->SetObj(mpPathObj.get());
894 rHandlerList.AddHdl( std::move(pHdl) );
895
896 if( !isSelected() )
897 return;
898
900
902 {
903 SdrHdlList aTemp( rHandlerList.GetView() );
904 mpPathObj->AddToHdlList( aTemp );
905 const SdrUShortCont& rMrkPnts = mpMark->GetMarkedPoints();
906
907 for( size_t nHandle = 0; nHandle < aTemp.GetHdlCount(); ++nHandle )
908 {
909 SdrHdl* pTempHdl = aTemp.GetHdl( nHandle );
910
911 SmartHdl* pSmartHdl = new SmartHdl( xThis, mpPathObj.get(), pTempHdl->GetPos(), pTempHdl->GetKind() );
912 pSmartHdl->SetObjHdlNum( static_cast<sal_uInt32>(nHandle) );
913 pSmartHdl->SetPolyNum( pTempHdl->GetPolyNum() );
914 pSmartHdl->SetPointNum( pTempHdl->GetPointNum() );
915 pSmartHdl->SetPlusHdl( pTempHdl->IsPlusHdl() );
916 pSmartHdl->SetSourceHdlNum( pTempHdl->GetSourceHdlNum() );
917 pSmartHdl->SetPageView( mrView.GetSdrPageView() );
918
919 rHandlerList.AddHdl( std::unique_ptr<SmartHdl>(pSmartHdl) );
920
921 const bool bSelected = rMrkPnts.find( sal_uInt16(nHandle) ) != rMrkPnts.end();
922 pSmartHdl->SetSelected(bSelected);
923
924 if( mrView.IsPlusHandlesAlwaysVisible() || bSelected )
925 {
926 SdrHdlList plusList(nullptr);
927 mpPathObj->AddToPlusHdlList(plusList, *pSmartHdl);
928 sal_uInt32 nPlusHdlCnt=plusList.GetHdlCount();
929 for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusHdlCnt; nPlusNum++)
930 {
931 SdrHdl* pPlusHdl = plusList.GetHdl(nPlusNum);
932 pPlusHdl->SetObj(mpPathObj.get());
933 pPlusHdl->SetPageView(mrView.GetSdrPageView());
934 pPlusHdl->SetPlusHdl(true);
935 }
936 plusList.MoveTo(rHandlerList);
937 }
938 }
939 }
940 else
941 {
942 ::tools::Rectangle aRect(mpPathObj->GetCurrentBoundRect());
943
944 if(!aRect.IsEmpty())
945 {
946 size_t nCount = rHandlerList.GetHdlCount();
947
948 bool bWdt0=aRect.Left()==aRect.Right();
949 bool bHgt0=aRect.Top()==aRect.Bottom();
950 if (bWdt0 && bHgt0)
951 {
952 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.TopLeft(),SdrHdlKind::UpperLeft));
953 }
954 else if (bWdt0 || bHgt0)
955 {
956 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.TopLeft() ,SdrHdlKind::UpperLeft));
957 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.BottomRight(),SdrHdlKind::LowerRight));
958 }
959 else // !bWdt0 && !bHgt0
960 {
961 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.TopLeft() ,SdrHdlKind::UpperLeft));
962 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.TopCenter() ,SdrHdlKind::Upper));
963 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.TopRight() ,SdrHdlKind::UpperRight));
964 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.LeftCenter() ,SdrHdlKind::Left ));
965 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.RightCenter() ,SdrHdlKind::Right));
966 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.BottomLeft() ,SdrHdlKind::LowerLeft));
967 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.BottomCenter(),SdrHdlKind::Lower));
968 rHandlerList.AddHdl(std::make_unique<SmartHdl>( xThis, mpPathObj.get(), aRect.BottomRight() ,SdrHdlKind::LowerRight));
969 }
970
971 while( nCount < rHandlerList.GetHdlCount() )
972 {
973 rHandlerList.GetHdl(nCount++)->SetPageView( mrView.GetSdrPageView() );
974 }
975 }
976 }
977}
978
980{
981 Reference< XChangesNotifier > xNotifier( mpEffect->getNode(), UNO_QUERY );
982 if( xNotifier.is() )
983 {
984 xNotifier->removeChangesListener( this );
985 }
986
987 if( mpPathObj )
988 {
989 mpPathObj = nullptr;
991 }
992
993 mpMark.reset();
994
996}
997
999{
1001
1002 if( mpMark )
1003 {
1004 SdrUShortCont& rPts = mpMark->GetMarkedPoints();
1005 rPts.clear();
1006 }
1007
1009}
1010
1012{
1014 {
1016 rBindings.InvalidateAll(true);
1017 }
1018}
1019
1020// IPolyPolygonEditorController
1021
1023{
1025 return;
1026
1027 mrView.BrkAction();
1028
1029 SdrUShortCont& rPts = mpMark->GetMarkedPoints();
1030 PolyPolygonEditor aEditor( mpPathObj->GetPathPoly());
1031 if (aEditor.DeletePoints(rPts))
1032 {
1033 if( aEditor.GetPolyPolygon().count() )
1034 {
1035 mpPathObj->SetPathPoly( aEditor.GetPolyPolygon() );
1036 }
1037
1041 }
1042}
1043
1045{
1046 return mpPathObj && isSelected() && (GetMarkedPointCount() != 0);
1047}
1048
1050{
1051 // not supported for motion path
1052}
1053
1055{
1056 // not supported for motion path
1057 return false;
1058}
1059
1061{
1062 if( mpPathObj )
1064 else
1065 return false;
1066}
1067
1069{
1070 if( mpPathObj )
1072 else
1073 return SdrPathSegmentKind::Line;
1074}
1075
1077{
1078 if(mpPathObj && isSelected() && (GetMarkedPointCount() != 0))
1079 {
1080 SdrUShortCont& rPts = mpMark->GetMarkedPoints();
1081 PolyPolygonEditor aEditor( mpPathObj->GetPathPoly() );
1082 if (aEditor.SetSegmentsKind(eKind, rPts))
1083 {
1084 mpPathObj->SetPathPoly(aEditor.GetPolyPolygon());
1087 }
1088 }
1089}
1090
1092{
1093 if( mpPathObj )
1095 else
1096 return false;
1097}
1098
1100{
1101 if( mpPathObj )
1103 else
1104 return SdrPathSmoothKind::Angular;
1105}
1106
1108{
1110
1111 if(SdrPathSmoothKind::Angular == eKind)
1112 {
1114 }
1115 else if(SdrPathSmoothKind::Asymmetric == eKind)
1116 {
1118 }
1119 else if(SdrPathSmoothKind::Symmetric == eKind)
1120 {
1122 }
1123 else
1124 {
1125 return;
1126 }
1127
1128 if(mpPathObj && mpMark && isSelected() && (GetMarkedPointCount() != 0))
1129 {
1130 SdrUShortCont& rPts = mpMark->GetMarkedPoints();
1131 PolyPolygonEditor aEditor( mpPathObj->GetPathPoly());
1132 if (aEditor.SetPointsSmooth(eFlags, rPts))
1133 {
1134 mpPathObj->SetPathPoly(aEditor.GetPolyPolygon());
1137 }
1138 }
1139}
1140
1142{
1143 // not supported for motion path
1144 return false;
1145}
1146
1148{
1149 // not supported for motion path
1150 return SdrObjClosedKind::Open;
1151}
1152
1153// XChangesListener
1154void SAL_CALL MotionPathTag::changesOccurred( const ChangesEvent& /*Event*/ )
1155{
1156 if( mpPathObj && !mbInUpdatePath && (mpEffect->getPath() != msLastPath) )
1157 {
1158 mbInUpdatePath =true;
1159 msLastPath = mpEffect->getPath();
1160 mpEffect->updateSdrPathObjFromPath( *mpPathObj );
1161 mbInUpdatePath = false;
1164 }
1165}
1166
1167void SAL_CALL MotionPathTag::disposing( const EventObject& /*Source*/ )
1168{
1169 if( mpPathObj )
1170 Dispose();
1171}
1172
1173Any SAL_CALL MotionPathTag::queryInterface( const css::uno::Type& aType )
1174{
1176 return Any( Reference< XChangesListener >( this ) );
1177 if( aType == cppu::UnoType<XEventListener>::get() )
1178 return Any( Reference< XEventListener >( this ) );
1179 if( aType == cppu::UnoType<XInterface>::get() )
1180 return Any( Reference< XInterface >( this ) );
1181
1182 return Any();
1183}
1184
1185void SAL_CALL MotionPathTag::acquire() noexcept
1186{
1188}
1189
1190void SAL_CALL MotionPathTag::release( ) noexcept
1191{
1193}
1194
1195} // end of namespace sd
1196
1197/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool BegDragObj(const Point &rPnt, OutputDevice *pOut, SdrHdl *pHdl, short nMinMov=-3, SdrDragMethod *pForcedMeth=nullptr) override
virtual void MovAction(const Point &rPnt) override
const vcl::KeyCode & GetKeyCode() const
bool IsMod1() const
sal_uInt16 GetClicks() const
bool IsRight() const
const Point & GetPosPixel() const
bool IsLeft() const
bool IsShift() const
virtual void BrkAction() override
virtual void createSdrDragEntries()
virtual void createSdrDragEntries() override
bool IsNoSnap() const
bool EndDragObj(bool bCopy=false)
void MovDragObj(const Point &rPnt)
bool IsInsObjPointMode() const
bool IsDragObj() const
void MoveTo(SdrHdlList &rOther)
size_t GetHdlCount() const
SdrMarkView * GetView() const
void AddHdl(std::unique_ptr< SdrHdl > pHdl)
SdrHdl * GetFocusHdl() const
SdrHdl * GetHdl(size_t nNum) const
void SetSelected(bool bJa=true)
bool IsSelected() const
SdrHdlKind GetKind() const
sal_uInt32 GetObjHdlNum() const
sal_uInt32 GetSourceHdlNum() const
void SetPos(const Point &rPnt)
sal_uInt32 GetPolyNum() const
bool IsPlusHdl() const
void SetPlusHdl(bool bOn)
void SetObj(SdrObject *pNewObj)
const Point & GetPos() const
sal_uInt32 GetPointNum() const
void SetObjHdlNum(sal_uInt32 nNum)
void SetPolyNum(sal_uInt32 nNum)
void SetPointNum(sal_uInt32 nNum)
void SetSourceHdlNum(sal_uInt32 nNum)
void SetPageView(SdrPageView *pNewPV)
bool IsFrameDragSingles() const
SdrHdl * PickHandle(const Point &rPnt) const
const SdrHdlList & GetHdlList() const
bool MarkPointHelper(SdrHdl *pHdl, SdrMark *pMark, bool bUnmark)
bool IsPointMarkable(const SdrHdl &rHdl) const
bool UnmarkAllPoints()
SdrHdl * GetHdl(size_t nHdlNum) const
bool areMarkHandlesHidden() const
bool UnmarkPoint(SdrHdl &rHdl)
bool IsPointMarked(const SdrHdl &rHdl) const
bool IsPlusHandlesAlwaysVisible() const
void BroadcastObjectChange() const
virtual const tools::Rectangle & GetCurrentBoundRect() const
virtual void SetChanged()
virtual bool applySpecialDrag(SdrDragStat &rDrag)
sal_uInt32 PageWindowCount() const
void SetHasMarkedObj(bool bOn)
SdrPageWindow * GetPageWindow(sal_uInt32 nIndex) const
rtl::Reference< sdr::overlay::OverlayManager > const & GetOverlayManager() const
SdrPaintWindow & GetPaintWindow() const
const sdr::contact::ObjectContact & GetObjectContact() const
virtual void MakeVisible(const tools::Rectangle &rRect, vcl::Window &rWin)
SdrModel & getSdrModelFromSdrView() const
const SdrDragStat & GetDragStat() const
SdrPageView * GetSdrPageView() const
bool OutputToWindow() const
void SetPathPoly(const basegfx::B2DPolyPolygon &rPathPoly)
const basegfx::B2DPolyPolygon & GetPathPoly() const
void CheckPolyPossibilitiesHelper(SdrMark *pM, bool &b1stSmooth, bool &b1stSegm, bool &bCurve, bool &bSmoothFuz, bool &bSegmFuz, basegfx::B2VectorContinuity &eSmooth)
SdrPathSmoothKind GetMarkedPointsSmooth() const override
bool IsSetMarkedPointsSmoothPossible() const override
SdrPathSegmentKind GetMarkedSegmentsKind() const override
bool IsSetMarkedSegmentsKindPossible() const override
void SetSnapEnabled(bool bOn)
bool IsSnapEnabled() const
Point GetSnapPos(const Point &rPnt, const SdrPageView *pPV) const
void InvalidateAll(bool bWithMsg)
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
SfxHintId GetId() const
SfxBindings & GetBindings()
SfxDispatcher * GetDispatcher()
constexpr tools::Long Height() const
constexpr tools::Long Width() const
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
void transform(const basegfx::B2DHomMatrix &rMatrix)
sal_uInt32 count() const
bool isClosed() const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
void setClosed(bool bNew)
const_iterator find(const Value &x) const
const_iterator end() const
size_type size() const
void updatePathFromMotionPathTag(const rtl::Reference< MotionPathTag > &xTag)
void remove(CustomAnimationEffectPtr const &pEffect)
virtual bool MarkPoints(const ::tools::Rectangle *pRect, bool bUnmark) override
virtual void DeleteMarkedPoints() override
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
CustomAnimationPane & mrPane
virtual bool IsSetMarkedPointsSmoothPossible() const override
virtual bool KeyInput(const KeyEvent &rKEvt) override
returns true if the SmartTag consumes this event.
virtual void RipUpAtMarkedPoints() override
virtual ~MotionPathTag() override
CustomAnimationEffectPtr mpEffect
virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent &Event) override
bool OnTabHandles(const KeyEvent &rKEvt)
::basegfx::B2DPolyPolygon mxPolyPoly
virtual SdrObjClosedKind GetMarkedObjectsClosedState() const override
virtual SdrPathSegmentKind GetMarkedSegmentsKind() const override
virtual void addCustomHandles(SdrHdlList &rHandlerList) override
rtl::Reference< SdrPathObj > mpPathObj
virtual void SetMarkedPointsSmooth(SdrPathSmoothKind eKind) override
virtual bool IsOpenCloseMarkedObjectsPossible() const override
css::uno::Reference< css::drawing::XShape > mxOrigin
bool OnMove(const KeyEvent &rKEvt)
virtual void SAL_CALL release() noexcept override
virtual sal_Int32 GetMarkedPointCount() const override
virtual SdrPathSmoothKind GetMarkedPointsSmooth() const override
css::awt::Point maOriginPos
bool OnMarkHandle(const KeyEvent &rKEvt)
virtual bool IsDeleteMarkedPointsPossible() const override
virtual sal_Int32 GetMarkablePointCount() const override
virtual bool MouseButtonDown(const MouseEvent &, SmartHdl &) override
returns true if the MotionPathTag handled the event.
virtual bool IsRipUpAtMarkedPointsPossible() const override
virtual bool IsSetMarkedSegmentsKindPossible() const override
virtual void SAL_CALL acquire() noexcept override
virtual bool MarkPoint(SdrHdl &rHdl, bool bUnmark) override
virtual void disposing() override
virtual void deselect() override
virtual void CheckPossibilities() override
virtual void SetMarkedSegmentsKind(SdrPathSegmentKind eKind) override
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
virtual bool getContext(SdrViewContext &rContext) override
std::unique_ptr< SdrMark > mpMark
void MovePath(int nDX, int nDY)
void acquire()
@ATTENTION The results are undefined if, for any individual instance of SimpleReferenceComponent,...
a derivation from this handle is the visual representation for a smart tag.
Definition: smarttag.hxx:157
const SmartTagReference & getTag() const
Definition: smarttag.hxx:162
void select(const SmartTagReference &xTag)
selects the given smart tag and updates all handles
Definition: smarttag.cxx:155
void deselect()
deselects the current selected smart tag and updates all handles
Definition: smarttag.cxx:172
a smart tag represents a visual user interface element on the documents edit view that is not part of...
Definition: smarttag.hxx:44
::sd::View & mrView
Definition: smarttag.hxx:79
virtual void deselect()
Definition: smarttag.cxx:69
virtual void disposing() override
Definition: smarttag.cxx:74
bool isSelected() const
returns true if this smart tag is currently selected
Definition: smarttag.hxx:61
::sd::Window * GetActiveWindow() const
The active window is usually the mpContentWindow.
Definition: ViewShell.hxx:155
SD_DLLPUBLIC SfxViewFrame * GetViewFrame() const
Definition: viewshel.cxx:118
ViewShell * GetViewShell() const
Definition: View.hxx:144
void SetResizeFreeAllowed(bool bSet)
Definition: View.hxx:243
void SetResizePropAllowed(bool bSet)
Definition: View.hxx:244
void SetMoveProtected(bool bSet)
Definition: View.hxx:242
void SetMoveAllowed(bool bSet)
Definition: View.hxx:241
virtual bool MarkPoint(SdrHdl &rHdl, bool bUnmark=false) override
Definition: sdview.cxx:1159
SmartTagSet & getSmartTags()
Definition: View.hxx:207
void updateHandles()
Definition: sdview.cxx:1122
void SetResizeProtected(bool bSet)
Definition: View.hxx:245
virtual void MarkListHasChanged() override
Definition: sdview.cxx:501
An SdWindow contains the actual working area of ViewShell.
Definition: Window.hxx:45
const basegfx::B2DPolyPolygon & GetPolyPolygon() const
bool SetPointsSmooth(basegfx::B2VectorContinuity eFlags, const o3tl::sorted_vector< sal_uInt16 > &rAbsPoints)
bool DeletePoints(const o3tl::sorted_vector< sal_uInt16 > &rAbsPoints)
bool SetSegmentsKind(SdrPathSegmentKind eKind, const o3tl::sorted_vector< sal_uInt16 > &rAbsPoints)
virtual ViewContact & GetViewContact(sal_uInt32 nIndex) const
void getViewIndependentPrimitive2DContainer(drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr tools::Long Right() const
constexpr Point RightCenter() const
constexpr Point BottomCenter() const
constexpr Point BottomRight() const
constexpr Point TopRight() const
constexpr Point LeftCenter() const
constexpr Point TopCenter() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
constexpr Point BottomLeft() const
bool IsMod1() const
sal_uInt16 GetCode() const
bool IsShift() const
bool IsMod2() const
::OutputDevice const * GetOutDev() const
constexpr ::Color COL_GRAY(0x80, 0x80, 0x80)
int nCount
#define DBG_ASSERT(sCon, aError)
SdrPathSmoothKind
SdrObjClosedKind
SdrPathSegmentKind
uno_Any a
constexpr sal_uInt16 KEY_ESCAPE
constexpr sal_uInt16 KEY_LEFT
constexpr sal_uInt16 KEY_TAB
constexpr sal_uInt16 KEY_UP
constexpr sal_uInt16 KEY_RIGHT
constexpr sal_uInt16 KEY_DELETE
constexpr sal_uInt16 KEY_DOWN
constexpr sal_uInt16 KEY_SPACE
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
B2VectorContinuity
rtl::Reference< SmartTag > SmartTagReference
Definition: smarttag.hxx:87
const int DRGPIX
std::shared_ptr< CustomAnimationEffect > CustomAnimationEffectPtr
const sal_uInt32 SMART_TAG_HDL_NUM
long Long
sal_Int32 nHandle
SdrHdlKind
SdrViewContext
#define SAL_MAX_UINT32
oslFileHandle & pOut