bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sd / source / ui / func / fupoor.cxx
blobda06f2add3578392d967550217a322e8d3097146
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 <svx/svdpagv.hxx>
24 #include <svx/svdoole2.hxx>
25 #include <svx/svdograf.hxx>
26 #include <vcl/seleng.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/request.hxx>
30 #include <svl/stritem.hxx>
32 #include <app.hrc>
33 #include <fusel.hxx>
34 #include <sdpage.hxx>
35 #include <DrawViewShell.hxx>
36 #include <Window.hxx>
37 #include <drawdoc.hxx>
38 #include <DrawDocShell.hxx>
39 #include <zoomlist.hxx>
40 #include <slideshow.hxx>
41 #include <LayerTabBar.hxx>
43 #include <sfx2/viewfrm.hxx>
45 #include <svx/svditer.hxx>
47 #include <editeng/editeng.hxx>
49 using namespace ::com::sun::star;
51 namespace sd {
54 FuPoor::FuPoor (
55 ViewShell* pViewSh,
56 ::sd::Window* pWin,
57 ::sd::View* pView,
58 SdDrawDocument* pDrDoc,
59 SfxRequest& rReq)
60 : mpView(pView),
61 mpViewShell(pViewSh),
62 mpWindow(pWin),
63 mpDocSh( pDrDoc->GetDocSh() ),
64 mpDoc(pDrDoc),
65 nSlotId( rReq.GetSlot() ),
66 bIsInDragMode(false),
67 bNoScrollUntilInside (true),
68 bScrollable (false),
69 bDelayActive (false),
70 bFirstMouseMove (false),
71 // remember MouseButton state
72 mnCode(0)
74 ReceiveRequest(rReq);
76 aScrollTimer.SetInvokeHandler( LINK(this, FuPoor, ScrollHdl) );
77 aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
79 aDragTimer.SetInvokeHandler( LINK(this, FuPoor, DragHdl) );
80 aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
82 aDelayToScrollTimer.SetInvokeHandler( LINK(this, FuPoor, DelayHdl) );
83 aDelayToScrollTimer.SetTimeout(2000);
86 FuPoor::~FuPoor()
88 aDragTimer.Stop();
89 aScrollTimer.Stop();
90 aDelayToScrollTimer.Stop();
93 void FuPoor::Activate()
97 void FuPoor::Deactivate()
99 aDragTimer.Stop();
100 aScrollTimer.Stop();
101 aDelayToScrollTimer.Stop ();
102 bScrollable = bDelayActive = false;
104 if (mpWindow && mpWindow->IsMouseCaptured())
105 mpWindow->ReleaseMouse();
108 void FuPoor::SetWindow(::sd::Window* pWin)
110 mpWindow = pWin;
114 * scroll when approached the border of the window; is called by MouseMove
116 void FuPoor::ForceScroll(const Point& aPixPos)
118 aScrollTimer.Stop();
120 if ( mpView->IsDragHelpLine() || mpView->IsSetPageOrg() ||
121 SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) )
122 return;
124 Point aPos = mpWindow->OutputToScreenPixel(aPixPos);
125 const ::tools::Rectangle& rRect = mpViewShell->GetAllWindowRect();
127 if ( bNoScrollUntilInside )
129 if ( rRect.IsInside(aPos) )
130 bNoScrollUntilInside = false;
132 else
134 short dx = 0, dy = 0;
136 if ( aPos.X() <= rRect.Left() ) dx = -1;
137 if ( aPos.X() >= rRect.Right() ) dx = 1;
138 if ( aPos.Y() <= rRect.Top() ) dy = -1;
139 if ( aPos.Y() >= rRect.Bottom() ) dy = 1;
141 if ( dx != 0 || dy != 0 )
143 if (bScrollable)
145 // scroll action in derived class
146 mpViewShell->ScrollLines(dx, dy);
147 aScrollTimer.Start();
149 else if (! bDelayActive) StartDelayToScrollTimer ();
155 * timer handler for window scrolling
157 IMPL_LINK_NOARG(FuPoor, ScrollHdl, Timer *, void)
159 Point aPnt(mpWindow->GetPointerPosPixel());
161 // use remembered MouseButton state to create correct
162 // MouseEvents for this artificial MouseMove.
163 MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
167 * handle keyboard events
168 * @returns sal_True if the event was handled, sal_False otherwise
170 bool FuPoor::KeyInput(const KeyEvent& rKEvt)
172 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
173 bool bReturn = false;
174 bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() );
176 switch (nCode)
178 case KEY_RETURN:
180 if(rKEvt.GetKeyCode().IsMod1())
182 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
184 DrawViewShell* pDrawViewShell =
185 static_cast<DrawViewShell*>(mpViewShell);
186 SdPage* pActualPage = pDrawViewShell->GetActualPage();
187 SdrTextObj* pCandidate = nullptr;
189 if(pActualPage)
191 SdrObjListIter aIter(pActualPage, SdrIterMode::DeepNoGroups);
193 while(aIter.IsMore() && !pCandidate)
195 SdrObject* pObj = aIter.Next();
197 if(dynamic_cast< const SdrTextObj *>( pObj ))
199 SdrInventor nInv(pObj->GetObjInventor());
200 sal_uInt16 nKnd(pObj->GetObjIdentifier());
202 if(SdrInventor::Default == nInv &&
203 (OBJ_TITLETEXT == nKnd || OBJ_OUTLINETEXT == nKnd || OBJ_TEXT == nKnd))
205 pCandidate = static_cast<SdrTextObj*>(pObj);
211 if(pCandidate)
213 mpView->UnMarkAll();
214 mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
216 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
217 SID_ATTR_CHAR, SfxCallMode::ASYNCHRON);
219 else
221 // insert a new page with the same page layout
222 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
223 SID_INSERTPAGE_QUICK, SfxCallMode::ASYNCHRON);
226 // consumed
227 bReturn = true;
230 else
232 // activate OLE object on RETURN for selected object
233 // activate text edit on RETURN for selected object
234 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
236 if( !mpView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
238 SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
240 if( dynamic_cast< const SdrOle2Obj* >( pObj ) && !mpDocSh->IsUIActive() )
242 //HMHmpView->HideMarkHdl();
243 mpViewShell->ActivateObject( static_cast< SdrOle2Obj* >( pObj ), 0 );
245 else if( pObj && pObj->IsEmptyPresObj() && dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr )
247 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_GRAPHIC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
249 else
251 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_ATTR_CHAR, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
254 // consumed
255 bReturn = true;
259 break;
261 case KEY_TAB:
263 // handle Mod1 and Mod2 to get travelling running on different systems
264 if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
266 // do something with a selected handle?
267 const SdrHdlList& rHdlList = mpView->GetHdlList();
268 bool bForward(!rKEvt.GetKeyCode().IsShift());
270 const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
272 // guarantee visibility of focused handle
273 SdrHdl* pHdl = rHdlList.GetFocusHdl();
275 if(pHdl)
277 Point aHdlPosition(pHdl->GetPos());
278 ::tools::Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
279 mpView->MakeVisible(aVisRect, *mpWindow);
282 // consumed
283 bReturn = true;
286 break;
288 case KEY_ESCAPE:
290 bReturn = FuPoor::cancel();
292 break;
294 case KEY_ADD:
296 if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
298 // increase zoom
299 mpViewShell->SetZoom(mpWindow->GetZoom() * 3 / 2);
301 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
302 static_cast<DrawViewShell*>(mpViewShell)
303 ->SetZoomOnPage(false);
305 bReturn = true;
308 break;
310 case KEY_SUBTRACT:
312 if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
314 // decrease zoom
315 mpViewShell->SetZoom(mpWindow->GetZoom() * 2 / 3);
317 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr)
318 static_cast<DrawViewShell*>(mpViewShell)
319 ->SetZoomOnPage(false);
321 bReturn = true;
324 break;
326 case KEY_MULTIPLY:
328 if (!mpView->IsTextEdit() && !bSlideShow)
330 // zoom to page
331 mpViewShell->GetViewFrame()->GetDispatcher()->
332 Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
333 bReturn = true;
336 break;
338 case KEY_DIVIDE:
340 if (!mpView->IsTextEdit() && !bSlideShow)
342 // zoom to selected objects
343 mpViewShell->GetViewFrame()->GetDispatcher()->
344 Execute(SID_SIZE_OPTIMAL, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
345 bReturn = true;
348 break;
350 case KEY_POINT:
352 ZoomList* pZoomList = mpViewShell->GetZoomList();
354 if (!mpView->IsTextEdit() && pZoomList->IsNextPossible() && !bSlideShow && !mpDocSh->IsUIActive())
356 // use next ZoomRect
357 mpViewShell->SetZoomRect(pZoomList->GetNextZoomRect());
358 bReturn = true;
361 break;
363 case KEY_COMMA:
365 ZoomList* pZoomList = mpViewShell->GetZoomList();
367 if (!mpView->IsTextEdit() && pZoomList->IsPreviousPossible() && !bSlideShow && !mpDocSh->IsUIActive())
369 // use previous ZoomRect
370 mpViewShell->SetZoomRect(pZoomList->GetPreviousZoomRect());
371 bReturn = true;
374 break;
376 case KEY_HOME:
378 if (!mpView->IsTextEdit()
379 && dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr
380 && !bSlideShow)
382 // jump to first page
383 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(0);
384 bReturn = true;
387 break;
389 case KEY_END:
391 if (!mpView->IsTextEdit()
392 && dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr
393 && !bSlideShow)
395 // jump to last page
396 SdPage* pPage =
397 static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
398 static_cast<DrawViewShell*>(mpViewShell)
399 ->SwitchPage(mpDoc->GetSdPageCount(
400 pPage->GetPageKind()) - 1);
401 bReturn = true;
404 break;
406 case KEY_PAGEUP:
408 if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
409 break;
411 if( dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr && !bSlideShow)
413 // The page-up key switches layers or pages depending on the
414 // modifier key.
415 if ( ! rKEvt.GetKeyCode().GetModifier())
417 // With no modifier pressed we move to the previous
418 // slide.
419 mpView->SdrEndTextEdit();
421 // Previous page.
422 bReturn = true;
423 SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
424 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
426 if (nSdPage > 0)
428 // Switch the page and send events regarding
429 // deactivation the old page and activating the new
430 // one.
431 TabControl& rPageTabControl =
432 static_cast<DrawViewShell*>(mpViewShell)
433 ->GetPageTabControl();
434 if (rPageTabControl.IsReallyShown())
435 rPageTabControl.SendDeactivatePageEvent ();
436 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage - 1);
437 if (rPageTabControl.IsReallyShown())
438 rPageTabControl.SendActivatePageEvent ();
441 else if (rKEvt.GetKeyCode().IsMod1())
443 // With the CONTROL modifier we switch layers.
444 if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
446 // Moves to the previous layer.
447 SwitchLayer (-1);
452 break;
454 case KEY_PAGEDOWN:
456 if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
457 break;
458 if(dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr && !bSlideShow)
460 // The page-down key switches layers or pages depending on the
461 // modifier key.
462 if ( ! rKEvt.GetKeyCode().GetModifier())
464 // With no modifier pressed we move to the next slide.
465 mpView->SdrEndTextEdit();
467 // Next page.
468 bReturn = true;
469 SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
470 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
472 if (nSdPage < mpDoc->GetSdPageCount(pPage->GetPageKind()) - 1)
474 // Switch the page and send events regarding
475 // deactivation the old page and activating the new
476 // one.
477 TabControl& rPageTabControl =
478 static_cast<DrawViewShell*>(mpViewShell)->GetPageTabControl();
479 if (rPageTabControl.IsReallyShown())
480 rPageTabControl.SendDeactivatePageEvent ();
481 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage + 1);
482 if (rPageTabControl.IsReallyShown())
483 rPageTabControl.SendActivatePageEvent ();
486 else if (rKEvt.GetKeyCode().IsMod1())
488 // With the CONTROL modifier we switch layers.
489 if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
491 // With the layer mode active pressing page-down
492 // moves to the next layer.
493 SwitchLayer (+1);
498 break;
500 // change select state when focus is on poly point
501 case KEY_SPACE:
503 const SdrHdlList& rHdlList = mpView->GetHdlList();
504 SdrHdl* pHdl = rHdlList.GetFocusHdl();
506 if(pHdl)
508 if(pHdl->GetKind() == SdrHdlKind::Poly)
510 // rescue ID of point with focus
511 sal_uInt32 nPol(pHdl->GetPolyNum());
512 sal_uInt32 nPnt(pHdl->GetPointNum());
514 if(mpView->IsPointMarked(*pHdl))
516 if(rKEvt.GetKeyCode().IsShift())
518 mpView->UnmarkPoint(*pHdl);
521 else
523 if(!rKEvt.GetKeyCode().IsShift())
525 mpView->UnmarkAllPoints();
528 mpView->MarkPoint(*pHdl);
531 if(nullptr == rHdlList.GetFocusHdl())
533 // restore point with focus
534 SdrHdl* pNewOne = nullptr;
536 for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a)
538 SdrHdl* pAct = rHdlList.GetHdl(a);
540 if(pAct
541 && pAct->GetKind() == SdrHdlKind::Poly
542 && pAct->GetPolyNum() == nPol
543 && pAct->GetPointNum() == nPnt)
545 pNewOne = pAct;
549 if(pNewOne)
551 const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne);
555 bReturn = true;
559 break;
561 case KEY_UP:
562 case KEY_DOWN:
563 case KEY_LEFT:
564 case KEY_RIGHT:
566 if (!mpView->IsTextEdit() && !bSlideShow)
568 long nX = 0;
569 long nY = 0;
571 if (nCode == KEY_UP)
573 // scroll up
574 nX = 0;
575 nY =-1;
577 else if (nCode == KEY_DOWN)
579 // scroll down
580 nX = 0;
581 nY = 1;
583 else if (nCode == KEY_LEFT)
585 // scroll left
586 nX =-1;
587 nY = 0;
589 else if (nCode == KEY_RIGHT)
591 // scroll right
592 nX = 1;
593 nY = 0;
596 if (mpView->AreObjectsMarked() && !rKEvt.GetKeyCode().IsMod1() &&
597 !mpDocSh->IsReadOnly())
599 const SdrHdlList& rHdlList = mpView->GetHdlList();
600 SdrHdl* pHdl = rHdlList.GetFocusHdl();
602 bool bIsMoveOfConnectedHandle(false);
603 bool bOldSuppress = false;
604 SdrEdgeObj* pEdgeObj = nullptr;
606 if(pHdl && dynamic_cast< const SdrEdgeObj *>( pHdl->GetObj() ) && 0 == pHdl->GetPolyNum())
608 pEdgeObj = static_cast<SdrEdgeObj*>(pHdl->GetObj());
610 if(0 == pHdl->GetPointNum())
612 if(pEdgeObj->GetConnection(true).GetObject())
614 bIsMoveOfConnectedHandle = true;
617 if(1 == pHdl->GetPointNum())
619 if(pEdgeObj->GetConnection(false).GetObject())
621 bIsMoveOfConnectedHandle = true;
626 if(pEdgeObj)
628 // Suppress default connects to inside object and object center
629 bOldSuppress = pEdgeObj->GetSuppressDefaultConnect();
630 pEdgeObj->SetSuppressDefaultConnect(true);
633 if(bIsMoveOfConnectedHandle)
635 sal_uInt16 nMarkHdSiz(mpView->GetMarkHdlSizePixel());
636 Size aHalfConSiz(nMarkHdSiz + 1, nMarkHdSiz + 1);
637 aHalfConSiz = mpWindow->PixelToLogic(aHalfConSiz);
639 if(100 < aHalfConSiz.Width())
640 nX *= aHalfConSiz.Width();
641 else
642 nX *= 100;
644 if(100 < aHalfConSiz.Height())
645 nY *= aHalfConSiz.Height();
646 else
647 nY *= 100;
649 else if(rKEvt.GetKeyCode().IsMod2())
651 // move in 1 pixel distance
652 Size aLogicSizeOnePixel = mpWindow->PixelToLogic(Size(1,1));
653 nX *= aLogicSizeOnePixel.Width();
654 nY *= aLogicSizeOnePixel.Height();
656 else if(rKEvt.GetKeyCode().IsShift())
658 nX *= 1000;
659 nY *= 1000;
661 else
663 // old, fixed move distance
664 nX *= 100;
665 nY *= 100;
668 if(nullptr == pHdl)
670 // only take action when move is allowed
671 if(mpView->IsMoveAllowed())
673 // restrict movement to WorkArea
674 const ::tools::Rectangle& rWorkArea = mpView->GetWorkArea();
676 if(!rWorkArea.IsEmpty())
678 ::tools::Rectangle aMarkRect(mpView->GetMarkedObjRect());
679 aMarkRect.Move(nX, nY);
681 if(!aMarkRect.IsInside(rWorkArea))
683 if(aMarkRect.Left() < rWorkArea.Left())
685 nX += rWorkArea.Left() - aMarkRect.Left();
688 if(aMarkRect.Right() > rWorkArea.Right())
690 nX -= aMarkRect.Right() - rWorkArea.Right();
693 if(aMarkRect.Top() < rWorkArea.Top())
695 nY += rWorkArea.Top() - aMarkRect.Top();
698 if(aMarkRect.Bottom() > rWorkArea.Bottom())
700 nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
705 // no handle selected
706 if(0 != nX || 0 != nY)
708 mpView->MoveAllMarked(Size(nX, nY));
710 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
714 else
716 // move handle with index nHandleIndex
717 if (nX || nY)
719 // now move the Handle (nX, nY)
720 Point aStartPoint(pHdl->GetPos());
721 Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
722 const SdrDragStat& rDragStat = mpView->GetDragStat();
724 // start dragging
725 mpView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
727 if(mpView->IsDragObj())
729 bool bWasNoSnap = rDragStat.IsNoSnap();
730 bool bWasSnapEnabled = mpView->IsSnapEnabled();
732 // switch snapping off
733 if(!bWasNoSnap)
734 const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
735 if(bWasSnapEnabled)
736 mpView->SetSnapEnabled(false);
738 mpView->MovAction(aEndPoint);
739 mpView->EndDragObj();
741 // restore snap
742 if(!bWasNoSnap)
743 const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
744 if(bWasSnapEnabled)
745 mpView->SetSnapEnabled(bWasSnapEnabled);
748 // make moved handle visible
749 ::tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
750 mpView->MakeVisible(aVisRect, *mpWindow);
754 if(pEdgeObj)
756 // Restore original suppress value
757 pEdgeObj->SetSuppressDefaultConnect(bOldSuppress);
760 else
762 // scroll page
763 mpViewShell->ScrollLines(nX, nY);
766 bReturn = true;
769 break;
772 if (bReturn)
774 mpWindow->ReleaseMouse();
777 // when a text-editable object is selected and the
778 // input character is printable, activate text edit on that object
779 // and feed character to object
780 if(!bReturn && !mpDocSh->IsReadOnly())
782 if (!mpView->IsTextEdit())
784 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
786 if(1 == rMarkList.GetMarkCount())
788 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
790 // #i118485# allow TextInput for OLEs, too
791 if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr && pObj->HasTextEdit())
793 // use common IsSimpleCharInput from the EditEngine.
794 bool bPrintable(EditEngine::IsSimpleCharInput(rKEvt));
796 if(bPrintable)
798 // try to activate textedit mode for the selected object
799 SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode()));
801 mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(
802 SID_ATTR_CHAR,
803 SfxCallMode::ASYNCHRON,
804 { &aInputString });
806 // consumed
807 bReturn = true;
811 else
813 // test if there is a title object there. If yes, try to
814 // set it to edit mode and start typing...
815 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell);
816 if (pDrawViewShell && EditEngine::IsSimpleCharInput(rKEvt))
818 SdPage* pActualPage = pDrawViewShell->GetActualPage();
819 SdrTextObj* pCandidate = nullptr;
821 if(pActualPage)
823 SdrObjListIter aIter(pActualPage, SdrIterMode::DeepNoGroups);
825 while(aIter.IsMore() && !pCandidate)
827 SdrObject* pObj = aIter.Next();
829 if(dynamic_cast< const SdrTextObj *>( pObj ))
831 SdrInventor nInv(pObj->GetObjInventor());
832 sal_uInt16 nKnd(pObj->GetObjIdentifier());
834 if(SdrInventor::Default == nInv && OBJ_TITLETEXT == nKnd)
836 pCandidate = static_cast<SdrTextObj*>(pObj);
842 // when candidate found and candidate is untouched, start editing text...
843 if(pCandidate && pCandidate->IsEmptyPresObj())
845 mpView->UnMarkAll();
846 mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
847 SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode()));
849 mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(
850 SID_ATTR_CHAR,
851 SfxCallMode::ASYNCHRON,
852 { &aInputString });
854 // consumed
855 bReturn = true;
862 return bReturn;
865 bool FuPoor::MouseMove(const MouseEvent& )
867 return false;
870 void FuPoor::SelectionHasChanged()
872 const SdrHdlList& rHdlList = mpView->GetHdlList();
873 const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl();
877 * Cut object to clipboard
879 void FuPoor::DoCut()
881 if (mpView)
883 mpView->DoCut();
888 * Copy object to clipboard
890 void FuPoor::DoCopy()
892 if (mpView)
894 mpView->DoCopy();
899 * Paste object from clipboard
901 void FuPoor::DoPaste()
903 if (mpView)
905 mpView->DoPaste(mpWindow);
910 * Paste unformatted text from clipboard
912 void FuPoor::DoPasteUnformatted()
914 if (mpView)
916 sal_Int8 nAction = DND_ACTION_COPY;
917 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewShell->GetActiveWindow() ) );
918 if (aDataHelper.GetTransferable().is())
920 mpView->InsertData( aDataHelper,
921 mpWindow->PixelToLogic( ::tools::Rectangle( Point(), mpWindow->GetOutputSizePixel() ).Center() ),
922 nAction, false, SotClipboardFormatId::STRING);
928 * Timer handler for Drag&Drop
930 IMPL_LINK_NOARG(FuPoor, DragHdl, Timer *, void)
932 if( !mpView )
933 return;
935 sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
936 SdrHdl* pHdl = mpView->PickHandle(aMDPos);
938 if ( pHdl==nullptr && mpView->IsMarkedHit(aMDPos, nHitLog)
939 && !mpView->IsPresObjSelected(false) )
941 mpWindow->ReleaseMouse();
942 bIsInDragMode = true;
943 mpView->StartDrag( aMDPos, mpWindow );
947 bool FuPoor::Command(const CommandEvent& rCEvt)
949 return mpView->Command(rCEvt,mpWindow);
953 * Timer handler for window scrolling
955 IMPL_LINK_NOARG(FuPoor, DelayHdl, Timer *, void)
957 aDelayToScrollTimer.Stop ();
958 bScrollable = true;
960 Point aPnt(mpWindow->GetPointerPosPixel());
962 // use remembered MouseButton state to create correct
963 // MouseEvents for this artificial MouseMove.
964 MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
967 bool FuPoor::MouseButtonUp (const MouseEvent& rMEvt)
969 // remember button state for creation of own MouseEvents
970 SetMouseButtonCode(rMEvt.GetButtons());
972 aDelayToScrollTimer.Stop ();
973 return bScrollable =
974 bDelayActive = false;
977 bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
979 // remember button state for creation of own MouseEvents
980 SetMouseButtonCode(rMEvt.GetButtons());
982 return false;
985 void FuPoor::StartDelayToScrollTimer ()
987 bDelayActive = true;
988 aDelayToScrollTimer.Start ();
991 bool FuPoor::RequestHelp(const HelpEvent& rHEvt)
993 bool bReturn = false;
995 SdrPageView* pPV = mpView->GetSdrPageView();
997 if (pPV)
999 SdPage* pPage = static_cast<SdPage*>( pPV->GetPage() );
1001 if (pPage)
1003 bReturn = FmFormPage::RequestHelp(mpWindow, mpView, rHEvt);
1007 return bReturn;
1010 void FuPoor::ReceiveRequest(SfxRequest& /*rReq*/)
1014 SdrObjectUniquePtr FuPoor::CreateDefaultObject(const sal_uInt16, const ::tools::Rectangle& )
1016 // empty base implementation
1017 return nullptr;
1020 void FuPoor::ImpForceQuadratic(::tools::Rectangle& rRect)
1022 if(rRect.GetWidth() > rRect.GetHeight())
1024 rRect = ::tools::Rectangle(
1025 Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
1026 Size(rRect.GetHeight(), rRect.GetHeight()));
1028 else
1030 rRect = ::tools::Rectangle(
1031 Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
1032 Size(rRect.GetWidth(), rRect.GetWidth()));
1036 void FuPoor::SwitchLayer (sal_Int32 nOffset)
1038 auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell );
1039 if(!pDrawViewShell)
1040 return;
1042 // Calculate the new index.
1043 sal_Int32 nIndex = pDrawViewShell->GetActiveTabLayerIndex() + nOffset;
1045 // Make sure the new index lies inside the range of valid indices.
1046 if (nIndex < 0)
1047 nIndex = 0;
1048 else if (nIndex >= pDrawViewShell->GetTabLayerCount ())
1049 nIndex = pDrawViewShell->GetTabLayerCount() - 1;
1051 // Set the new active layer.
1052 if (nIndex != pDrawViewShell->GetActiveTabLayerIndex ())
1054 LayerTabBar* pLayerTabControl =
1055 static_cast<DrawViewShell*>(mpViewShell)->GetLayerTabControl();
1056 if (pLayerTabControl != nullptr)
1057 pLayerTabControl->SendDeactivatePageEvent ();
1059 pDrawViewShell->SetActiveTabLayerIndex (nIndex);
1061 if (pLayerTabControl != nullptr)
1062 pLayerTabControl->SendActivatePageEvent ();
1066 /** is called when the current function should be aborted. <p>
1067 This is used when a function gets a KEY_ESCAPE but can also
1068 be called directly.
1070 @returns true if a active function was aborted
1072 bool FuPoor::cancel()
1074 if ( dynamic_cast< const FuSelection *>( this ) == nullptr )
1076 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
1077 return true;
1080 return false;
1083 // #i33136#
1084 bool FuPoor::doConstructOrthogonal() const
1086 // Check whether a media object is selected
1087 bool bResizeKeepRatio = false;
1088 // tdf#89758 Avoid interactive crop preview from being proportionally scaled by default.
1089 if (mpView->AreObjectsMarked() && mpView->GetDragMode() != SdrDragMode::Crop)
1091 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1092 if (rMarkList.GetMarkCount() == 1)
1094 sal_uInt16 aObjIdentifier = rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier();
1095 bResizeKeepRatio = aObjIdentifier == OBJ_GRAF ||
1096 aObjIdentifier == OBJ_MEDIA ||
1097 aObjIdentifier == OBJ_OLE2;
1100 SdrHdl* pHdl = mpView->PickHandle(aMDPos);
1101 // Resize proportionally when media is selected and the user drags on a corner
1102 if (pHdl)
1103 bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl();
1105 return (
1106 bResizeKeepRatio ||
1107 SID_DRAW_XLINE == nSlotId ||
1108 SID_DRAW_CIRCLEARC == nSlotId ||
1109 SID_DRAW_SQUARE == nSlotId ||
1110 SID_DRAW_SQUARE_NOFILL == nSlotId ||
1111 SID_DRAW_SQUARE_ROUND == nSlotId ||
1112 SID_DRAW_SQUARE_ROUND_NOFILL == nSlotId ||
1113 SID_DRAW_CIRCLE == nSlotId ||
1114 SID_DRAW_CIRCLE_NOFILL == nSlotId ||
1115 SID_DRAW_CIRCLEPIE == nSlotId ||
1116 SID_DRAW_CIRCLEPIE_NOFILL == nSlotId ||
1117 SID_DRAW_CIRCLECUT == nSlotId ||
1118 SID_DRAW_CIRCLECUT_NOFILL == nSlotId ||
1119 SID_DRAW_XPOLYGON == nSlotId ||
1120 SID_DRAW_XPOLYGON_NOFILL == nSlotId ||
1121 SID_3D_CUBE == nSlotId ||
1122 SID_3D_SPHERE == nSlotId ||
1123 SID_3D_SHELL == nSlotId ||
1124 SID_3D_HALF_SPHERE == nSlotId ||
1125 SID_3D_TORUS == nSlotId ||
1126 SID_3D_CYLINDER == nSlotId ||
1127 SID_3D_CONE == nSlotId ||
1128 SID_3D_PYRAMID == nSlotId);
1131 void FuPoor::DoExecute( SfxRequest& )
1135 } // end of namespace sd
1137 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */