Line data Source code
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 :
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>
32 :
33 348 : 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(NULL),
41 : bIsInDragMode(false),
42 : // remember MouseButton state
43 348 : mnCode(0)
44 : {
45 348 : aScrollTimer.SetTimeoutHdl( LINK(this, FuPoor, ScrollHdl) );
46 348 : aScrollTimer.SetTimeout(SELENG_AUTOREPEAT_INTERVAL);
47 :
48 348 : aDragTimer.SetTimeoutHdl( LINK(this, FuPoor, DragTimerHdl) );
49 348 : aDragTimer.SetTimeout(SELENG_DRAGDROP_TIMEOUT);
50 348 : }
51 :
52 690 : FuPoor::~FuPoor()
53 : {
54 345 : aDragTimer.Stop();
55 345 : aScrollTimer.Stop();
56 345 : pDialog.disposeAndClear();
57 345 : }
58 :
59 0 : void FuPoor::Activate()
60 : {
61 0 : if (pDialog)
62 : {
63 0 : pDialog->Show();
64 : }
65 0 : }
66 :
67 0 : void FuPoor::Deactivate()
68 : {
69 0 : aDragTimer.Stop();
70 0 : aScrollTimer.Stop();
71 :
72 0 : if (pDialog)
73 : {
74 0 : pDialog->Hide();
75 : }
76 0 : }
77 :
78 : /*************************************************************************
79 : |*
80 : |* Scrollen bei Erreichen des Fensterrandes; wird von
81 : |* MouseMove aufgerufen
82 : |*
83 : \************************************************************************/
84 :
85 0 : void FuPoor::ForceScroll(const Point& aPixPos)
86 : {
87 0 : aScrollTimer.Stop();
88 :
89 0 : Size aSize = pWindow->GetSizePixel();
90 0 : SCsCOL dx = 0;
91 0 : SCsROW dy = 0;
92 :
93 0 : if ( aPixPos.X() <= 0 ) dx = -1;
94 0 : if ( aPixPos.X() >= aSize.Width() ) dx = 1;
95 0 : if ( aPixPos.Y() <= 0 ) dy = -1;
96 0 : if ( aPixPos.Y() >= aSize.Height() ) dy = 1;
97 :
98 0 : ScViewData& rViewData = pViewShell->GetViewData();
99 0 : if ( rViewData.GetDocument()->IsNegativePage( rViewData.GetTabNo() ) )
100 0 : dx = -dx;
101 :
102 0 : ScSplitPos eWhich = rViewData.GetActivePart();
103 0 : if ( dx > 0 && rViewData.GetHSplitMode() == SC_SPLIT_FIX && WhichH(eWhich) == SC_SPLIT_LEFT )
104 : {
105 : pViewShell->ActivatePart( ( eWhich == SC_SPLIT_TOPLEFT ) ?
106 0 : SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
107 0 : dx = 0;
108 : }
109 0 : if ( dy > 0 && rViewData.GetVSplitMode() == SC_SPLIT_FIX && WhichV(eWhich) == SC_SPLIT_TOP )
110 : {
111 : pViewShell->ActivatePart( ( eWhich == SC_SPLIT_TOPLEFT ) ?
112 0 : SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
113 0 : dy = 0;
114 : }
115 :
116 0 : if ( dx != 0 || dy != 0 )
117 : {
118 0 : pViewShell->ScrollLines(2*dx, 4*dy);
119 0 : aScrollTimer.Start();
120 : }
121 0 : }
122 :
123 : /*************************************************************************
124 : |*
125 : |* Timer-Handler fuer Fensterscrolling
126 : |*
127 : \************************************************************************/
128 :
129 0 : IMPL_LINK_NOARG_TYPED(FuPoor, ScrollHdl, Timer *, void)
130 : {
131 0 : Point aPosPixel = pWindow->GetPointerPosPixel();
132 :
133 : // use remembered MouseButton state to create correct
134 : // MouseEvents for this artificial MouseMove.
135 0 : MouseMove(MouseEvent(aPosPixel, 1, MouseEventModifiers::NONE, GetMouseButtonCode()));
136 0 : }
137 :
138 : // moved from inline to *.cxx
139 0 : bool FuPoor::MouseButtonUp(const MouseEvent& rMEvt)
140 : {
141 : // remember button state for creation of own MouseEvents
142 0 : SetMouseButtonCode(rMEvt.GetButtons());
143 :
144 0 : return false;
145 : }
146 :
147 : // moved from inline to *.cxx
148 0 : bool FuPoor::MouseButtonDown(const MouseEvent& rMEvt)
149 : {
150 : // remember button state for creation of own MouseEvents
151 0 : SetMouseButtonCode(rMEvt.GetButtons());
152 :
153 0 : return false;
154 : }
155 :
156 : /*************************************************************************
157 : |*
158 : |* String in Applikations-Statuszeile ausgeben
159 : |*
160 : \************************************************************************/
161 :
162 : // WriteStatus gibt's nicht mehr
163 :
164 : /*************************************************************************
165 : |*
166 : |* Tastaturereignisse bearbeiten
167 : |*
168 : |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
169 : |* FALSE.
170 : |*
171 : \************************************************************************/
172 :
173 0 : bool FuPoor::KeyInput(const KeyEvent& /* rKEvt */)
174 : {
175 0 : return false;
176 : }
177 :
178 0 : sal_uInt8 FuPoor::Command(const CommandEvent& rCEvt)
179 : {
180 0 : if ( CommandEventId::StartDrag == rCEvt.GetCommand() )
181 : {
182 : //!!! sollte Joe eigentlich machen:
183 : // nur, wenn im Outliner was selektiert ist, darf
184 : // Command sal_True zurueckliefern:
185 :
186 0 : OutlinerView* pOutView = pView->GetTextEditOutlinerView();
187 :
188 0 : if ( pOutView )
189 0 : return pOutView->HasSelection() ? (pView->Command(rCEvt,pWindow) ? 1 : 0) : SC_CMD_NONE;
190 : else
191 0 : return pView->Command(rCEvt,pWindow) ? 1 : 0;
192 : }
193 : else
194 0 : return pView->Command(rCEvt,pWindow) ? 1 : 0;
195 : }
196 :
197 : /*************************************************************************
198 : |*
199 : |* Timer-Handler fuer Drag&Drop
200 : |*
201 : \************************************************************************/
202 0 : IMPL_LINK_NOARG_TYPED(FuPoor, DragTimerHdl, Timer *, void)
203 : {
204 : // ExecuteDrag (und das damit verbundene Reschedule) direkt aus dem Timer
205 : // aufzurufen, bringt die VCL-Timer-Verwaltung durcheinander, wenn dabei
206 : // (z.B. im Drop) wieder ein Timer gestartet wird (z.B. ComeBack-Timer der
207 : // DrawView fuer Solid Handles / ModelHasChanged) - der neue Timer laeuft
208 : // dann um die Dauer des Drag&Drop zu spaet ab.
209 : // Darum Drag&Drop aus eigenem Event:
210 :
211 0 : Application::PostUserEvent( LINK( this, FuPoor, DragHdl ) );
212 0 : }
213 :
214 0 : IMPL_LINK_NOARG(FuPoor, DragHdl)
215 : {
216 0 : SdrHdl* pHdl = pView->PickHandle(aMDPos);
217 :
218 0 : if ( pHdl==NULL && pView->IsMarkedHit(aMDPos) )
219 : {
220 0 : pWindow->ReleaseMouse();
221 0 : bIsInDragMode = true;
222 0 : pViewShell->GetScDrawView()->BeginDrag(pWindow, aMDPos);
223 : }
224 0 : return 0;
225 : }
226 :
227 : // Detektiv-Linie
228 :
229 0 : bool FuPoor::IsDetectiveHit( const Point& rLogicPos )
230 : {
231 0 : SdrPageView* pPV = pView->GetSdrPageView();
232 0 : if (!pPV)
233 0 : return false;
234 :
235 0 : bool bFound = false;
236 0 : SdrObjListIter aIter( *pPV->GetObjList(), IM_FLAT );
237 0 : SdrObject* pObject = aIter.Next();
238 0 : while (pObject && !bFound)
239 : {
240 0 : if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
241 : {
242 0 : sal_uInt16 nHitLog = (sal_uInt16) pWindow->PixelToLogic(
243 0 : Size(pView->GetHitTolerancePixel(),0)).Width();
244 0 : if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, 0, false))
245 : {
246 0 : bFound = true;
247 : }
248 : }
249 :
250 0 : pObject = aIter.Next();
251 : }
252 0 : return bFound;
253 : }
254 :
255 689 : void FuPoor::StopDragTimer()
256 : {
257 689 : if (aDragTimer.IsActive() )
258 0 : aDragTimer.Stop();
259 689 : }
260 :
261 : /*************************************************************************
262 : |*
263 : |* Create default drawing objects via keyboard
264 : |*
265 : \************************************************************************/
266 :
267 0 : SdrObject* FuPoor::CreateDefaultObject(const sal_uInt16 /* nID */, const Rectangle& /* rRectangle */)
268 : {
269 : // empty base implementation
270 0 : return 0L;
271 : }
272 :
273 0 : void FuPoor::ImpForceQuadratic(Rectangle& rRect)
274 : {
275 0 : if(rRect.GetWidth() > rRect.GetHeight())
276 : {
277 : rRect = Rectangle(
278 0 : Point(rRect.Left() + ((rRect.GetWidth() - rRect.GetHeight()) / 2), rRect.Top()),
279 0 : Size(rRect.GetHeight(), rRect.GetHeight()));
280 : }
281 : else
282 : {
283 : rRect = Rectangle(
284 0 : Point(rRect.Left(), rRect.Top() + ((rRect.GetHeight() - rRect.GetWidth()) / 2)),
285 0 : Size(rRect.GetWidth(), rRect.GetWidth()));
286 : }
287 0 : }
288 :
289 : // #i33136# fdo#88339
290 0 : bool FuPoor::doConstructOrthogonal() const
291 : {
292 : // Detect whether we're moving an object or resizing.
293 0 : bool bIsMoveMode = false;
294 0 : if (pView->IsDragObj())
295 : {
296 0 : const SdrHdl* pHdl = pView->GetDragStat().GetHdl();
297 0 : if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
298 : {
299 0 : bIsMoveMode = true;
300 : }
301 : }
302 :
303 : // Detect image and resize proportionally, but don't constrain movement by default
304 0 : if (!bIsMoveMode && pView->AreObjectsMarked())
305 : {
306 0 : const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
307 0 : if (rMarkList.GetMarkCount() == 1)
308 : {
309 0 : if (rMarkList.GetMark(0)->GetMarkedSdrObj()->GetObjIdentifier() == OBJ_GRAF)
310 : {
311 0 : return true;
312 : }
313 : }
314 : }
315 0 : return false;
316 156 : }
317 :
318 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|