Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / ui / func / fupoor.cxx
blob3a18ec79469d9fdaa5d20e14905a6bdc4729d44a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <fupoor.hxx>
22 #include <svx/svxids.hrc>
23 #include <svl/aeitem.hxx>
24 #include <svx/svdpagv.hxx>
25 #include <svx/svdoole2.hxx>
26 #include <svx/svdograf.hxx>
27 #include <vcl/seleng.hxx>
28 #include <sfx2/app.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <sfx2/bindings.hxx>
31 #include <sfx2/request.hxx>
32 #include <vcl/dialog.hxx>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/drawing/XLayer.hpp>
35 #include <com/sun/star/drawing/XLayerManager.hpp>
36 #include <com/sun/star/container/XChild.hpp>
38 #include <FrameView.hxx>
39 #include <app.hrc>
40 #include <fusel.hxx>
41 #include <sdpage.hxx>
42 #include <drawview.hxx>
43 #include <DrawViewShell.hxx>
44 #include <Window.hxx>
45 #include <drawdoc.hxx>
46 #include <DrawDocShell.hxx>
47 #include <zoomlist.hxx>
48 #include <Client.hxx>
49 #include <slideshow.hxx>
50 #include <LayerTabBar.hxx>
52 #include <sfx2/viewfrm.hxx>
54 #include <svx/svditer.hxx>
56 #include <editeng/editeng.hxx>
58 using namespace ::com::sun::star;
60 namespace sd {
63 FuPoor::FuPoor (
64 ViewShell* pViewSh,
65 ::sd::Window* pWin,
66 ::sd::View* pView,
67 SdDrawDocument* pDrDoc,
68 SfxRequest& rReq)
69 : mpView(pView),
70 mpViewShell(pViewSh),
71 mpWindow(pWin),
72 mpDocSh( pDrDoc->GetDocSh() ),
73 mpDoc(pDrDoc),
74 nSlotId( rReq.GetSlot() ),
75 pDialog(nullptr),
76 bIsInDragMode(false),
77 bNoScrollUntilInside (true),
78 bScrollable (false),
79 bDelayActive (false),
80 bFirstMouseMove (false),
81 // remember MouseButton state
82 mnCode(0)
84 ReceiveRequest(rReq);
86 aScrollTimer.SetInvokeHandler( LINK(this, FuPoor, ScrollHdl) );
87 aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
89 aDragTimer.SetInvokeHandler( LINK(this, FuPoor, DragHdl) );
90 aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
92 aDelayToScrollTimer.SetInvokeHandler( LINK(this, FuPoor, DelayHdl) );
93 aDelayToScrollTimer.SetTimeout(2000);
96 FuPoor::~FuPoor()
98 aDragTimer.Stop();
99 aScrollTimer.Stop();
100 aDelayToScrollTimer.Stop();
101 pDialog.disposeAndClear();
104 void FuPoor::Activate()
106 if (pDialog)
108 pDialog->Show();
112 void FuPoor::Deactivate()
114 aDragTimer.Stop();
115 aScrollTimer.Stop();
116 aDelayToScrollTimer.Stop ();
117 bScrollable = bDelayActive = false;
119 if (pDialog)
121 pDialog->Hide();
124 if (mpWindow && mpWindow->IsMouseCaptured())
125 mpWindow->ReleaseMouse();
128 void FuPoor::SetWindow(::sd::Window* pWin)
130 mpWindow = pWin;
134 * scroll when approached the border of the window; is called by MouseMove
136 void FuPoor::ForceScroll(const Point& aPixPos)
138 aScrollTimer.Stop();
140 if ( !mpView->IsDragHelpLine() && !mpView->IsSetPageOrg() &&
141 !SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) )
143 Point aPos = mpWindow->OutputToScreenPixel(aPixPos);
144 const ::tools::Rectangle& rRect = mpViewShell->GetAllWindowRect();
146 if ( bNoScrollUntilInside )
148 if ( rRect.IsInside(aPos) )
149 bNoScrollUntilInside = false;
151 else
153 short dx = 0, dy = 0;
155 if ( aPos.X() <= rRect.Left() ) dx = -1;
156 if ( aPos.X() >= rRect.Right() ) dx = 1;
157 if ( aPos.Y() <= rRect.Top() ) dy = -1;
158 if ( aPos.Y() >= rRect.Bottom() ) dy = 1;
160 if ( dx != 0 || dy != 0 )
162 if (bScrollable)
164 // scroll action in derived class
165 mpViewShell->ScrollLines(dx, dy);
166 aScrollTimer.Start();
168 else if (! bDelayActive) StartDelayToScrollTimer ();
175 * timer handler for window scrolling
177 IMPL_LINK_NOARG(FuPoor, ScrollHdl, Timer *, void)
179 Point aPnt(mpWindow->GetPointerPosPixel());
181 // use remembered MouseButton state to create correct
182 // MouseEvents for this artificial MouseMove.
183 MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
187 * handle keyboard events
188 * @returns sal_True if the event was handled, sal_False otherwise
190 bool FuPoor::KeyInput(const KeyEvent& rKEvt)
192 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
193 bool bReturn = false;
194 bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() );
196 switch (nCode)
198 case KEY_RETURN:
200 if(rKEvt.GetKeyCode().IsMod1())
202 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
204 DrawViewShell* pDrawViewShell =
205 static_cast<DrawViewShell*>(mpViewShell);
206 SdPage* pActualPage = pDrawViewShell->GetActualPage();
207 SdrTextObj* pCandidate = nullptr;
209 if(pActualPage)
211 SdrObjListIter aIter(*pActualPage, SdrIterMode::DeepNoGroups);
213 while(aIter.IsMore() && !pCandidate)
215 SdrObject* pObj = aIter.Next();
217 if(pObj && dynamic_cast< const SdrTextObj *>( pObj ) != nullptr)
219 SdrInventor nInv(pObj->GetObjInventor());
220 sal_uInt16 nKnd(pObj->GetObjIdentifier());
222 if(SdrInventor::Default == nInv &&
223 (OBJ_TITLETEXT == nKnd || OBJ_OUTLINETEXT == nKnd || OBJ_TEXT == nKnd))
225 pCandidate = static_cast<SdrTextObj*>(pObj);
231 if(pCandidate)
233 mpView->UnMarkAll();
234 mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
236 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
237 SID_ATTR_CHAR, SfxCallMode::ASYNCHRON);
239 else
241 // insert a new page with the same page layout
242 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
243 SID_INSERTPAGE_QUICK, SfxCallMode::ASYNCHRON);
246 // consumed
247 bReturn = true;
250 else
252 // activate OLE object on RETURN for selected object
253 // activate text edit on RETURN for selected object
254 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
256 if( !mpView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
258 SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
260 if( pObj && dynamic_cast< const SdrOle2Obj* >( pObj ) != nullptr && !mpDocSh->IsUIActive() )
262 //HMHmpView->HideMarkHdl();
263 mpViewShell->ActivateObject( static_cast< SdrOle2Obj* >( pObj ), 0 );
265 else if( pObj && pObj->IsEmptyPresObj() && dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr )
267 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_GRAPHIC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
269 else
271 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_ATTR_CHAR, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
274 // consumed
275 bReturn = true;
279 break;
281 case KEY_TAB:
283 // handle Mod1 and Mod2 to get travelling running on different systems
284 if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
286 // do something with a selected handle?
287 const SdrHdlList& rHdlList = mpView->GetHdlList();
288 bool bForward(!rKEvt.GetKeyCode().IsShift());
290 const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
292 // guarantee visibility of focused handle
293 SdrHdl* pHdl = rHdlList.GetFocusHdl();
295 if(pHdl)
297 Point aHdlPosition(pHdl->GetPos());
298 ::tools::Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
299 mpView->MakeVisible(aVisRect, *mpWindow);
302 // consumed
303 bReturn = true;
306 break;
308 case KEY_ESCAPE:
310 bReturn = FuPoor::cancel();
312 break;
314 case KEY_ADD:
316 if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
318 // increase zoom
319 mpViewShell->SetZoom(mpWindow->GetZoom() * 3 / 2);
321 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
322 static_cast<DrawViewShell*>(mpViewShell)
323 ->SetZoomOnPage(false);
325 bReturn = true;
328 break;
330 case KEY_SUBTRACT:
332 if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
334 // decrease zoom
335 mpViewShell->SetZoom(mpWindow->GetZoom() * 2 / 3);
337 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
338 static_cast<DrawViewShell*>(mpViewShell)
339 ->SetZoomOnPage(false);
341 bReturn = true;
344 break;
346 case KEY_MULTIPLY:
348 if (!mpView->IsTextEdit() && !bSlideShow)
350 // zoom to page
351 mpViewShell->GetViewFrame()->GetDispatcher()->
352 Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
353 bReturn = true;
356 break;
358 case KEY_DIVIDE:
360 if (!mpView->IsTextEdit() && !bSlideShow)
362 // zoom to selected objects
363 mpViewShell->GetViewFrame()->GetDispatcher()->
364 Execute(SID_SIZE_OPTIMAL, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
365 bReturn = true;
368 break;
370 case KEY_POINT:
372 ZoomList* pZoomList = mpViewShell->GetZoomList();
374 if (!mpView->IsTextEdit() && pZoomList->IsNextPossible() && !bSlideShow && !mpDocSh->IsUIActive())
376 // use next ZoomRect
377 mpViewShell->SetZoomRect(pZoomList->GetNextZoomRect());
378 bReturn = true;
381 break;
383 case KEY_COMMA:
385 ZoomList* pZoomList = mpViewShell->GetZoomList();
387 if (!mpView->IsTextEdit() && pZoomList->IsPreviousPossible() && !bSlideShow && !mpDocSh->IsUIActive())
389 // use previous ZoomRect
390 mpViewShell->SetZoomRect(pZoomList->GetPreviousZoomRect());
391 bReturn = true;
394 break;
396 case KEY_HOME:
398 if (!mpView->IsTextEdit()
399 && dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr
400 && !bSlideShow)
402 // jump to first page
403 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(0);
404 bReturn = true;
407 break;
409 case KEY_END:
411 if (!mpView->IsTextEdit()
412 && dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr
413 && !bSlideShow)
415 // jump to last page
416 SdPage* pPage =
417 static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
418 static_cast<DrawViewShell*>(mpViewShell)
419 ->SwitchPage(mpDoc->GetSdPageCount(
420 pPage->GetPageKind()) - 1);
421 bReturn = true;
424 break;
426 case KEY_PAGEUP:
428 if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
429 break;
431 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr && !bSlideShow)
433 // The page-up key switches layers or pages depending on the
434 // modifier key.
435 if ( ! rKEvt.GetKeyCode().GetModifier())
437 // With no modifier pressed we move to the previous
438 // slide.
439 mpView->SdrEndTextEdit();
441 // Previous page.
442 bReturn = true;
443 SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
444 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
446 if (nSdPage > 0)
448 // Switch the page and send events regarding
449 // deactivation the old page and activating the new
450 // one.
451 TabControl& rPageTabControl =
452 static_cast<DrawViewShell*>(mpViewShell)
453 ->GetPageTabControl();
454 if (rPageTabControl.IsReallyShown())
455 rPageTabControl.SendDeactivatePageEvent ();
456 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage - 1);
457 if (rPageTabControl.IsReallyShown())
458 rPageTabControl.SendActivatePageEvent ();
461 else if (rKEvt.GetKeyCode().IsMod1())
463 // With the CONTROL modifier we switch layers.
464 if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
466 // Moves to the previous layer.
467 SwitchLayer (-1);
472 break;
474 case KEY_PAGEDOWN:
476 if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
477 break;
478 if(dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr && !bSlideShow)
480 // The page-down key switches layers or pages depending on the
481 // modifier key.
482 if ( ! rKEvt.GetKeyCode().GetModifier())
484 // With no modifier pressed we move to the next slide.
485 mpView->SdrEndTextEdit();
487 // Next page.
488 bReturn = true;
489 SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
490 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
492 if (nSdPage < mpDoc->GetSdPageCount(pPage->GetPageKind()) - 1)
494 // Switch the page and send events regarding
495 // deactivation the old page and activating the new
496 // one.
497 TabControl& rPageTabControl =
498 static_cast<DrawViewShell*>(mpViewShell)->GetPageTabControl();
499 if (rPageTabControl.IsReallyShown())
500 rPageTabControl.SendDeactivatePageEvent ();
501 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage + 1);
502 if (rPageTabControl.IsReallyShown())
503 rPageTabControl.SendActivatePageEvent ();
506 else if (rKEvt.GetKeyCode().IsMod1())
508 // With the CONTROL modifier we switch layers.
509 if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
511 // With the layer mode active pressing page-down
512 // moves to the next layer.
513 SwitchLayer (+1);
518 break;
520 // change select state when focus is on poly point
521 case KEY_SPACE:
523 const SdrHdlList& rHdlList = mpView->GetHdlList();
524 SdrHdl* pHdl = rHdlList.GetFocusHdl();
526 if(pHdl)
528 if(pHdl->GetKind() == SdrHdlKind::Poly)
530 // rescue ID of point with focus
531 sal_uInt32 nPol(pHdl->GetPolyNum());
532 sal_uInt32 nPnt(pHdl->GetPointNum());
534 if(mpView->IsPointMarked(*pHdl))
536 if(rKEvt.GetKeyCode().IsShift())
538 mpView->UnmarkPoint(*pHdl);
541 else
543 if(!rKEvt.GetKeyCode().IsShift())
545 mpView->UnmarkAllPoints();
548 mpView->MarkPoint(*pHdl);
551 if(nullptr == rHdlList.GetFocusHdl())
553 // restore point with focus
554 SdrHdl* pNewOne = nullptr;
556 for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a)
558 SdrHdl* pAct = rHdlList.GetHdl(a);
560 if(pAct
561 && pAct->GetKind() == SdrHdlKind::Poly
562 && pAct->GetPolyNum() == nPol
563 && pAct->GetPointNum() == nPnt)
565 pNewOne = pAct;
569 if(pNewOne)
571 const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne);
575 bReturn = true;
579 break;
581 case KEY_UP:
582 case KEY_DOWN:
583 case KEY_LEFT:
584 case KEY_RIGHT:
586 if (!mpView->IsTextEdit() && !bSlideShow)
588 long nX = 0;
589 long nY = 0;
591 if (nCode == KEY_UP)
593 // scroll up
594 nX = 0;
595 nY =-1;
597 else if (nCode == KEY_DOWN)
599 // scroll down
600 nX = 0;
601 nY = 1;
603 else if (nCode == KEY_LEFT)
605 // scroll left
606 nX =-1;
607 nY = 0;
609 else if (nCode == KEY_RIGHT)
611 // scroll right
612 nX = 1;
613 nY = 0;
616 if (mpView->AreObjectsMarked() && !rKEvt.GetKeyCode().IsMod1() &&
617 !mpDocSh->IsReadOnly())
619 const SdrHdlList& rHdlList = mpView->GetHdlList();
620 SdrHdl* pHdl = rHdlList.GetFocusHdl();
622 bool bIsMoveOfConnectedHandle(false);
623 bool bOldSuppress = false;
624 SdrEdgeObj* pEdgeObj = nullptr;
626 if(pHdl && pHdl->GetObj() && nullptr != dynamic_cast< const SdrEdgeObj *>( pHdl->GetObj() ) && 0 == pHdl->GetPolyNum())
628 pEdgeObj = static_cast<SdrEdgeObj*>(pHdl->GetObj());
630 if(0 == pHdl->GetPointNum())
632 if(pEdgeObj->GetConnection(true).GetObject())
634 bIsMoveOfConnectedHandle = true;
637 if(1 == pHdl->GetPointNum())
639 if(pEdgeObj->GetConnection(false).GetObject())
641 bIsMoveOfConnectedHandle = true;
646 if(pEdgeObj)
648 // Suppress default connects to inside object and object center
649 bOldSuppress = pEdgeObj->GetSuppressDefaultConnect();
650 pEdgeObj->SetSuppressDefaultConnect(true);
653 if(bIsMoveOfConnectedHandle)
655 sal_uInt16 nMarkHdSiz(mpView->GetMarkHdlSizePixel());
656 Size aHalfConSiz(nMarkHdSiz + 1, nMarkHdSiz + 1);
657 aHalfConSiz = mpWindow->PixelToLogic(aHalfConSiz);
659 if(100 < aHalfConSiz.Width())
660 nX *= aHalfConSiz.Width();
661 else
662 nX *= 100;
664 if(100 < aHalfConSiz.Height())
665 nY *= aHalfConSiz.Height();
666 else
667 nY *= 100;
669 else if(rKEvt.GetKeyCode().IsMod2())
671 // move in 1 pixel distance
672 Size aLogicSizeOnePixel = mpWindow->PixelToLogic(Size(1,1));
673 nX *= aLogicSizeOnePixel.Width();
674 nY *= aLogicSizeOnePixel.Height();
676 else if(rKEvt.GetKeyCode().IsShift())
678 nX *= 1000;
679 nY *= 1000;
681 else
683 // old, fixed move distance
684 nX *= 100;
685 nY *= 100;
688 if(nullptr == pHdl)
690 // only take action when move is allowed
691 if(mpView->IsMoveAllowed())
693 // restrict movement to WorkArea
694 const ::tools::Rectangle& rWorkArea = mpView->GetWorkArea();
696 if(!rWorkArea.IsEmpty())
698 ::tools::Rectangle aMarkRect(mpView->GetMarkedObjRect());
699 aMarkRect.Move(nX, nY);
701 if(!aMarkRect.IsInside(rWorkArea))
703 if(aMarkRect.Left() < rWorkArea.Left())
705 nX += rWorkArea.Left() - aMarkRect.Left();
708 if(aMarkRect.Right() > rWorkArea.Right())
710 nX -= aMarkRect.Right() - rWorkArea.Right();
713 if(aMarkRect.Top() < rWorkArea.Top())
715 nY += rWorkArea.Top() - aMarkRect.Top();
718 if(aMarkRect.Bottom() > rWorkArea.Bottom())
720 nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
725 // no handle selected
726 if(0 != nX || 0 != nY)
728 mpView->MoveAllMarked(Size(nX, nY));
730 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
734 else
736 // move handle with index nHandleIndex
737 if(pHdl && (nX || nY))
739 // now move the Handle (nX, nY)
740 Point aStartPoint(pHdl->GetPos());
741 Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
742 const SdrDragStat& rDragStat = mpView->GetDragStat();
744 // start dragging
745 mpView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
747 if(mpView->IsDragObj())
749 bool bWasNoSnap = rDragStat.IsNoSnap();
750 bool bWasSnapEnabled = mpView->IsSnapEnabled();
752 // switch snapping off
753 if(!bWasNoSnap)
754 const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
755 if(bWasSnapEnabled)
756 mpView->SetSnapEnabled(false);
758 mpView->MovAction(aEndPoint);
759 mpView->EndDragObj();
761 // restore snap
762 if(!bWasNoSnap)
763 const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
764 if(bWasSnapEnabled)
765 mpView->SetSnapEnabled(bWasSnapEnabled);
768 // make moved handle visible
769 ::tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
770 mpView->MakeVisible(aVisRect, *mpWindow);
774 if(pEdgeObj)
776 // Restore original suppress value
777 pEdgeObj->SetSuppressDefaultConnect(bOldSuppress);
780 else
782 // scroll page
783 mpViewShell->ScrollLines(nX, nY);
786 bReturn = true;
789 break;
792 if (bReturn)
794 mpWindow->ReleaseMouse();
797 // when a text-editable object is selected and the
798 // input character is printable, activate text edit on that object
799 // and feed character to object
800 if(!bReturn && !mpDocSh->IsReadOnly())
802 if (!mpView->IsTextEdit())
804 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
806 if(1 == rMarkList.GetMarkCount())
808 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
810 // #i118485# allow TextInput for OLEs, too
811 if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr && pObj->HasTextEdit())
813 // use common IsSimpleCharInput from the EditEngine.
814 bool bPrintable(EditEngine::IsSimpleCharInput(rKEvt));
816 if(bPrintable)
818 // try to activate textedit mode for the selected object
819 SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode()));
821 mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(
822 SID_ATTR_CHAR,
823 SfxCallMode::ASYNCHRON,
824 { &aInputString });
826 // consumed
827 bReturn = true;
831 else
833 // test if there is a title object there. If yes, try to
834 // set it to edit mode and start typing...
835 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell);
836 if (pDrawViewShell && EditEngine::IsSimpleCharInput(rKEvt))
838 SdPage* pActualPage = pDrawViewShell->GetActualPage();
839 SdrTextObj* pCandidate = nullptr;
841 if(pActualPage)
843 SdrObjListIter aIter(*pActualPage, SdrIterMode::DeepNoGroups);
845 while(aIter.IsMore() && !pCandidate)
847 SdrObject* pObj = aIter.Next();
849 if(pObj && dynamic_cast< const SdrTextObj *>( pObj ) != nullptr)
851 SdrInventor nInv(pObj->GetObjInventor());
852 sal_uInt16 nKnd(pObj->GetObjIdentifier());
854 if(SdrInventor::Default == nInv && OBJ_TITLETEXT == nKnd)
856 pCandidate = static_cast<SdrTextObj*>(pObj);
862 // when candidate found and candidate is untouched, start editing text...
863 if(pCandidate && pCandidate->IsEmptyPresObj())
865 mpView->UnMarkAll();
866 mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
867 SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode()));
869 mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(
870 SID_ATTR_CHAR,
871 SfxCallMode::ASYNCHRON,
872 { &aInputString });
874 // consumed
875 bReturn = true;
882 return bReturn;
885 bool FuPoor::MouseMove(const MouseEvent& )
887 return false;
890 void FuPoor::SelectionHasChanged()
892 const SdrHdlList& rHdlList = mpView->GetHdlList();
893 const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl();
897 * Cut object to clipboard
899 void FuPoor::DoCut()
901 if (mpView)
903 mpView->DoCut();
908 * Copy object to clipboard
910 void FuPoor::DoCopy()
912 if (mpView)
914 mpView->DoCopy();
919 * Paste object from clipboard
921 void FuPoor::DoPaste()
923 if (mpView)
925 mpView->DoPaste(mpWindow);
930 * Paste unformatted text from clipboard
932 void FuPoor::DoPasteUnformatted()
934 if (mpView)
936 sal_Int8 nAction = DND_ACTION_COPY;
937 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewShell->GetActiveWindow() ) );
938 if (aDataHelper.GetTransferable().is())
940 mpView->InsertData( aDataHelper,
941 mpWindow->PixelToLogic( ::tools::Rectangle( Point(), mpWindow->GetOutputSizePixel() ).Center() ),
942 nAction, false, SotClipboardFormatId::STRING);
948 * Timer handler for Drag&Drop
950 IMPL_LINK_NOARG(FuPoor, DragHdl, Timer *, void)
952 if( mpView )
954 sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
955 SdrHdl* pHdl = mpView->PickHandle(aMDPos);
957 if ( pHdl==nullptr && mpView->IsMarkedHit(aMDPos, nHitLog)
958 && !mpView->IsPresObjSelected(false) )
960 mpWindow->ReleaseMouse();
961 bIsInDragMode = true;
962 mpView->StartDrag( aMDPos, mpWindow );
967 bool FuPoor::Command(const CommandEvent& rCEvt)
969 return mpView->Command(rCEvt,mpWindow);
973 * Timer handler for window scrolling
975 IMPL_LINK_NOARG(FuPoor, DelayHdl, Timer *, void)
977 aDelayToScrollTimer.Stop ();
978 bScrollable = true;
980 Point aPnt(mpWindow->GetPointerPosPixel());
982 // use remembered MouseButton state to create correct
983 // MouseEvents for this artificial MouseMove.
984 MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
987 bool FuPoor::MouseButtonUp (const MouseEvent& rMEvt)
989 // remember button state for creation of own MouseEvents
990 SetMouseButtonCode(rMEvt.GetButtons());
992 aDelayToScrollTimer.Stop ();
993 return bScrollable =
994 bDelayActive = false;
997 bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
999 // remember button state for creation of own MouseEvents
1000 SetMouseButtonCode(rMEvt.GetButtons());
1002 return false;
1005 void FuPoor::StartDelayToScrollTimer ()
1007 bDelayActive = true;
1008 aDelayToScrollTimer.Start ();
1011 bool FuPoor::RequestHelp(const HelpEvent& rHEvt)
1013 bool bReturn = false;
1015 SdrPageView* pPV = mpView->GetSdrPageView();
1017 if (pPV)
1019 SdPage* pPage = static_cast<SdPage*>( pPV->GetPage() );
1021 if (pPage)
1023 bReturn = FmFormPage::RequestHelp(mpWindow, mpView, rHEvt);
1027 return bReturn;
1030 void FuPoor::ReceiveRequest(SfxRequest& /*rReq*/)
1034 SdrObject* FuPoor::CreateDefaultObject(const sal_uInt16, const ::tools::Rectangle& )
1036 // empty base implementation
1037 return nullptr;
1040 void FuPoor::ImpForceQuadratic(::tools::Rectangle& rRect)
1042 if(rRect.GetWidth() > rRect.GetHeight())
1044 rRect = ::tools::Rectangle(
1045 Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
1046 Size(rRect.GetHeight(), rRect.GetHeight()));
1048 else
1050 rRect = ::tools::Rectangle(
1051 Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
1052 Size(rRect.GetWidth(), rRect.GetWidth()));
1056 void FuPoor::SwitchLayer (sal_Int32 nOffset)
1058 if(mpViewShell && dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
1060 DrawViewShell* pDrawViewShell =
1061 static_cast<DrawViewShell*>(mpViewShell);
1063 // Calculate the new index.
1064 sal_Int32 nIndex = pDrawViewShell->GetActiveTabLayerIndex() + nOffset;
1066 // Make sure the new index lies inside the range of valid indices.
1067 if (nIndex < 0)
1068 nIndex = 0;
1069 else if (nIndex >= pDrawViewShell->GetTabLayerCount ())
1070 nIndex = pDrawViewShell->GetTabLayerCount() - 1;
1072 // Set the new active layer.
1073 if (nIndex != pDrawViewShell->GetActiveTabLayerIndex ())
1075 LayerTabBar* pLayerTabControl =
1076 static_cast<DrawViewShell*>(mpViewShell)->GetLayerTabControl();
1077 if (pLayerTabControl != nullptr)
1078 pLayerTabControl->SendDeactivatePageEvent ();
1080 pDrawViewShell->SetActiveTabLayerIndex (nIndex);
1082 if (pLayerTabControl != nullptr)
1083 pLayerTabControl->SendActivatePageEvent ();
1088 /** is called when the current function should be aborted. <p>
1089 This is used when a function gets a KEY_ESCAPE but can also
1090 be called directly.
1092 @returns true if a active function was aborted
1094 bool FuPoor::cancel()
1096 if ( dynamic_cast< const FuSelection *>( this ) == nullptr )
1098 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
1099 return true;
1102 return false;
1105 // #i33136#
1106 bool FuPoor::doConstructOrthogonal() const
1108 // Check whether a media object is selected
1109 bool bResizeKeepRatio = false;
1110 // tdf#89758 Avoid interactive crop preview from being proportionally scaled by default.
1111 if (mpView->AreObjectsMarked() && mpView->GetDragMode() != SdrDragMode::Crop)
1113 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1114 if (rMarkList.GetMarkCount() == 1)
1116 sal_uInt16 aObjIdentifier = rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier();
1117 bResizeKeepRatio = aObjIdentifier == OBJ_GRAF ||
1118 aObjIdentifier == OBJ_MEDIA ||
1119 aObjIdentifier == OBJ_OLE2;
1122 SdrHdl* pHdl = mpView->PickHandle(aMDPos);
1123 // Resize proportionally when media is selected and the user drags on a corner
1124 if (pHdl)
1125 bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl();
1127 return (
1128 bResizeKeepRatio ||
1129 SID_DRAW_XLINE == nSlotId ||
1130 SID_DRAW_CIRCLEARC == nSlotId ||
1131 SID_DRAW_SQUARE == nSlotId ||
1132 SID_DRAW_SQUARE_NOFILL == nSlotId ||
1133 SID_DRAW_SQUARE_ROUND == nSlotId ||
1134 SID_DRAW_SQUARE_ROUND_NOFILL == nSlotId ||
1135 SID_DRAW_CIRCLE == nSlotId ||
1136 SID_DRAW_CIRCLE_NOFILL == nSlotId ||
1137 SID_DRAW_CIRCLEPIE == nSlotId ||
1138 SID_DRAW_CIRCLEPIE_NOFILL == nSlotId ||
1139 SID_DRAW_CIRCLECUT == nSlotId ||
1140 SID_DRAW_CIRCLECUT_NOFILL == nSlotId ||
1141 SID_DRAW_XPOLYGON == nSlotId ||
1142 SID_DRAW_XPOLYGON_NOFILL == nSlotId ||
1143 SID_3D_CUBE == nSlotId ||
1144 SID_3D_SPHERE == nSlotId ||
1145 SID_3D_SHELL == nSlotId ||
1146 SID_3D_HALF_SPHERE == nSlotId ||
1147 SID_3D_TORUS == nSlotId ||
1148 SID_3D_CYLINDER == nSlotId ||
1149 SID_3D_CONE == nSlotId ||
1150 SID_3D_PYRAMID == nSlotId);
1153 void FuPoor::DoExecute( SfxRequest& )
1157 } // end of namespace sd
1159 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */