Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / drawfunc / fupoor.cxx
blobf0b86395cc9f28dbf5d082e0030c1aee17ae379a
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 <editeng/outliner.hxx>
21 #include <svx/svditer.hxx>
22 #include <svx/svdobj.hxx>
23 #include <svx/svdpagv.hxx>
25 #include "fupoor.hxx"
26 #include "tabvwsh.hxx"
27 #include "drawview.hxx"
28 #include "detfunc.hxx"
29 #include "document.hxx"
30 #include <vcl/svapp.hxx>
31 #include <svx/sdrhittesthelper.hxx>
33 FuPoor::FuPoor(ScTabViewShell* pViewSh, vcl::Window* pWin, ScDrawView* pViewP,
34 SdrModel* pDoc, SfxRequest& rReq) :
35 pView(pViewP),
36 pViewShell(pViewSh),
37 pWindow(pWin),
38 pDrDoc(pDoc),
39 aSfxRequest(rReq),
40 pDialog(nullptr),
41 bIsInDragMode(false),
42 // remember MouseButton state
43 mnCode(0)
45 aScrollTimer.SetTimeoutHdl( LINK(this, FuPoor, ScrollHdl) );
46 aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
48 aDragTimer.SetTimeoutHdl( LINK(this, FuPoor, DragTimerHdl) );
49 aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
52 FuPoor::~FuPoor()
54 aDragTimer.Stop();
55 aScrollTimer.Stop();
56 pDialog.disposeAndClear();
59 void FuPoor::Activate()
61 if (pDialog)
63 pDialog->Show();
67 void FuPoor::Deactivate()
69 aDragTimer.Stop();
70 aScrollTimer.Stop();
72 if (pDialog)
74 pDialog->Hide();
78 /*************************************************************************
80 |* Scrollen bei Erreichen des Fensterrandes; wird von
81 |* MouseMove aufgerufen
83 \************************************************************************/
85 void FuPoor::ForceScroll(const Point& aPixPos)
87 aScrollTimer.Stop();
89 Size aSize = pWindow->GetSizePixel();
90 SCsCOL dx = 0;
91 SCsROW dy = 0;
93 if ( aPixPos.X() <= 0 ) dx = -1;
94 if ( aPixPos.X() >= aSize.Width() ) dx = 1;
95 if ( aPixPos.Y() <= 0 ) dy = -1;
96 if ( aPixPos.Y() >= aSize.Height() ) dy = 1;
98 ScViewData& rViewData = pViewShell->GetViewData();
99 if ( rViewData.GetDocument()->IsNegativePage( rViewData.GetTabNo() ) )
100 dx = -dx;
102 ScSplitPos eWhich = rViewData.GetActivePart();
103 if ( dx > 0 && rViewData.GetHSplitMode() == SC_SPLIT_FIX && WhichH(eWhich) == SC_SPLIT_LEFT )
105 pViewShell->ActivatePart( ( eWhich == SC_SPLIT_TOPLEFT ) ?
106 SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
107 dx = 0;
109 if ( dy > 0 && rViewData.GetVSplitMode() == SC_SPLIT_FIX && WhichV(eWhich) == SC_SPLIT_TOP )
111 pViewShell->ActivatePart( ( eWhich == SC_SPLIT_TOPLEFT ) ?
112 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
113 dy = 0;
116 if ( dx != 0 || dy != 0 )
118 pViewShell->ScrollLines(2*dx, 4*dy);
119 aScrollTimer.Start();
123 /*************************************************************************
125 |* Timer-Handler fuer Fensterscrolling
127 \************************************************************************/
129 IMPL_LINK_NOARG_TYPED(FuPoor, ScrollHdl, Timer *, void)
131 Point aPosPixel = pWindow->GetPointerPosPixel();
133 // use remembered MouseButton state to create correct
134 // MouseEvents for this artificial MouseMove.
135 MouseMove(MouseEvent(aPosPixel, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
138 // moved from inline to *.cxx
139 bool FuPoor::MouseButtonUp(const MouseEvent& rMEvt)
141 // remember button state for creation of own MouseEvents
142 SetMouseButtonCode(rMEvt.GetButtons());
144 return false;
147 // moved from inline to *.cxx
148 bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
150 // remember button state for creation of own MouseEvents
151 SetMouseButtonCode(rMEvt.GetButtons());
153 return false;
156 /*************************************************************************
158 |* Tastaturereignisse bearbeiten
160 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
161 |* FALSE.
163 \************************************************************************/
165 bool FuPoor::KeyInput(const KeyEvent& /* rKEvt */)
167 return false;
170 sal_uInt8 FuPoor::Command(const CommandEvent& rCEvt)
172 if ( CommandEventId::StartDrag == rCEvt.GetCommand() )
174 //!!! sollte Joe eigentlich machen:
175 // nur, wenn im Outliner was selektiert ist, darf
176 // Command sal_True zurueckliefern:
178 OutlinerView* pOutView = pView->GetTextEditOutlinerView();
180 if ( pOutView )
181 return pOutView->HasSelection() ? (pView->Command(rCEvt,pWindow) ? 1 : 0) : SC_CMD_NONE;
182 else
183 return pView->Command(rCEvt,pWindow) ? 1 : 0;
185 else
186 return pView->Command(rCEvt,pWindow) ? 1 : 0;
189 /*************************************************************************
191 |* Timer-Handler fuer Drag&Drop
193 \************************************************************************/
194 IMPL_LINK_NOARG_TYPED(FuPoor, DragTimerHdl, Timer *, void)
196 // ExecuteDrag (und das damit verbundene Reschedule) direkt aus dem Timer
197 // aufzurufen, bringt die VCL-Timer-Verwaltung durcheinander, wenn dabei
198 // (z.B. im Drop) wieder ein Timer gestartet wird (z.B. ComeBack-Timer der
199 // DrawView fuer Solid Handles / ModelHasChanged) - der neue Timer laeuft
200 // dann um die Dauer des Drag&Drop zu spaet ab.
201 // Darum Drag&Drop aus eigenem Event:
203 Application::PostUserEvent( LINK( this, FuPoor, DragHdl ) );
206 IMPL_LINK_NOARG_TYPED(FuPoor, DragHdl, void*, void)
208 SdrHdl* pHdl = pView->PickHandle(aMDPos);
210 if ( pHdl==nullptr && pView->IsMarkedHit(aMDPos) )
212 pWindow->ReleaseMouse();
213 bIsInDragMode = true;
214 pViewShell->GetScDrawView()->BeginDrag(pWindow, aMDPos);
218 // Detektiv-Linie
220 bool FuPoor::IsDetectiveHit( const Point& rLogicPos )
222 SdrPageView* pPV = pView->GetSdrPageView();
223 if (!pPV)
224 return false;
226 bool bFound = false;
227 SdrObjListIter aIter( *pPV->GetObjList(), IM_FLAT );
228 SdrObject* pObject = aIter.Next();
229 while (pObject && !bFound)
231 if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
233 sal_uInt16 nHitLog = (sal_uInt16) pWindow->PixelToLogic(
234 Size(pView->GetHitTolerancePixel(),0)).Width();
235 if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, nullptr, false))
237 bFound = true;
241 pObject = aIter.Next();
243 return bFound;
246 void FuPoor::StopDragTimer()
248 if (aDragTimer.IsActive() )
249 aDragTimer.Stop();
252 /*************************************************************************
254 |* Create default drawing objects via keyboard
256 \************************************************************************/
258 SdrObject* FuPoor::CreateDefaultObject(const sal_uInt16 /* nID */, const Rectangle& /* rRectangle */)
260 // empty base implementation
261 return nullptr;
264 void FuPoor::ImpForceQuadratic(Rectangle& rRect)
266 if(rRect.GetWidth() > rRect.GetHeight())
268 rRect = Rectangle(
269 Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
270 Size(rRect.GetHeight(), rRect.GetHeight()));
272 else
274 rRect = Rectangle(
275 Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
276 Size(rRect.GetWidth(), rRect.GetWidth()));
280 // #i33136# fdo#88339
281 bool FuPoor::doConstructOrthogonal() const
283 // Detect whether we're moving an object or resizing.
284 if (pView->IsDragObj())
286 const SdrHdl* pHdl = pView->GetDragStat().GetHdl();
287 if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
289 return false;
293 // Detect image/media and resize proportionally, but don't constrain movement by default
294 if (pView->AreObjectsMarked())
296 const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
297 if (rMarkList.GetMarkCount() == 1)
299 sal_uInt16 aObjIdentifier = rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier();
300 bool bIsMediaSelected = aObjIdentifier == OBJ_GRAF ||
301 aObjIdentifier == OBJ_MEDIA ||
302 aObjIdentifier == OBJ_OLE2;
304 SdrHdl* pHdl = pView->PickHandle(aMDPos);
305 // Resize proportionally when media is selected and the user drags on a corner
306 if (pHdl)
307 return bIsMediaSelected && pHdl->IsCornerHdl();
308 return bIsMediaSelected;
311 else if (aSfxRequest.GetSlot() == SID_DRAW_XPOLYGON || aSfxRequest.GetSlot() == SID_DRAW_XPOLYGON_NOFILL)
312 return true;
314 return false;
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */