1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <editeng/outliner.hxx>
21 #include <svx/svditer.hxx>
22 #include <svx/svdobj.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/svxids.hrc>
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>
35 FuPoor::FuPoor(ScTabViewShell
& rViewSh
, vcl::Window
* pWin
, ScDrawView
* pViewP
,
36 SdrModel
* pDoc
, const SfxRequest
& rReq
) :
43 // remember MouseButton state
46 aScrollTimer
.SetInvokeHandler( LINK(this, FuPoor
, ScrollHdl
) );
47 aScrollTimer
.SetTimeout(SELENG_AUTOREPEAT_INTERVAL
);
49 aDragTimer
.SetInvokeHandler( LINK(this, FuPoor
, DragTimerHdl
) );
50 aDragTimer
.SetTimeout(SELENG_DRAGDROP_TIMEOUT
);
59 void FuPoor::Activate()
63 void FuPoor::Deactivate()
69 // Scroll when reached the window border; is called from MouseMove
70 void FuPoor::ForceScroll(const Point
& aPixPos
)
74 Size aSize
= pWindow
->GetSizePixel();
78 if ( aPixPos
.X() <= 0 ) dx
= -1;
79 if ( aPixPos
.X() >= aSize
.Width() ) dx
= 1;
80 if ( aPixPos
.Y() <= 0 ) dy
= -1;
81 if ( aPixPos
.Y() >= aSize
.Height() ) dy
= 1;
83 ScViewData
& rViewData
= rViewShell
.GetViewData();
84 if ( rViewData
.GetDocument().IsNegativePage( rViewData
.GetTabNo() ) )
87 ScSplitPos eWhich
= rViewData
.GetActivePart();
88 if ( dx
> 0 && rViewData
.GetHSplitMode() == SC_SPLIT_FIX
&& WhichH(eWhich
) == SC_SPLIT_LEFT
)
90 rViewShell
.ActivatePart( ( eWhich
== SC_SPLIT_TOPLEFT
) ?
91 SC_SPLIT_TOPRIGHT
: SC_SPLIT_BOTTOMRIGHT
);
94 if ( dy
> 0 && rViewData
.GetVSplitMode() == SC_SPLIT_FIX
&& WhichV(eWhich
) == SC_SPLIT_TOP
)
96 rViewShell
.ActivatePart( ( eWhich
== SC_SPLIT_TOPLEFT
) ?
97 SC_SPLIT_BOTTOMLEFT
: SC_SPLIT_BOTTOMRIGHT
);
101 if ( dx
!= 0 || dy
!= 0 )
103 rViewShell
.ScrollLines(2*dx
, 4*dy
);
104 aScrollTimer
.Start();
108 // Timer handler for window scrolling
109 IMPL_LINK_NOARG(FuPoor
, ScrollHdl
, Timer
*, void)
111 Point aPosPixel
= pWindow
->GetPointerPosPixel();
113 // use remembered MouseButton state to create correct
114 // MouseEvents for this artificial MouseMove.
115 MouseMove(MouseEvent(aPosPixel
, 1, MouseEventModifiers::NONE
, GetMouseButtonCode()));
118 bool FuPoor::MouseButtonUp(const MouseEvent
& rMEvt
)
120 // remember button state for creation of own MouseEvents
121 SetMouseButtonCode(rMEvt
.GetButtons());
126 bool FuPoor::MouseButtonDown(const MouseEvent
& rMEvt
)
128 // remember button state for creation of own MouseEvents
129 SetMouseButtonCode(rMEvt
.GetButtons());
134 // If we handle a KeyEvent, then the return value is sal_True else FALSE.
135 bool FuPoor::KeyInput(const KeyEvent
& /* rKEvt */)
140 sal_uInt8
FuPoor::Command(const CommandEvent
& rCEvt
)
142 if ( CommandEventId::StartDrag
== rCEvt
.GetCommand() )
144 // Only if a selection is in Outliner, then Command is allowed
145 // to return sal_True
147 OutlinerView
* pOutView
= pView
->GetTextEditOutlinerView();
150 return pOutView
->HasSelection() ? (pView
->Command(rCEvt
,pWindow
) ? 1 : 0) : SC_CMD_NONE
;
152 return pView
->Command(rCEvt
,pWindow
) ? 1 : 0;
155 return pView
->Command(rCEvt
,pWindow
) ? 1 : 0;
158 // Timer-Handler for Drag&Drop
159 IMPL_LINK_NOARG(FuPoor
, DragTimerHdl
, Timer
*, void)
161 // Calling ExecuteDrag (and that associated reschedule) directly from
162 // the Timer, will confuse the VCL-Timer-Management, if (e.g during Drop)
163 // a new timer is started (e.g ComeBack-Timer of DrawView for
164 // Solid Handles / ModelHasChanged) - the new timer will end with a delay
165 // of the duration of the Drag&Drop.
166 // Therefore Drag&Drop from own event:
168 Application::PostUserEvent( LINK( this, FuPoor
, DragHdl
) );
171 IMPL_LINK_NOARG(FuPoor
, DragHdl
, void*, void)
173 SdrHdl
* pHdl
= pView
->PickHandle(aMDPos
);
175 if ( pHdl
==nullptr && pView
->IsMarkedHit(aMDPos
) )
177 pWindow
->ReleaseMouse();
178 bIsInDragMode
= true;
179 rViewShell
.GetScDrawView()->BeginDrag(pWindow
, aMDPos
);
184 bool FuPoor::IsDetectiveHit( const Point
& rLogicPos
)
186 SdrPageView
* pPV
= pView
->GetSdrPageView();
191 SdrObjListIter
aIter( pPV
->GetObjList(), SdrIterMode::Flat
);
192 SdrObject
* pObject
= aIter
.Next();
193 while (pObject
&& !bFound
)
195 if (ScDetectiveFunc::IsNonAlienArrow( pObject
))
197 sal_uInt16 nHitLog
= static_cast<sal_uInt16
>(pWindow
->PixelToLogic(
198 Size(pView
->GetHitTolerancePixel(),0)).Width());
199 if(SdrObjectPrimitiveHit(*pObject
, rLogicPos
, nHitLog
, *pPV
, nullptr, false))
205 pObject
= aIter
.Next();
210 void FuPoor::StopDragTimer()
212 if (aDragTimer
.IsActive() )
216 // Create default drawing objects via keyboard
217 SdrObjectUniquePtr
FuPoor::CreateDefaultObject(const sal_uInt16
/* nID */, const tools::Rectangle
& /* rRectangle */)
219 // empty base implementation
223 void FuPoor::ImpForceQuadratic(tools::Rectangle
& rRect
)
225 if(rRect
.GetWidth() > rRect
.GetHeight())
227 rRect
= tools::Rectangle(
228 Point(rRect
.Left() + ((rRect
.GetWidth() - rRect
.GetHeight()) / 2), rRect
.Top()),
229 Size(rRect
.GetHeight(), rRect
.GetHeight()));
233 rRect
= tools::Rectangle(
234 Point(rRect
.Left(), rRect
.Top() + ((rRect
.GetHeight() - rRect
.GetWidth()) / 2)),
235 Size(rRect
.GetWidth(), rRect
.GetWidth()));
239 // #i33136# fdo#88339
240 bool FuPoor::doConstructOrthogonal() const
242 // Detect whether we're moving an object or resizing.
243 if (pView
->IsDragObj())
245 const SdrHdl
* pHdl
= pView
->GetDragStat().GetHdl();
246 if (!pHdl
|| (!pHdl
->IsCornerHdl() && !pHdl
->IsVertexHdl()))
252 // Detect image/media and resize proportionally, but don't constrain movement by default
253 if (pView
->AreObjectsMarked())
255 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
256 if (rMarkList
.GetMarkCount() == 1)
258 sal_uInt16 aObjIdentifier
= rMarkList
.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier();
259 bool bIsMediaSelected
= aObjIdentifier
== OBJ_GRAF
||
260 aObjIdentifier
== OBJ_MEDIA
||
261 aObjIdentifier
== OBJ_OLE2
;
263 SdrHdl
* pHdl
= pView
->PickHandle(aMDPos
);
264 // Resize proportionally when media is selected and the user drags on a corner
266 return bIsMediaSelected
&& pHdl
->IsCornerHdl();
267 return bIsMediaSelected
;
270 else if (aSfxRequest
.GetSlot() == SID_DRAW_XPOLYGON
271 || aSfxRequest
.GetSlot() == SID_DRAW_XPOLYGON_NOFILL
272 || aSfxRequest
.GetSlot() == SID_DRAW_XLINE
)
278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */