/* -*- 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() )
&& !SlideShow::IsInteractiveSlideshow( &mpViewShell->GetViewShellBase() )) ) // IASS
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() )
&& !SlideShow::IsInteractiveSlideshow( &mpViewShell->GetViewShellBase() ); // IASS
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 = DynCastSdrTextObj( 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;
}
const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
if (rMarkList.GetMarkCount() != 0 && !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).GetSdrObject())
{
bIsMoveOfConnectedHandle = true;
}
}
if(1 == pHdl->GetPointNum())
{
if(pEdgeObj->GetConnection(false).GetSdrObject())
{
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( DynCastSdrTextObj( 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 = DynCastSdrTextObj( 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*/)
{
}
rtl::Reference<SdrObject> 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;
const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
// tdf#89758 Avoid interactive crop preview from being proportionally scaled by default.
if (rMarkList.GetMarkCount() != 0 && mpView->GetDragMode() != SdrDragMode::Crop)
{
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: */
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V530 The return value of function 'ExecuteList' is required to be utilized.
↑ V530 The return value of function 'ExecuteList' is required to be utilized.
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V1053 Calling the 'ReceiveRequest' virtual function in the constructor may lead to unexpected result at runtime.
↑ V1004 The 'pHdl' pointer was used unsafely after it was verified against nullptr. Check lines: 606, 609.