android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / func / fupoor.cxx
blobc75959fbc243808ecc4fcc41d31a286678162d3f
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 <com/sun/star/embed/EmbedVerbs.hpp>
45 #include <sfx2/viewfrm.hxx>
47 #include <svx/svditer.hxx>
49 #include <editeng/editeng.hxx>
51 using namespace ::com::sun::star;
53 namespace sd {
56 FuPoor::FuPoor (
57 ViewShell* pViewSh,
58 ::sd::Window* pWin,
59 ::sd::View* pView,
60 SdDrawDocument* pDrDoc,
61 SfxRequest& rReq)
62 : mpView(pView),
63 mpViewShell(pViewSh),
64 mpWindow(pWin),
65 mpDocSh( pDrDoc->GetDocSh() ),
66 mpDoc(pDrDoc),
67 nSlotId( rReq.GetSlot() ),
68 aScrollTimer("sd FuPoor aScrollTimer"),
69 aDragTimer("sd FuPoor aDragTimer"),
70 bIsInDragMode(false),
71 bNoScrollUntilInside (true),
72 aDelayToScrollTimer("sd FuPoor aDelayToScrollTimer"),
73 bScrollable (false),
74 bDelayActive (false),
75 bFirstMouseMove (false),
76 // remember MouseButton state
77 mnCode(0)
79 ReceiveRequest(rReq);
81 aScrollTimer.SetInvokeHandler( LINK(this, FuPoor, ScrollHdl) );
82 aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
84 aDragTimer.SetInvokeHandler( LINK(this, FuPoor, DragHdl) );
85 aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
87 aDelayToScrollTimer.SetInvokeHandler( LINK(this, FuPoor, DelayHdl) );
88 aDelayToScrollTimer.SetTimeout(2000);
91 FuPoor::~FuPoor()
93 aDragTimer.Stop();
94 aScrollTimer.Stop();
95 aDelayToScrollTimer.Stop();
98 void FuPoor::Activate()
102 void FuPoor::Deactivate()
104 aDragTimer.Stop();
105 aScrollTimer.Stop();
106 aDelayToScrollTimer.Stop ();
107 bScrollable = bDelayActive = false;
109 if (mpWindow && mpWindow->IsMouseCaptured())
110 mpWindow->ReleaseMouse();
113 void FuPoor::SetWindow(::sd::Window* pWin)
115 mpWindow = pWin;
119 * scroll when approached the border of the window; is called by MouseMove
121 void FuPoor::ForceScroll(const Point& aPixPos)
123 aScrollTimer.Stop();
125 if ( mpView->IsDragHelpLine() || mpView->IsSetPageOrg() ||
126 SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) )
127 return;
129 Point aPos = mpWindow->OutputToScreenPixel(aPixPos);
130 const ::tools::Rectangle& rRect = mpViewShell->GetAllWindowRect();
132 if ( bNoScrollUntilInside )
134 if ( rRect.Contains(aPos) )
135 bNoScrollUntilInside = false;
137 else
139 short dx = 0, dy = 0;
141 if ( aPos.X() <= rRect.Left() ) dx = -1;
142 if ( aPos.X() >= rRect.Right() ) dx = 1;
143 if ( aPos.Y() <= rRect.Top() ) dy = -1;
144 if ( aPos.Y() >= rRect.Bottom() ) dy = 1;
146 if ( dx != 0 || dy != 0 )
148 if (bScrollable)
150 // scroll action in derived class
151 mpViewShell->ScrollLines(dx, dy);
152 aScrollTimer.Start();
154 else if (! bDelayActive) StartDelayToScrollTimer ();
160 * timer handler for window scrolling
162 IMPL_LINK_NOARG(FuPoor, ScrollHdl, Timer *, void)
164 Point aPnt(mpWindow->GetPointerPosPixel());
166 // use remembered MouseButton state to create correct
167 // MouseEvents for this artificial MouseMove.
168 MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
172 * handle keyboard events
173 * @returns sal_True if the event was handled, sal_False otherwise
175 bool FuPoor::KeyInput(const KeyEvent& rKEvt)
177 sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
178 bool bReturn = false;
179 bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() );
181 switch (nCode)
183 case KEY_RETURN:
185 if(rKEvt.GetKeyCode().IsMod1())
187 if( auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ))
189 SdPage* pActualPage = pDrawViewShell->GetActualPage();
190 SdrTextObj* pCandidate = nullptr;
192 if(pActualPage)
194 SdrObjListIter aIter(pActualPage, SdrIterMode::DeepNoGroups);
196 while(aIter.IsMore() && !pCandidate)
198 SdrObject* pObj = aIter.Next();
200 if(auto pTextObj = DynCastSdrTextObj( pObj ))
202 SdrInventor nInv(pObj->GetObjInventor());
203 SdrObjKind nKnd(pObj->GetObjIdentifier());
205 if(SdrInventor::Default == nInv &&
206 (SdrObjKind::TitleText == nKnd || SdrObjKind::OutlineText == nKnd || SdrObjKind::Text == nKnd))
208 pCandidate = pTextObj;
214 if(pCandidate)
216 mpView->UnMarkAll();
217 mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
219 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
220 SID_ATTR_CHAR, SfxCallMode::ASYNCHRON);
222 else
224 // insert a new page with the same page layout
225 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
226 SID_INSERTPAGE_QUICK, SfxCallMode::ASYNCHRON);
229 // consumed
230 bReturn = true;
233 else
235 // activate OLE object on RETURN for selected object
236 // activate text edit on RETURN for selected object
237 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
239 if( !mpView->IsTextEdit() && 1 == rMarkList.GetMarkCount() )
241 SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
243 if( dynamic_cast< const SdrOle2Obj* >( pObj ) && !mpDocSh->IsUIActive() )
245 //HMHmpView->HideMarkHdl();
246 mpViewShell->ActivateObject(static_cast<SdrOle2Obj*>(pObj), css::embed::EmbedVerbs::MS_OLEVERB_PRIMARY);
248 else if( pObj && pObj->IsEmptyPresObj() && dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr )
250 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_GRAPHIC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
252 else
254 mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_ATTR_CHAR, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
257 // consumed
258 bReturn = true;
262 break;
264 case KEY_TAB:
266 // handle Mod1 and Mod2 to get travelling running on different systems
267 if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2())
269 // do something with a selected handle?
270 const SdrHdlList& rHdlList = mpView->GetHdlList();
271 bool bForward(!rKEvt.GetKeyCode().IsShift());
273 const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward);
275 // guarantee visibility of focused handle
276 SdrHdl* pHdl = rHdlList.GetFocusHdl();
278 if(pHdl)
280 Point aHdlPosition(pHdl->GetPos());
281 ::tools::Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200));
282 mpView->MakeVisible(aVisRect, *mpWindow);
285 // consumed
286 bReturn = true;
289 break;
291 case KEY_ESCAPE:
293 bReturn = FuPoor::cancel();
295 break;
297 case KEY_ADD:
299 if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
301 // increase zoom
302 mpViewShell->SetZoom(mpWindow->GetZoom() * 3 / 2);
304 if( auto pViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ))
305 pViewShell->SetZoomOnPage(false);
307 bReturn = true;
310 break;
312 case KEY_SUBTRACT:
314 if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive())
316 // decrease zoom
317 mpViewShell->SetZoom(mpWindow->GetZoom() * 2 / 3);
319 if( auto pViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ))
320 pViewShell->SetZoomOnPage(false);
322 bReturn = true;
325 break;
327 case KEY_MULTIPLY:
329 if (!mpView->IsTextEdit() && !bSlideShow)
331 // zoom to page
332 mpViewShell->GetViewFrame()->GetDispatcher()->
333 Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
334 bReturn = true;
337 break;
339 case KEY_DIVIDE:
341 if (!mpView->IsTextEdit() && !bSlideShow)
343 // zoom to selected objects
344 mpViewShell->GetViewFrame()->GetDispatcher()->
345 Execute(SID_SIZE_OPTIMAL, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
346 bReturn = true;
349 break;
351 case KEY_POINT:
353 ZoomList* pZoomList = mpViewShell->GetZoomList();
355 if (!mpView->IsTextEdit() && pZoomList->IsNextPossible() && !bSlideShow && !mpDocSh->IsUIActive())
357 // use next ZoomRect
358 mpViewShell->SetZoomRect(pZoomList->GetNextZoomRect());
359 bReturn = true;
362 break;
364 case KEY_COMMA:
366 ZoomList* pZoomList = mpViewShell->GetZoomList();
368 if (!mpView->IsTextEdit() && pZoomList->IsPreviousPossible() && !bSlideShow && !mpDocSh->IsUIActive())
370 // use previous ZoomRect
371 mpViewShell->SetZoomRect(pZoomList->GetPreviousZoomRect());
372 bReturn = true;
375 break;
377 case KEY_HOME:
379 if (!mpView->IsTextEdit() && !bSlideShow)
380 if (auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ))
382 // jump to first page
383 pDrawViewShell->SwitchPage(0);
384 bReturn = true;
387 break;
389 case KEY_END:
391 if (!mpView->IsTextEdit() && !bSlideShow)
392 if (auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ))
394 // jump to last page
395 SdPage* pPage = pDrawViewShell->GetActualPage();
396 pDrawViewShell->SwitchPage(mpDoc->GetSdPageCount(
397 pPage->GetPageKind()) - 1);
398 bReturn = true;
401 break;
403 case KEY_PAGEUP:
405 if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
406 break;
407 if( bSlideShow)
408 break;
410 if( auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ) )
412 // The page-up key switches layers or pages depending on the
413 // modifier key.
414 if ( ! rKEvt.GetKeyCode().GetModifier())
416 // With no modifier pressed we move to the previous
417 // slide.
418 mpView->SdrEndTextEdit();
420 // Previous page.
421 bReturn = true;
422 SdPage* pPage = pDrawViewShell->GetActualPage();
423 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
425 if (nSdPage > 0)
427 // Switch the page and send events regarding
428 // deactivation the old page and activating the new
429 // one.
430 TabControl& rPageTabControl =
431 pDrawViewShell->GetPageTabControl();
432 if (rPageTabControl.IsReallyShown())
433 rPageTabControl.SendDeactivatePageEvent ();
434 pDrawViewShell->SwitchPage(nSdPage - 1);
435 if (rPageTabControl.IsReallyShown())
436 rPageTabControl.SendActivatePageEvent ();
439 else if (rKEvt.GetKeyCode().IsMod1())
441 // With the CONTROL modifier we switch layers.
442 if (pDrawViewShell->IsLayerModeActive())
444 // Moves to the previous layer.
445 SwitchLayer (-1);
450 break;
452 case KEY_PAGEDOWN:
454 if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() )
455 break;
456 if(dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr && !bSlideShow)
458 // The page-down key switches layers or pages depending on the
459 // modifier key.
460 if ( ! rKEvt.GetKeyCode().GetModifier())
462 // With no modifier pressed we move to the next slide.
463 mpView->SdrEndTextEdit();
465 // Next page.
466 bReturn = true;
467 SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage();
468 sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2;
470 if (nSdPage < mpDoc->GetSdPageCount(pPage->GetPageKind()) - 1)
472 // Switch the page and send events regarding
473 // deactivation the old page and activating the new
474 // one.
475 TabControl& rPageTabControl =
476 static_cast<DrawViewShell*>(mpViewShell)->GetPageTabControl();
477 if (rPageTabControl.IsReallyShown())
478 rPageTabControl.SendDeactivatePageEvent ();
479 static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage + 1);
480 if (rPageTabControl.IsReallyShown())
481 rPageTabControl.SendActivatePageEvent ();
484 else if (rKEvt.GetKeyCode().IsMod1())
486 // With the CONTROL modifier we switch layers.
487 if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive())
489 // With the layer mode active pressing page-down
490 // moves to the next layer.
491 SwitchLayer (+1);
496 break;
498 // change select state when focus is on poly point
499 case KEY_SPACE:
501 const SdrHdlList& rHdlList = mpView->GetHdlList();
502 SdrHdl* pHdl = rHdlList.GetFocusHdl();
504 if(pHdl)
506 if(pHdl->GetKind() == SdrHdlKind::Poly)
508 // rescue ID of point with focus
509 sal_uInt32 nPol(pHdl->GetPolyNum());
510 sal_uInt32 nPnt(pHdl->GetPointNum());
512 if(mpView->IsPointMarked(*pHdl))
514 if(rKEvt.GetKeyCode().IsShift())
516 mpView->UnmarkPoint(*pHdl);
519 else
521 if(!rKEvt.GetKeyCode().IsShift())
523 mpView->UnmarkAllPoints();
526 mpView->MarkPoint(*pHdl);
529 if(nullptr == rHdlList.GetFocusHdl())
531 // restore point with focus
532 SdrHdl* pNewOne = nullptr;
534 for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a)
536 SdrHdl* pAct = rHdlList.GetHdl(a);
538 if(pAct
539 && pAct->GetKind() == SdrHdlKind::Poly
540 && pAct->GetPolyNum() == nPol
541 && pAct->GetPointNum() == nPnt)
543 pNewOne = pAct;
547 if(pNewOne)
549 const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne);
553 bReturn = true;
557 break;
559 case KEY_UP:
560 case KEY_DOWN:
561 case KEY_LEFT:
562 case KEY_RIGHT:
564 if (!mpView->IsTextEdit() && !bSlideShow)
566 ::tools::Long nX = 0;
567 ::tools::Long nY = 0;
569 if (nCode == KEY_UP)
571 // scroll up
572 nX = 0;
573 nY =-1;
575 else if (nCode == KEY_DOWN)
577 // scroll down
578 nX = 0;
579 nY = 1;
581 else if (nCode == KEY_LEFT)
583 // scroll left
584 nX =-1;
585 nY = 0;
587 else if (nCode == KEY_RIGHT)
589 // scroll right
590 nX = 1;
591 nY = 0;
594 if (mpView->AreObjectsMarked() && !rKEvt.GetKeyCode().IsMod1() &&
595 !mpDocSh->IsReadOnly())
597 const SdrHdlList& rHdlList = mpView->GetHdlList();
598 SdrHdl* pHdl = rHdlList.GetFocusHdl();
600 bool bIsMoveOfConnectedHandle(false);
601 bool bOldSuppress = false;
602 SdrEdgeObj* pEdgeObj = nullptr;
603 if(pHdl)
604 pEdgeObj = dynamic_cast<SdrEdgeObj *>( pHdl->GetObj() );
606 if(pEdgeObj && 0 == pHdl->GetPolyNum())
608 if(0 == pHdl->GetPointNum())
610 if(pEdgeObj->GetConnection(true).GetObject())
612 bIsMoveOfConnectedHandle = true;
615 if(1 == pHdl->GetPointNum())
617 if(pEdgeObj->GetConnection(false).GetObject())
619 bIsMoveOfConnectedHandle = true;
624 if(pEdgeObj)
626 // Suppress default connects to inside object and object center
627 bOldSuppress = pEdgeObj->GetSuppressDefaultConnect();
628 pEdgeObj->SetSuppressDefaultConnect(true);
631 if(bIsMoveOfConnectedHandle)
633 sal_uInt16 nMarkHdSiz(mpView->GetMarkHdlSizePixel());
634 Size aHalfConSiz(nMarkHdSiz + 1, nMarkHdSiz + 1);
635 aHalfConSiz = mpWindow->PixelToLogic(aHalfConSiz);
637 if(100 < aHalfConSiz.Width())
638 nX *= aHalfConSiz.Width();
639 else
640 nX *= 100;
642 if(100 < aHalfConSiz.Height())
643 nY *= aHalfConSiz.Height();
644 else
645 nY *= 100;
647 else if(rKEvt.GetKeyCode().IsMod2())
649 // move in 1 pixel distance
650 Size aLogicSizeOnePixel = mpWindow->PixelToLogic(Size(1,1));
651 nX *= aLogicSizeOnePixel.Width();
652 nY *= aLogicSizeOnePixel.Height();
654 else if(rKEvt.GetKeyCode().IsShift())
656 nX *= 1000;
657 nY *= 1000;
659 else
661 // old, fixed move distance
662 nX *= 100;
663 nY *= 100;
666 if(nullptr == pHdl)
668 // only take action when move is allowed
669 if(mpView->IsMoveAllowed())
671 // restrict movement to WorkArea
672 const ::tools::Rectangle& rWorkArea = mpView->GetWorkArea();
674 if(!rWorkArea.IsEmpty())
676 ::tools::Rectangle aMarkRect(mpView->GetMarkedObjRect());
677 aMarkRect.Move(nX, nY);
679 if(!aMarkRect.Contains(rWorkArea))
681 if(aMarkRect.Left() < rWorkArea.Left())
683 nX += rWorkArea.Left() - aMarkRect.Left();
686 if(aMarkRect.Right() > rWorkArea.Right())
688 nX -= aMarkRect.Right() - rWorkArea.Right();
691 if(aMarkRect.Top() < rWorkArea.Top())
693 nY += rWorkArea.Top() - aMarkRect.Top();
696 if(aMarkRect.Bottom() > rWorkArea.Bottom())
698 nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
703 // no handle selected
704 if(0 != nX || 0 != nY)
706 mpView->MoveAllMarked(Size(nX, nY));
708 mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
712 else
714 // move handle with index nHandleIndex
715 if (nX || nY)
717 // now move the Handle (nX, nY)
718 Point aStartPoint(pHdl->GetPos());
719 Point aEndPoint(pHdl->GetPos() + Point(nX, nY));
720 const SdrDragStat& rDragStat = mpView->GetDragStat();
722 // start dragging
723 mpView->BegDragObj(aStartPoint, nullptr, pHdl, 0);
725 if(mpView->IsDragObj())
727 bool bWasNoSnap = rDragStat.IsNoSnap();
728 bool bWasSnapEnabled = mpView->IsSnapEnabled();
730 // switch snapping off
731 if(!bWasNoSnap)
732 const_cast<SdrDragStat&>(rDragStat).SetNoSnap();
733 if(bWasSnapEnabled)
734 mpView->SetSnapEnabled(false);
736 mpView->MovAction(aEndPoint);
737 mpView->EndDragObj();
739 // restore snap
740 if(!bWasNoSnap)
741 const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap);
742 if(bWasSnapEnabled)
743 mpView->SetSnapEnabled(bWasSnapEnabled);
746 // make moved handle visible
747 ::tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200));
748 mpView->MakeVisible(aVisRect, *mpWindow);
752 if(pEdgeObj)
754 // Restore original suppress value
755 pEdgeObj->SetSuppressDefaultConnect(bOldSuppress);
758 else
760 // scroll page
761 mpViewShell->ScrollLines(nX, nY);
764 bReturn = true;
767 break;
770 if (bReturn)
772 mpWindow->ReleaseMouse();
775 // when a text-editable object is selected and the
776 // input character is printable, activate text edit on that object
777 // and feed character to object
778 if(!bReturn && !mpDocSh->IsReadOnly())
780 if (!mpView->IsTextEdit())
782 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
784 if(1 == rMarkList.GetMarkCount())
786 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
788 // #i118485# allow TextInput for OLEs, too
789 if( DynCastSdrTextObj( pObj ) != nullptr && pObj->HasTextEdit())
791 // use common IsSimpleCharInput from the EditEngine.
792 bool bPrintable(EditEngine::IsSimpleCharInput(rKEvt));
794 if(bPrintable)
796 // try to activate textedit mode for the selected object
797 SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode()));
799 mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(
800 SID_ATTR_CHAR,
801 SfxCallMode::ASYNCHRON,
802 { &aInputString });
804 // consumed
805 bReturn = true;
809 else
811 // test if there is a title object there. If yes, try to
812 // set it to edit mode and start typing...
813 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell);
814 if (pDrawViewShell && EditEngine::IsSimpleCharInput(rKEvt))
816 SdPage* pActualPage = pDrawViewShell->GetActualPage();
817 SdrTextObj* pCandidate = nullptr;
819 if(pActualPage)
821 SdrObjListIter aIter(pActualPage, SdrIterMode::DeepNoGroups);
823 while(aIter.IsMore() && !pCandidate)
825 SdrObject* pObj = aIter.Next();
827 if(auto pTextObj = DynCastSdrTextObj( pObj ))
829 SdrInventor nInv(pObj->GetObjInventor());
830 SdrObjKind nKnd(pObj->GetObjIdentifier());
832 if(SdrInventor::Default == nInv && SdrObjKind::TitleText == nKnd)
834 pCandidate = pTextObj;
840 // when candidate found and candidate is untouched, start editing text...
841 if(pCandidate && pCandidate->IsEmptyPresObj())
843 mpView->UnMarkAll();
844 mpView->MarkObj(pCandidate, mpView->GetSdrPageView());
845 SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode()));
847 mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList(
848 SID_ATTR_CHAR,
849 SfxCallMode::ASYNCHRON,
850 { &aInputString });
852 // consumed
853 bReturn = true;
860 return bReturn;
863 bool FuPoor::MouseMove(const MouseEvent& )
865 return false;
868 void FuPoor::SelectionHasChanged()
870 const SdrHdlList& rHdlList = mpView->GetHdlList();
871 const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl();
875 * Cut object to clipboard
877 void FuPoor::DoCut()
879 if (mpView)
881 mpView->DoCut();
886 * Copy object to clipboard
888 void FuPoor::DoCopy()
890 if (mpView)
892 mpView->DoCopy();
897 * Paste object from clipboard
899 void FuPoor::DoPaste()
901 if (mpView)
903 mpView->DoPaste(mpWindow);
908 * Paste unformatted text from clipboard
910 void FuPoor::DoPasteUnformatted()
912 if (mpView)
914 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewShell->GetActiveWindow() ) );
915 if (aDataHelper.GetTransferable().is())
917 sal_Int8 nAction = DND_ACTION_COPY;
918 mpView->InsertData( aDataHelper,
919 mpWindow->PixelToLogic( ::tools::Rectangle( Point(), mpWindow->GetOutputSizePixel() ).Center() ),
920 nAction, false, SotClipboardFormatId::STRING);
926 * Timer handler for Drag&Drop
928 IMPL_LINK_NOARG(FuPoor, DragHdl, Timer *, void)
930 if( !mpView )
931 return;
933 sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
934 SdrHdl* pHdl = mpView->PickHandle(aMDPos);
936 if ( pHdl==nullptr && mpView->IsMarkedHit(aMDPos, nHitLog)
937 && !mpView->IsPresObjSelected(false) )
939 mpWindow->ReleaseMouse();
940 bIsInDragMode = true;
941 mpView->StartDrag( aMDPos, mpWindow );
945 bool FuPoor::Command(const CommandEvent& rCEvt)
947 return mpView->Command(rCEvt,mpWindow);
951 * Timer handler for window scrolling
953 IMPL_LINK_NOARG(FuPoor, DelayHdl, Timer *, void)
955 aDelayToScrollTimer.Stop ();
956 bScrollable = true;
958 Point aPnt(mpWindow->GetPointerPosPixel());
960 // use remembered MouseButton state to create correct
961 // MouseEvents for this artificial MouseMove.
962 MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
965 bool FuPoor::MouseButtonUp (const MouseEvent& rMEvt)
967 // remember button state for creation of own MouseEvents
968 SetMouseButtonCode(rMEvt.GetButtons());
970 aDelayToScrollTimer.Stop ();
971 bScrollable = bDelayActive = false;
972 return bScrollable;
975 bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
977 // remember button state for creation of own MouseEvents
978 SetMouseButtonCode(rMEvt.GetButtons());
980 return false;
983 void FuPoor::StartDelayToScrollTimer ()
985 bDelayActive = true;
986 aDelayToScrollTimer.Start ();
989 bool FuPoor::RequestHelp(const HelpEvent& rHEvt)
991 bool bReturn = false;
993 SdrPageView* pPV = mpView->GetSdrPageView();
995 if (pPV)
997 SdPage* pPage = static_cast<SdPage*>( pPV->GetPage() );
999 if (pPage)
1001 bReturn = FmFormPage::RequestHelp(mpWindow, mpView, rHEvt);
1005 return bReturn;
1008 void FuPoor::ReceiveRequest(SfxRequest& /*rReq*/)
1012 rtl::Reference<SdrObject> FuPoor::CreateDefaultObject(const sal_uInt16, const ::tools::Rectangle& )
1014 // empty base implementation
1015 return nullptr;
1018 void FuPoor::ImpForceQuadratic(::tools::Rectangle& rRect)
1020 if(rRect.GetWidth() > rRect.GetHeight())
1022 rRect = ::tools::Rectangle(
1023 Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
1024 Size(rRect.GetHeight(), rRect.GetHeight()));
1026 else
1028 rRect = ::tools::Rectangle(
1029 Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
1030 Size(rRect.GetWidth(), rRect.GetWidth()));
1034 void FuPoor::SwitchLayer (sal_Int32 nOffset)
1036 auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell );
1037 if(!pDrawViewShell)
1038 return;
1040 // Calculate the new index.
1041 sal_Int32 nIndex = pDrawViewShell->GetActiveTabLayerIndex() + nOffset;
1043 // Make sure the new index lies inside the range of valid indices.
1044 if (nIndex < 0)
1045 nIndex = 0;
1046 else if (nIndex >= pDrawViewShell->GetTabLayerCount ())
1047 nIndex = pDrawViewShell->GetTabLayerCount() - 1;
1049 // Set the new active layer.
1050 if (nIndex != pDrawViewShell->GetActiveTabLayerIndex ())
1052 LayerTabBar* pLayerTabControl =
1053 static_cast<DrawViewShell*>(mpViewShell)->GetLayerTabControl();
1054 if (pLayerTabControl != nullptr)
1055 pLayerTabControl->SendDeactivatePageEvent ();
1057 pDrawViewShell->SetActiveTabLayerIndex (nIndex);
1059 if (pLayerTabControl != nullptr)
1060 pLayerTabControl->SendActivatePageEvent ();
1064 /** is called when the current function should be aborted. <p>
1065 This is used when a function gets a KEY_ESCAPE but can also
1066 be called directly.
1068 @returns true if an active function was aborted
1070 bool FuPoor::cancel()
1072 if ( dynamic_cast< const FuSelection *>( this ) == nullptr )
1074 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
1075 return true;
1078 return false;
1081 // #i33136#
1082 bool FuPoor::doConstructOrthogonal() const
1084 // Check whether a media object is selected
1085 bool bResizeKeepRatio = false;
1086 // tdf#89758 Avoid interactive crop preview from being proportionally scaled by default.
1087 if (mpView->AreObjectsMarked() && mpView->GetDragMode() != SdrDragMode::Crop)
1089 const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
1090 if (rMarkList.GetMarkCount() == 1)
1092 SdrObjKind aObjIdentifier = rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier();
1093 bResizeKeepRatio = aObjIdentifier == SdrObjKind::Graphic ||
1094 aObjIdentifier == SdrObjKind::Media ||
1095 aObjIdentifier == SdrObjKind::OLE2;
1098 SdrHdl* pHdl = mpView->PickHandle(aMDPos);
1099 // Resize proportionally when media is selected and the user drags on a corner
1100 if (pHdl)
1101 bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl();
1103 return (
1104 bResizeKeepRatio ||
1105 SID_DRAW_XLINE == nSlotId ||
1106 SID_DRAW_CIRCLEARC == nSlotId ||
1107 SID_DRAW_SQUARE == nSlotId ||
1108 SID_DRAW_SQUARE_NOFILL == nSlotId ||
1109 SID_DRAW_SQUARE_ROUND == nSlotId ||
1110 SID_DRAW_SQUARE_ROUND_NOFILL == nSlotId ||
1111 SID_DRAW_CIRCLE == nSlotId ||
1112 SID_DRAW_CIRCLE_NOFILL == nSlotId ||
1113 SID_DRAW_CIRCLEPIE == nSlotId ||
1114 SID_DRAW_CIRCLEPIE_NOFILL == nSlotId ||
1115 SID_DRAW_CIRCLECUT == nSlotId ||
1116 SID_DRAW_CIRCLECUT_NOFILL == nSlotId ||
1117 SID_DRAW_XPOLYGON == nSlotId ||
1118 SID_DRAW_XPOLYGON_NOFILL == nSlotId ||
1119 SID_3D_CUBE == nSlotId ||
1120 SID_3D_SPHERE == nSlotId ||
1121 SID_3D_SHELL == nSlotId ||
1122 SID_3D_HALF_SPHERE == nSlotId ||
1123 SID_3D_TORUS == nSlotId ||
1124 SID_3D_CYLINDER == nSlotId ||
1125 SID_3D_CONE == nSlotId ||
1126 SID_3D_PYRAMID == nSlotId);
1129 void FuPoor::DoExecute( SfxRequest& )
1133 } // end of namespace sd
1135 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */