diff options
Diffstat (limited to 'sd/source/ui/func/fupoor.cxx')
-rw-r--r-- | sd/source/ui/func/fupoor.cxx | 1135 |
1 files changed, 1135 insertions, 0 deletions
diff --git a/sd/source/ui/func/fupoor.cxx b/sd/source/ui/func/fupoor.cxx new file mode 100644 index 000000000..e901d07a6 --- /dev/null +++ b/sd/source/ui/func/fupoor.cxx @@ -0,0 +1,1135 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <fupoor.hxx> + +#include <svx/svxids.hrc> +#include <svx/svdpagv.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdograf.hxx> +#include <vcl/seleng.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/request.hxx> +#include <svl/stritem.hxx> + +#include <app.hrc> +#include <fusel.hxx> +#include <sdpage.hxx> +#include <DrawViewShell.hxx> +#include <Window.hxx> +#include <drawdoc.hxx> +#include <DrawDocShell.hxx> +#include <zoomlist.hxx> +#include <slideshow.hxx> +#include <LayerTabBar.hxx> + +#include <com/sun/star/embed/EmbedVerbs.hpp> + +#include <sfx2/viewfrm.hxx> + +#include <svx/svditer.hxx> + +#include <editeng/editeng.hxx> + +using namespace ::com::sun::star; + +namespace sd { + + +FuPoor::FuPoor ( + ViewShell* pViewSh, + ::sd::Window* pWin, + ::sd::View* pView, + SdDrawDocument* pDrDoc, + SfxRequest& rReq) + : mpView(pView), + mpViewShell(pViewSh), + mpWindow(pWin), + mpDocSh( pDrDoc->GetDocSh() ), + mpDoc(pDrDoc), + nSlotId( rReq.GetSlot() ), + aScrollTimer("sd FuPoor aScrollTimer"), + aDragTimer("sd FuPoor aDragTimer"), + bIsInDragMode(false), + bNoScrollUntilInside (true), + aDelayToScrollTimer("sd FuPoor aDelayToScrollTimer"), + bScrollable (false), + bDelayActive (false), + bFirstMouseMove (false), + // remember MouseButton state + mnCode(0) +{ + ReceiveRequest(rReq); + + aScrollTimer.SetInvokeHandler( LINK(this, FuPoor, ScrollHdl) ); + aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL); + + aDragTimer.SetInvokeHandler( LINK(this, FuPoor, DragHdl) ); + aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT); + + aDelayToScrollTimer.SetInvokeHandler( LINK(this, FuPoor, DelayHdl) ); + aDelayToScrollTimer.SetTimeout(2000); +} + +FuPoor::~FuPoor() +{ + aDragTimer.Stop(); + aScrollTimer.Stop(); + aDelayToScrollTimer.Stop(); +} + +void FuPoor::Activate() +{ +} + +void FuPoor::Deactivate() +{ + aDragTimer.Stop(); + aScrollTimer.Stop(); + aDelayToScrollTimer.Stop (); + bScrollable = bDelayActive = false; + + if (mpWindow && mpWindow->IsMouseCaptured()) + mpWindow->ReleaseMouse(); +} + +void FuPoor::SetWindow(::sd::Window* pWin) +{ + mpWindow = pWin; +} + +/** + * scroll when approached the border of the window; is called by MouseMove + */ +void FuPoor::ForceScroll(const Point& aPixPos) +{ + aScrollTimer.Stop(); + + if ( mpView->IsDragHelpLine() || mpView->IsSetPageOrg() || + SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) ) + return; + + Point aPos = mpWindow->OutputToScreenPixel(aPixPos); + const ::tools::Rectangle& rRect = mpViewShell->GetAllWindowRect(); + + if ( bNoScrollUntilInside ) + { + if ( rRect.Contains(aPos) ) + bNoScrollUntilInside = false; + } + else + { + short dx = 0, dy = 0; + + if ( aPos.X() <= rRect.Left() ) dx = -1; + if ( aPos.X() >= rRect.Right() ) dx = 1; + if ( aPos.Y() <= rRect.Top() ) dy = -1; + if ( aPos.Y() >= rRect.Bottom() ) dy = 1; + + if ( dx != 0 || dy != 0 ) + { + if (bScrollable) + { + // scroll action in derived class + mpViewShell->ScrollLines(dx, dy); + aScrollTimer.Start(); + } + else if (! bDelayActive) StartDelayToScrollTimer (); + } + } +} + +/** + * timer handler for window scrolling + */ +IMPL_LINK_NOARG(FuPoor, ScrollHdl, Timer *, void) +{ + Point aPnt(mpWindow->GetPointerPosPixel()); + + // use remembered MouseButton state to create correct + // MouseEvents for this artificial MouseMove. + MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode())); +} + +/** + * handle keyboard events + * @returns sal_True if the event was handled, sal_False otherwise + */ +bool FuPoor::KeyInput(const KeyEvent& rKEvt) +{ + sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); + bool bReturn = false; + bool bSlideShow = SlideShow::IsRunning( mpViewShell->GetViewShellBase() ); + + switch (nCode) + { + case KEY_RETURN: + { + if(rKEvt.GetKeyCode().IsMod1()) + { + if( auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell )) + { + SdPage* pActualPage = pDrawViewShell->GetActualPage(); + SdrTextObj* pCandidate = nullptr; + + if(pActualPage) + { + SdrObjListIter aIter(pActualPage, SdrIterMode::DeepNoGroups); + + while(aIter.IsMore() && !pCandidate) + { + SdrObject* pObj = aIter.Next(); + + if(auto pTextObj = dynamic_cast<SdrTextObj *>( pObj )) + { + SdrInventor nInv(pObj->GetObjInventor()); + SdrObjKind nKnd(pObj->GetObjIdentifier()); + + if(SdrInventor::Default == nInv && + (SdrObjKind::TitleText == nKnd || SdrObjKind::OutlineText == nKnd || SdrObjKind::Text == nKnd)) + { + pCandidate = pTextObj; + } + } + } + } + + if(pCandidate) + { + mpView->UnMarkAll(); + mpView->MarkObj(pCandidate, mpView->GetSdrPageView()); + + mpViewShell->GetViewFrame()->GetDispatcher()->Execute( + SID_ATTR_CHAR, SfxCallMode::ASYNCHRON); + } + else + { + // insert a new page with the same page layout + mpViewShell->GetViewFrame()->GetDispatcher()->Execute( + SID_INSERTPAGE_QUICK, SfxCallMode::ASYNCHRON); + } + + // consumed + bReturn = true; + } + } + else + { + // activate OLE object on RETURN for selected object + // activate text edit on RETURN for selected object + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + + if( !mpView->IsTextEdit() && 1 == rMarkList.GetMarkCount() ) + { + SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj(); + + if( dynamic_cast< const SdrOle2Obj* >( pObj ) && !mpDocSh->IsUIActive() ) + { + //HMHmpView->HideMarkHdl(); + mpViewShell->ActivateObject(static_cast<SdrOle2Obj*>(pObj), css::embed::EmbedVerbs::MS_OLEVERB_PRIMARY); + } + else if( pObj && pObj->IsEmptyPresObj() && dynamic_cast< const SdrGrafObj *>( pObj ) != nullptr ) + { + mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_INSERT_GRAPHIC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD ); + } + else + { + mpViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_ATTR_CHAR, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD ); + } + + // consumed + bReturn = true; + } + } + } + break; + + case KEY_TAB: + { + // handle Mod1 and Mod2 to get travelling running on different systems + if(rKEvt.GetKeyCode().IsMod1() || rKEvt.GetKeyCode().IsMod2()) + { + // do something with a selected handle? + const SdrHdlList& rHdlList = mpView->GetHdlList(); + bool bForward(!rKEvt.GetKeyCode().IsShift()); + + const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward); + + // guarantee visibility of focused handle + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl) + { + Point aHdlPosition(pHdl->GetPos()); + ::tools::Rectangle aVisRect(aHdlPosition - Point(100, 100), Size(200, 200)); + mpView->MakeVisible(aVisRect, *mpWindow); + } + + // consumed + bReturn = true; + } + } + break; + + case KEY_ESCAPE: + { + bReturn = FuPoor::cancel(); + } + break; + + case KEY_ADD: + { + if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive()) + { + // increase zoom + mpViewShell->SetZoom(mpWindow->GetZoom() * 3 / 2); + + if( auto pViewShell = dynamic_cast<DrawViewShell *>( mpViewShell )) + pViewShell->SetZoomOnPage(false); + + bReturn = true; + } + } + break; + + case KEY_SUBTRACT: + { + if (!mpView->IsTextEdit() && !bSlideShow && !mpDocSh->IsUIActive()) + { + // decrease zoom + mpViewShell->SetZoom(mpWindow->GetZoom() * 2 / 3); + + if( auto pViewShell = dynamic_cast<DrawViewShell *>( mpViewShell )) + pViewShell->SetZoomOnPage(false); + + bReturn = true; + } + } + break; + + case KEY_MULTIPLY: + { + if (!mpView->IsTextEdit() && !bSlideShow) + { + // zoom to page + mpViewShell->GetViewFrame()->GetDispatcher()-> + Execute(SID_SIZE_PAGE, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); + bReturn = true; + } + } + break; + + case KEY_DIVIDE: + { + if (!mpView->IsTextEdit() && !bSlideShow) + { + // zoom to selected objects + mpViewShell->GetViewFrame()->GetDispatcher()-> + Execute(SID_SIZE_OPTIMAL, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); + bReturn = true; + } + } + break; + + case KEY_POINT: + { + ZoomList* pZoomList = mpViewShell->GetZoomList(); + + if (!mpView->IsTextEdit() && pZoomList->IsNextPossible() && !bSlideShow && !mpDocSh->IsUIActive()) + { + // use next ZoomRect + mpViewShell->SetZoomRect(pZoomList->GetNextZoomRect()); + bReturn = true; + } + } + break; + + case KEY_COMMA: + { + ZoomList* pZoomList = mpViewShell->GetZoomList(); + + if (!mpView->IsTextEdit() && pZoomList->IsPreviousPossible() && !bSlideShow && !mpDocSh->IsUIActive()) + { + // use previous ZoomRect + mpViewShell->SetZoomRect(pZoomList->GetPreviousZoomRect()); + bReturn = true; + } + } + break; + + case KEY_HOME: + { + if (!mpView->IsTextEdit() && !bSlideShow) + if (auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell )) + { + // jump to first page + pDrawViewShell->SwitchPage(0); + bReturn = true; + } + } + break; + + case KEY_END: + { + if (!mpView->IsTextEdit() && !bSlideShow) + if (auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell )) + { + // jump to last page + SdPage* pPage = pDrawViewShell->GetActualPage(); + pDrawViewShell->SwitchPage(mpDoc->GetSdPageCount( + pPage->GetPageKind()) - 1); + bReturn = true; + } + } + break; + + case KEY_PAGEUP: + { + if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() ) + break; + if( bSlideShow) + break; + + if( auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ) ) + { + // The page-up key switches layers or pages depending on the + // modifier key. + if ( ! rKEvt.GetKeyCode().GetModifier()) + { + // With no modifier pressed we move to the previous + // slide. + mpView->SdrEndTextEdit(); + + // Previous page. + bReturn = true; + SdPage* pPage = pDrawViewShell->GetActualPage(); + sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2; + + if (nSdPage > 0) + { + // Switch the page and send events regarding + // deactivation the old page and activating the new + // one. + TabControl& rPageTabControl = + pDrawViewShell->GetPageTabControl(); + if (rPageTabControl.IsReallyShown()) + rPageTabControl.SendDeactivatePageEvent (); + pDrawViewShell->SwitchPage(nSdPage - 1); + if (rPageTabControl.IsReallyShown()) + rPageTabControl.SendActivatePageEvent (); + } + } + else if (rKEvt.GetKeyCode().IsMod1()) + { + // With the CONTROL modifier we switch layers. + if (pDrawViewShell->IsLayerModeActive()) + { + // Moves to the previous layer. + SwitchLayer (-1); + } + } + } + } + break; + + case KEY_PAGEDOWN: + { + if( rKEvt.GetKeyCode().IsMod1() && rKEvt.GetKeyCode().IsMod2() ) + break; + if(dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr && !bSlideShow) + { + // The page-down key switches layers or pages depending on the + // modifier key. + if ( ! rKEvt.GetKeyCode().GetModifier()) + { + // With no modifier pressed we move to the next slide. + mpView->SdrEndTextEdit(); + + // Next page. + bReturn = true; + SdPage* pPage = static_cast<DrawViewShell*>(mpViewShell)->GetActualPage(); + sal_uInt16 nSdPage = (pPage->GetPageNum() - 1) / 2; + + if (nSdPage < mpDoc->GetSdPageCount(pPage->GetPageKind()) - 1) + { + // Switch the page and send events regarding + // deactivation the old page and activating the new + // one. + TabControl& rPageTabControl = + static_cast<DrawViewShell*>(mpViewShell)->GetPageTabControl(); + if (rPageTabControl.IsReallyShown()) + rPageTabControl.SendDeactivatePageEvent (); + static_cast<DrawViewShell*>(mpViewShell)->SwitchPage(nSdPage + 1); + if (rPageTabControl.IsReallyShown()) + rPageTabControl.SendActivatePageEvent (); + } + } + else if (rKEvt.GetKeyCode().IsMod1()) + { + // With the CONTROL modifier we switch layers. + if (static_cast<DrawViewShell*>(mpViewShell)->IsLayerModeActive()) + { + // With the layer mode active pressing page-down + // moves to the next layer. + SwitchLayer (+1); + } + } + } + } + break; + + // change select state when focus is on poly point + case KEY_SPACE: + { + const SdrHdlList& rHdlList = mpView->GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if(pHdl) + { + if(pHdl->GetKind() == SdrHdlKind::Poly) + { + // rescue ID of point with focus + sal_uInt32 nPol(pHdl->GetPolyNum()); + sal_uInt32 nPnt(pHdl->GetPointNum()); + + if(mpView->IsPointMarked(*pHdl)) + { + if(rKEvt.GetKeyCode().IsShift()) + { + mpView->UnmarkPoint(*pHdl); + } + } + else + { + if(!rKEvt.GetKeyCode().IsShift()) + { + mpView->UnmarkAllPoints(); + } + + mpView->MarkPoint(*pHdl); + } + + if(nullptr == rHdlList.GetFocusHdl()) + { + // restore point with focus + SdrHdl* pNewOne = nullptr; + + for(size_t a = 0; !pNewOne && a < rHdlList.GetHdlCount(); ++a) + { + SdrHdl* pAct = rHdlList.GetHdl(a); + + if(pAct + && pAct->GetKind() == SdrHdlKind::Poly + && pAct->GetPolyNum() == nPol + && pAct->GetPointNum() == nPnt) + { + pNewOne = pAct; + } + } + + if(pNewOne) + { + const_cast<SdrHdlList&>(rHdlList).SetFocusHdl(pNewOne); + } + } + + bReturn = true; + } + } + } + break; + + case KEY_UP: + case KEY_DOWN: + case KEY_LEFT: + case KEY_RIGHT: + { + if (!mpView->IsTextEdit() && !bSlideShow) + { + ::tools::Long nX = 0; + ::tools::Long nY = 0; + + if (nCode == KEY_UP) + { + // scroll up + nX = 0; + nY =-1; + } + else if (nCode == KEY_DOWN) + { + // scroll down + nX = 0; + nY = 1; + } + else if (nCode == KEY_LEFT) + { + // scroll left + nX =-1; + nY = 0; + } + else if (nCode == KEY_RIGHT) + { + // scroll right + nX = 1; + nY = 0; + } + + if (mpView->AreObjectsMarked() && !rKEvt.GetKeyCode().IsMod1() && + !mpDocSh->IsReadOnly()) + { + const SdrHdlList& rHdlList = mpView->GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + bool bIsMoveOfConnectedHandle(false); + bool bOldSuppress = false; + SdrEdgeObj* pEdgeObj = nullptr; + if(pHdl) + pEdgeObj = dynamic_cast<SdrEdgeObj *>( pHdl->GetObj() ); + + if(pEdgeObj && 0 == pHdl->GetPolyNum()) + { + if(0 == pHdl->GetPointNum()) + { + if(pEdgeObj->GetConnection(true).GetObject()) + { + bIsMoveOfConnectedHandle = true; + } + } + if(1 == pHdl->GetPointNum()) + { + if(pEdgeObj->GetConnection(false).GetObject()) + { + bIsMoveOfConnectedHandle = true; + } + } + } + + if(pEdgeObj) + { + // Suppress default connects to inside object and object center + bOldSuppress = pEdgeObj->GetSuppressDefaultConnect(); + pEdgeObj->SetSuppressDefaultConnect(true); + } + + if(bIsMoveOfConnectedHandle) + { + sal_uInt16 nMarkHdSiz(mpView->GetMarkHdlSizePixel()); + Size aHalfConSiz(nMarkHdSiz + 1, nMarkHdSiz + 1); + aHalfConSiz = mpWindow->PixelToLogic(aHalfConSiz); + + if(100 < aHalfConSiz.Width()) + nX *= aHalfConSiz.Width(); + else + nX *= 100; + + if(100 < aHalfConSiz.Height()) + nY *= aHalfConSiz.Height(); + else + nY *= 100; + } + else if(rKEvt.GetKeyCode().IsMod2()) + { + // move in 1 pixel distance + Size aLogicSizeOnePixel = mpWindow->PixelToLogic(Size(1,1)); + nX *= aLogicSizeOnePixel.Width(); + nY *= aLogicSizeOnePixel.Height(); + } + else if(rKEvt.GetKeyCode().IsShift()) + { + nX *= 1000; + nY *= 1000; + } + else + { + // old, fixed move distance + nX *= 100; + nY *= 100; + } + + if(nullptr == pHdl) + { + // only take action when move is allowed + if(mpView->IsMoveAllowed()) + { + // restrict movement to WorkArea + const ::tools::Rectangle& rWorkArea = mpView->GetWorkArea(); + + if(!rWorkArea.IsEmpty()) + { + ::tools::Rectangle aMarkRect(mpView->GetMarkedObjRect()); + aMarkRect.Move(nX, nY); + + if(!aMarkRect.Contains(rWorkArea)) + { + if(aMarkRect.Left() < rWorkArea.Left()) + { + nX += rWorkArea.Left() - aMarkRect.Left(); + } + + if(aMarkRect.Right() > rWorkArea.Right()) + { + nX -= aMarkRect.Right() - rWorkArea.Right(); + } + + if(aMarkRect.Top() < rWorkArea.Top()) + { + nY += rWorkArea.Top() - aMarkRect.Top(); + } + + if(aMarkRect.Bottom() > rWorkArea.Bottom()) + { + nY -= aMarkRect.Bottom() - rWorkArea.Bottom(); + } + } + } + + // no handle selected + if(0 != nX || 0 != nY) + { + mpView->MoveAllMarked(Size(nX, nY)); + + mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow); + } + } + } + else + { + // move handle with index nHandleIndex + if (nX || nY) + { + // now move the Handle (nX, nY) + Point aStartPoint(pHdl->GetPos()); + Point aEndPoint(pHdl->GetPos() + Point(nX, nY)); + const SdrDragStat& rDragStat = mpView->GetDragStat(); + + // start dragging + mpView->BegDragObj(aStartPoint, nullptr, pHdl, 0); + + if(mpView->IsDragObj()) + { + bool bWasNoSnap = rDragStat.IsNoSnap(); + bool bWasSnapEnabled = mpView->IsSnapEnabled(); + + // switch snapping off + if(!bWasNoSnap) + const_cast<SdrDragStat&>(rDragStat).SetNoSnap(); + if(bWasSnapEnabled) + mpView->SetSnapEnabled(false); + + mpView->MovAction(aEndPoint); + mpView->EndDragObj(); + + // restore snap + if(!bWasNoSnap) + const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap); + if(bWasSnapEnabled) + mpView->SetSnapEnabled(bWasSnapEnabled); + } + + // make moved handle visible + ::tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200)); + mpView->MakeVisible(aVisRect, *mpWindow); + } + } + + if(pEdgeObj) + { + // Restore original suppress value + pEdgeObj->SetSuppressDefaultConnect(bOldSuppress); + } + } + else + { + // scroll page + mpViewShell->ScrollLines(nX, nY); + } + + bReturn = true; + } + } + break; + } + + if (bReturn) + { + mpWindow->ReleaseMouse(); + } + + // when a text-editable object is selected and the + // input character is printable, activate text edit on that object + // and feed character to object + if(!bReturn && !mpDocSh->IsReadOnly()) + { + if (!mpView->IsTextEdit()) + { + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + + if(1 == rMarkList.GetMarkCount()) + { + SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + + // #i118485# allow TextInput for OLEs, too + if( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr && pObj->HasTextEdit()) + { + // use common IsSimpleCharInput from the EditEngine. + bool bPrintable(EditEngine::IsSimpleCharInput(rKEvt)); + + if(bPrintable) + { + // try to activate textedit mode for the selected object + SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode())); + + mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList( + SID_ATTR_CHAR, + SfxCallMode::ASYNCHRON, + { &aInputString }); + + // consumed + bReturn = true; + } + } + } + else + { + // test if there is a title object there. If yes, try to + // set it to edit mode and start typing... + DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell); + if (pDrawViewShell && EditEngine::IsSimpleCharInput(rKEvt)) + { + SdPage* pActualPage = pDrawViewShell->GetActualPage(); + SdrTextObj* pCandidate = nullptr; + + if(pActualPage) + { + SdrObjListIter aIter(pActualPage, SdrIterMode::DeepNoGroups); + + while(aIter.IsMore() && !pCandidate) + { + SdrObject* pObj = aIter.Next(); + + if(auto pTextObj = dynamic_cast< SdrTextObj *>( pObj )) + { + SdrInventor nInv(pObj->GetObjInventor()); + SdrObjKind nKnd(pObj->GetObjIdentifier()); + + if(SdrInventor::Default == nInv && SdrObjKind::TitleText == nKnd) + { + pCandidate = pTextObj; + } + } + } + } + + // when candidate found and candidate is untouched, start editing text... + if(pCandidate && pCandidate->IsEmptyPresObj()) + { + mpView->UnMarkAll(); + mpView->MarkObj(pCandidate, mpView->GetSdrPageView()); + SfxStringItem aInputString(SID_ATTR_CHAR, OUString(rKEvt.GetCharCode())); + + mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList( + SID_ATTR_CHAR, + SfxCallMode::ASYNCHRON, + { &aInputString }); + + // consumed + bReturn = true; + } + } + } + } + } + + return bReturn; +} + +bool FuPoor::MouseMove(const MouseEvent& ) +{ + return false; +} + +void FuPoor::SelectionHasChanged() +{ + const SdrHdlList& rHdlList = mpView->GetHdlList(); + const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl(); +} + +/** + * Cut object to clipboard + */ +void FuPoor::DoCut() +{ + if (mpView) + { + mpView->DoCut(); + } +} + +/** + * Copy object to clipboard + */ +void FuPoor::DoCopy() +{ + if (mpView) + { + mpView->DoCopy(); + } +} + +/** + * Paste object from clipboard + */ +void FuPoor::DoPaste() +{ + if (mpView) + { + mpView->DoPaste(mpWindow); + } +} + +/** + * Paste unformatted text from clipboard + */ +void FuPoor::DoPasteUnformatted() +{ + if (mpView) + { + TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewShell->GetActiveWindow() ) ); + if (aDataHelper.GetTransferable().is()) + { + sal_Int8 nAction = DND_ACTION_COPY; + mpView->InsertData( aDataHelper, + mpWindow->PixelToLogic( ::tools::Rectangle( Point(), mpWindow->GetOutputSizePixel() ).Center() ), + nAction, false, SotClipboardFormatId::STRING); + } + } +} + +/** + * Timer handler for Drag&Drop + */ +IMPL_LINK_NOARG(FuPoor, DragHdl, Timer *, void) +{ + if( !mpView ) + return; + + sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); + SdrHdl* pHdl = mpView->PickHandle(aMDPos); + + if ( pHdl==nullptr && mpView->IsMarkedHit(aMDPos, nHitLog) + && !mpView->IsPresObjSelected(false) ) + { + mpWindow->ReleaseMouse(); + bIsInDragMode = true; + mpView->StartDrag( aMDPos, mpWindow ); + } +} + +bool FuPoor::Command(const CommandEvent& rCEvt) +{ + return mpView->Command(rCEvt,mpWindow); +} + +/** + * Timer handler for window scrolling + */ +IMPL_LINK_NOARG(FuPoor, DelayHdl, Timer *, void) +{ + aDelayToScrollTimer.Stop (); + bScrollable = true; + + Point aPnt(mpWindow->GetPointerPosPixel()); + + // use remembered MouseButton state to create correct + // MouseEvents for this artificial MouseMove. + MouseMove(MouseEvent(aPnt, 1, MouseEventModifiers::NONE, GetMouseButtonCode())); +} + +bool FuPoor::MouseButtonUp (const MouseEvent& rMEvt) +{ + // remember button state for creation of own MouseEvents + SetMouseButtonCode(rMEvt.GetButtons()); + + aDelayToScrollTimer.Stop (); + bScrollable = bDelayActive = false; + return bScrollable; +} + +bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt) +{ + // remember button state for creation of own MouseEvents + SetMouseButtonCode(rMEvt.GetButtons()); + + return false; +} + +void FuPoor::StartDelayToScrollTimer () +{ + bDelayActive = true; + aDelayToScrollTimer.Start (); +} + +bool FuPoor::RequestHelp(const HelpEvent& rHEvt) +{ + bool bReturn = false; + + SdrPageView* pPV = mpView->GetSdrPageView(); + + if (pPV) + { + SdPage* pPage = static_cast<SdPage*>( pPV->GetPage() ); + + if (pPage) + { + bReturn = FmFormPage::RequestHelp(mpWindow, mpView, rHEvt); + } + } + + return bReturn; +} + +void FuPoor::ReceiveRequest(SfxRequest& /*rReq*/) +{ +} + +SdrObjectUniquePtr FuPoor::CreateDefaultObject(const sal_uInt16, const ::tools::Rectangle& ) +{ + // empty base implementation + return nullptr; +} + +void FuPoor::ImpForceQuadratic(::tools::Rectangle& rRect) +{ + if(rRect.GetWidth() > rRect.GetHeight()) + { + rRect = ::tools::Rectangle( + Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()), + Size(rRect.GetHeight(), rRect.GetHeight())); + } + else + { + rRect = ::tools::Rectangle( + Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)), + Size(rRect.GetWidth(), rRect.GetWidth())); + } +} + +void FuPoor::SwitchLayer (sal_Int32 nOffset) +{ + auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ); + if(!pDrawViewShell) + return; + + // Calculate the new index. + sal_Int32 nIndex = pDrawViewShell->GetActiveTabLayerIndex() + nOffset; + + // Make sure the new index lies inside the range of valid indices. + if (nIndex < 0) + nIndex = 0; + else if (nIndex >= pDrawViewShell->GetTabLayerCount ()) + nIndex = pDrawViewShell->GetTabLayerCount() - 1; + + // Set the new active layer. + if (nIndex != pDrawViewShell->GetActiveTabLayerIndex ()) + { + LayerTabBar* pLayerTabControl = + static_cast<DrawViewShell*>(mpViewShell)->GetLayerTabControl(); + if (pLayerTabControl != nullptr) + pLayerTabControl->SendDeactivatePageEvent (); + + pDrawViewShell->SetActiveTabLayerIndex (nIndex); + + if (pLayerTabControl != nullptr) + pLayerTabControl->SendActivatePageEvent (); + } +} + +/** is called when the current function should be aborted. <p> + This is used when a function gets a KEY_ESCAPE but can also + be called directly. + + @returns true if an active function was aborted +*/ +bool FuPoor::cancel() +{ + if ( dynamic_cast< const FuSelection *>( this ) == nullptr ) + { + mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON); + return true; + } + + return false; +} + +// #i33136# +bool FuPoor::doConstructOrthogonal() const +{ + // Check whether a media object is selected + bool bResizeKeepRatio = false; + // tdf#89758 Avoid interactive crop preview from being proportionally scaled by default. + if (mpView->AreObjectsMarked() && mpView->GetDragMode() != SdrDragMode::Crop) + { + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + if (rMarkList.GetMarkCount() == 1) + { + SdrObjKind aObjIdentifier = rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier(); + bResizeKeepRatio = aObjIdentifier == SdrObjKind::Graphic || + aObjIdentifier == SdrObjKind::Media || + aObjIdentifier == SdrObjKind::OLE2; + } + } + SdrHdl* pHdl = mpView->PickHandle(aMDPos); + // Resize proportionally when media is selected and the user drags on a corner + if (pHdl) + bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl(); + + return ( + bResizeKeepRatio || + SID_DRAW_XLINE == nSlotId || + SID_DRAW_CIRCLEARC == nSlotId || + SID_DRAW_SQUARE == nSlotId || + SID_DRAW_SQUARE_NOFILL == nSlotId || + SID_DRAW_SQUARE_ROUND == nSlotId || + SID_DRAW_SQUARE_ROUND_NOFILL == nSlotId || + SID_DRAW_CIRCLE == nSlotId || + SID_DRAW_CIRCLE_NOFILL == nSlotId || + SID_DRAW_CIRCLEPIE == nSlotId || + SID_DRAW_CIRCLEPIE_NOFILL == nSlotId || + SID_DRAW_CIRCLECUT == nSlotId || + SID_DRAW_CIRCLECUT_NOFILL == nSlotId || + SID_DRAW_XPOLYGON == nSlotId || + SID_DRAW_XPOLYGON_NOFILL == nSlotId || + SID_3D_CUBE == nSlotId || + SID_3D_SPHERE == nSlotId || + SID_3D_SHELL == nSlotId || + SID_3D_HALF_SPHERE == nSlotId || + SID_3D_TORUS == nSlotId || + SID_3D_CYLINDER == nSlotId || + SID_3D_CONE == nSlotId || + SID_3D_PYRAMID == nSlotId); +} + +void FuPoor::DoExecute( SfxRequest& ) +{ +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |