LibreOffice Module sc (master)  1
fupoor.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <editeng/outliner.hxx>
21 #include <svx/svditer.hxx>
22 #include <svx/svdobj.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/svxids.hrc>
25 
26 #include <fupoor.hxx>
27 #include <tabvwsh.hxx>
28 #include <drawview.hxx>
29 #include <detfunc.hxx>
30 #include <document.hxx>
31 #include <vcl/commandevent.hxx>
32 #include <vcl/svapp.hxx>
33 #include <svx/sdrhittesthelper.hxx>
34 
36  SdrModel* pDoc, const SfxRequest& rReq) :
37  pView(pViewP),
38  rViewShell(rViewSh),
39  pWindow(pWin),
40  pDrDoc(pDoc),
41  aSfxRequest(rReq),
42  aScrollTimer("sc FuPoor aScrollTimer"),
43  aDragTimer("sc FuPoor aDragTimer"),
44  bIsInDragMode(false),
45  // remember MouseButton state
46  mnCode(0)
47 {
48  aScrollTimer.SetInvokeHandler( LINK(this, FuPoor, ScrollHdl) );
50 
51  aDragTimer.SetInvokeHandler( LINK(this, FuPoor, DragTimerHdl) );
53 }
54 
56 {
57  aDragTimer.Stop();
59 }
60 
62 {
63 }
64 
66 {
67  aDragTimer.Stop();
69 }
70 
71 // Scroll when reached the window border; is called from MouseMove
72 void FuPoor::ForceScroll(const Point& aPixPos)
73 {
75 
76  Size aSize = pWindow->GetSizePixel();
77  SCCOL dx = 0;
78  SCROW dy = 0;
79 
80  if ( aPixPos.X() <= 0 ) dx = -1;
81  if ( aPixPos.X() >= aSize.Width() ) dx = 1;
82  if ( aPixPos.Y() <= 0 ) dy = -1;
83  if ( aPixPos.Y() >= aSize.Height() ) dy = 1;
84 
85  ScViewData& rViewData = rViewShell.GetViewData();
86  if ( rViewData.GetDocument().IsNegativePage( rViewData.GetTabNo() ) )
87  dx = -dx;
88 
89  ScSplitPos eWhich = rViewData.GetActivePart();
90  if ( dx > 0 && rViewData.GetHSplitMode() == SC_SPLIT_FIX && WhichH(eWhich) == SC_SPLIT_LEFT )
91  {
94  dx = 0;
95  }
96  if ( dy > 0 && rViewData.GetVSplitMode() == SC_SPLIT_FIX && WhichV(eWhich) == SC_SPLIT_TOP )
97  {
100  dy = 0;
101  }
102 
103  if ( dx != 0 || dy != 0 )
104  {
105  rViewShell.ScrollLines(2*dx, 4*dy);
107  }
108 }
109 
110 // Timer handler for window scrolling
111 IMPL_LINK_NOARG(FuPoor, ScrollHdl, Timer *, void)
112 {
113  Point aPosPixel = pWindow->GetPointerPosPixel();
114 
115  // use remembered MouseButton state to create correct
116  // MouseEvents for this artificial MouseMove.
117  MouseMove(MouseEvent(aPosPixel, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
118 }
119 
121 {
122  // remember button state for creation of own MouseEvents
124 
125  return false;
126 }
127 
129 {
130  // remember button state for creation of own MouseEvents
132 
133  return false;
134 }
135 
136 // If we handle a KeyEvent, then the return value is sal_True else FALSE.
137 bool FuPoor::KeyInput(const KeyEvent& /* rKEvt */)
138 {
139  return false;
140 }
141 
143 {
144  if ( CommandEventId::StartDrag == rCEvt.GetCommand() )
145  {
146  // Only if a selection is in Outliner, then Command is allowed
147  // to return sal_True
148 
150 
151  if ( pOutView )
152  return pOutView->HasSelection() ? (pView->Command(rCEvt,pWindow) ? 1 : 0) : SC_CMD_NONE;
153  else
154  return pView->Command(rCEvt,pWindow) ? 1 : 0;
155  }
156  else
157  return pView->Command(rCEvt,pWindow) ? 1 : 0;
158 }
159 
160 // Timer-Handler for Drag&Drop
161 IMPL_LINK_NOARG(FuPoor, DragTimerHdl, Timer *, void)
162 {
163  // Calling ExecuteDrag (and that associated reschedule) directly from
164  // the Timer, will confuse the VCL-Timer-Management, if (e.g during Drop)
165  // a new timer is started (e.g ComeBack-Timer of DrawView for
166  // Solid Handles / ModelHasChanged) - the new timer will end with a delay
167  // of the duration of the Drag&Drop.
168  // Therefore Drag&Drop from own event:
169 
170  Application::PostUserEvent( LINK( this, FuPoor, DragHdl ) );
171 }
172 
173 IMPL_LINK_NOARG(FuPoor, DragHdl, void*, void)
174 {
175  SdrHdl* pHdl = pView->PickHandle(aMDPos);
176 
177  if ( pHdl==nullptr && pView->IsMarkedHit(aMDPos) )
178  {
179  pWindow->ReleaseMouse();
180  bIsInDragMode = true;
181  rViewShell.GetScDrawView()->BeginDrag(pWindow, aMDPos);
182  }
183 }
184 
185 // Detective-line
186 bool FuPoor::IsDetectiveHit( const Point& rLogicPos )
187 {
188  SdrPageView* pPV = pView->GetSdrPageView();
189  if (!pPV)
190  return false;
191 
192  bool bFound = false;
193  SdrObjListIter aIter( pPV->GetObjList(), SdrIterMode::Flat );
194  SdrObject* pObject = aIter.Next();
195  while (pObject && !bFound)
196  {
197  if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
198  {
199  sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWindow->PixelToLogic(
200  Size(pView->GetHitTolerancePixel(),0)).Width());
201  if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, nullptr, false))
202  {
203  bFound = true;
204  }
205  }
206 
207  pObject = aIter.Next();
208  }
209  return bFound;
210 }
211 
213 {
214  if (aDragTimer.IsActive() )
215  aDragTimer.Stop();
216 }
217 
218 // Create default drawing objects via keyboard
219 SdrObjectUniquePtr FuPoor::CreateDefaultObject(const sal_uInt16 /* nID */, const tools::Rectangle& /* rRectangle */)
220 {
221  // empty base implementation
222  return nullptr;
223 }
224 
226 {
227  if(rRect.GetWidth() > rRect.GetHeight())
228  {
229  rRect = tools::Rectangle(
230  Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
231  Size(rRect.GetHeight(), rRect.GetHeight()));
232  }
233  else
234  {
235  rRect = tools::Rectangle(
236  Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
237  Size(rRect.GetWidth(), rRect.GetWidth()));
238  }
239 }
240 
241 // #i33136# fdo#88339
243 {
244  // Detect whether we're moving an object or resizing.
245  if (pView->IsDragObj())
246  {
247  const SdrHdl* pHdl = pView->GetDragStat().GetHdl();
248  if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
249  {
250  return false;
251  }
252  }
253 
254  // Detect image/media and resize proportionally, but don't constrain movement by default
255  if (pView->AreObjectsMarked())
256  {
257  const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
258  if (rMarkList.GetMarkCount() == 1)
259  {
260  sal_uInt16 aObjIdentifier = rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier();
261  bool bIsMediaSelected = aObjIdentifier == OBJ_GRAF ||
262  aObjIdentifier == OBJ_MEDIA ||
263  aObjIdentifier == OBJ_OLE2;
264 
265  SdrHdl* pHdl = pView->PickHandle(aMDPos);
266  // Resize proportionally when media is selected and the user drags on a corner
267  if (pHdl)
268  return bIsMediaSelected && pHdl->IsCornerHdl();
269  return bIsMediaSelected;
270  }
271  }
272  else if (aSfxRequest.GetSlot() == SID_DRAW_XPOLYGON
273  || aSfxRequest.GetSlot() == SID_DRAW_XPOLYGON_NOFILL
274  || aSfxRequest.GetSlot() == SID_DRAW_XLINE)
275  return true;
276 
277  return false;
278 }
279 
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t GetMarkCount() const
ScVSplitPos WhichV(ScSplitPos ePos)
Definition: viewdata.hxx:718
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:994
constexpr tools::Long Left() const
virtual bool MouseButtonUp(const MouseEvent &rMEvt)
Definition: fupoor.cxx:120
bool AreObjectsMarked() const
const SdrDragStat & GetDragStat() const
ScHSplitPos WhichH(ScSplitPos ePos)
Definition: viewdata.hxx:712
static bool IsNonAlienArrow(const SdrObject *pObject)
Definition: detfunc.cxx:426
virtual Size GetSizePixel() const
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
virtual bool doConstructOrthogonal() const
Definition: fupoor.cxx:242
SCTAB GetTabNo() const
Definition: viewdata.hxx:394
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:397
SdrMark * GetMark(size_t nNum) const
ScDocument & GetDocument() const
Definition: viewdata.hxx:379
FuPoor(ScTabViewShell &rViewSh, vcl::Window *pWin, ScDrawView *pView, SdrModel *pDoc, const SfxRequest &rReq)
Definition: fupoor.cxx:35
#define SELENG_DRAGDROP_TIMEOUT
virtual SdrObjKind GetObjIdentifier() const
EmbeddedObjectRef * pObject
SC_DLLPUBLIC void ScrollLines(tools::Long nDeltaX, tools::Long nDeltaY)
Definition: tabview.cxx:1319
ScSplitPos
Definition: viewdata.hxx:44
bool IsActive() const
constexpr tools::Long Width() const
virtual bool MouseButtonDown(const MouseEvent &rMEvt)
Definition: fupoor.cxx:128
const SdrHdl * GetHdl() const
sal_uInt16 GetButtons() const
IMPL_LINK_NOARG(FuPoor, ScrollHdl, Timer *, void)
Definition: fupoor.cxx:111
void SetMouseButtonCode(sal_uInt16 nNew)
Definition: fupoor.hxx:70
#define SELENG_AUTOREPEAT_INTERVAL
SdrObject * SdrObjectPrimitiveHit(const SdrObject &rObject, const Point &rPnt, sal_uInt16 nTol, const SdrPageView &rSdrPageView, const SdrLayerIDSet *pVisiLayer, bool bTextOnly, drawinglayer::primitive2d::Primitive2DContainer *pHitContainer)
constexpr tools::Long GetWidth() const
bool IsDetectiveHit(const Point &rLogicPos)
Definition: fupoor.cxx:186
void ActivatePart(ScSplitPos eWhich)
Definition: tabview3.cxx:2879
ScTabViewShell & rViewShell
Definition: fupoor.hxx:43
Timer aDragTimer
Definition: fupoor.hxx:53
bool HasSelection() const
void ForceScroll(const Point &aPixPos)
Definition: fupoor.cxx:72
ScSplitMode GetHSplitMode() const
Definition: viewdata.hxx:415
virtual bool KeyInput(const KeyEvent &rKEvt)
Definition: fupoor.cxx:137
ScViewData & GetViewData()
Definition: tabview.hxx:333
SdrObjList * GetObjList() const
SdrObject * GetMarkedSdrObj() const
sal_Int16 SCCOL
Definition: types.hxx:21
const SdrMarkList & GetMarkedObjectList() const
OBJ_GRAF
CommandEventId GetCommand() const
virtual void Start(bool bStartTimer=true) override
SdrHdl * PickHandle(const Point &rPnt) const
virtual SdrObjectUniquePtr CreateDefaultObject(const sal_uInt16 nID, const tools::Rectangle &rRectangle)
Definition: fupoor.cxx:219
constexpr tools::Long Top() const
const OutlinerView * GetTextEditOutlinerView() const
SfxRequest aSfxRequest
Definition: fupoor.hxx:47
Timer aScrollTimer
Definition: fupoor.hxx:49
Point PixelToLogic(const Point &rDevicePt) const
void SetTimeout(sal_uInt64 nTimeoutMs)
Base class for all functions.
Definition: fupoor.hxx:39
Point aMDPos
Definition: fupoor.hxx:57
sal_Int32 SCROW
Definition: types.hxx:17
sal_uInt16 GetSlot() const
sal_uInt8 Command(const CommandEvent &rCEvt)
Definition: fupoor.cxx:142
void Stop()
virtual ~FuPoor()
Definition: fupoor.cxx:55
void StopDragTimer()
Definition: fupoor.cxx:212
constexpr tools::Long Height() const
unsigned char sal_uInt8
virtual bool Command(const CommandEvent &rCEvt, vcl::Window *pWin) override
bool IsVertexHdl() const
ScDrawView * pView
Definition: fupoor.hxx:42
sal_uInt16 GetHitTolerancePixel() const
void SetInvokeHandler(const Link< Timer *, void > &rLink)
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
SdrPageView * GetSdrPageView() const
static void ImpForceQuadratic(tools::Rectangle &rRect)
Definition: fupoor.cxx:225
bool IsDragObj() const
bool IsCornerHdl() const
OBJ_OLE2
virtual void Activate()
Definition: fupoor.cxx:61
VclPtr< vcl::Window > pWindow
Definition: fupoor.hxx:44
ScSplitMode GetVSplitMode() const
Definition: viewdata.hxx:416
OBJ_MEDIA
#define SC_CMD_NONE
Definition: fupoor.hxx:35
constexpr tools::Long GetHeight() const
virtual void Deactivate()
Definition: fupoor.cxx:65