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 <tools/debug.hxx>
21 : #include <tools/time.hxx>
22 :
23 : #include <unotools/localedatawrapper.hxx>
24 :
25 : #include <vcl/i18nhelp.hxx>
26 : #include <vcl/unohelp.hxx>
27 : #include <vcl/timer.hxx>
28 : #include <vcl/event.hxx>
29 : #include <vcl/settings.hxx>
30 : #include <vcl/svapp.hxx>
31 : #include <vcl/cursor.hxx>
32 : #include <vcl/wrkwin.hxx>
33 : #include <vcl/floatwin.hxx>
34 : #include <vcl/dialog.hxx>
35 : #include <vcl/help.hxx>
36 : #include <vcl/dockwin.hxx>
37 : #include <vcl/menu.hxx>
38 : #include <touch/touch.h>
39 :
40 : #include <svdata.hxx>
41 : #include <dbggui.hxx>
42 : #include <salwtype.hxx>
43 : #include <salframe.hxx>
44 : #include <accmgr.hxx>
45 : #include <print.h>
46 : #include <window.h>
47 : #include <helpwin.hxx>
48 : #include <brdwin.hxx>
49 : #include <salgdi.hxx>
50 : #include <dndlcon.hxx>
51 :
52 : #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
53 : #include <com/sun/star/awt/MouseEvent.hpp>
54 :
55 : #define IMPL_MIN_NEEDSYSWIN 49
56 :
57 32698 : bool ImplCallPreNotify( NotifyEvent& rEvt )
58 : {
59 32698 : return Application::CallEventHooks( rEvt )
60 32698 : || rEvt.GetWindow()->CompatPreNotify( rEvt );
61 : }
62 :
63 0 : static bool ImplHandleMouseFloatMode( vcl::Window* pChild, const Point& rMousePos,
64 : sal_uInt16 nCode, MouseNotifyEvent nSVEvent,
65 : bool bMouseLeave )
66 : {
67 0 : ImplSVData* pSVData = ImplGetSVData();
68 :
69 0 : if ( pSVData->maWinData.mpFirstFloat && !pSVData->maWinData.mpCaptureWin &&
70 0 : !pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( pChild ) )
71 : {
72 : /*
73 : * #93895# since floats are system windows, coordinates have
74 : * to be converted to float relative for the hittest
75 : */
76 0 : HitTest nHitTest = HITTEST_OUTSIDE;
77 0 : FloatingWindow* pFloat = pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( pChild, rMousePos, nHitTest );
78 : FloatingWindow* pLastLevelFloat;
79 : FloatWinPopupFlags nPopupFlags;
80 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
81 : {
82 0 : if ( bMouseLeave )
83 0 : return true;
84 :
85 0 : if ( !pFloat || (nHitTest == HITTEST_RECT) )
86 : {
87 0 : if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
88 0 : ImplDestroyHelpWindow( true );
89 0 : pChild->ImplGetFrame()->SetPointer( PointerStyle::Arrow );
90 0 : return true;
91 : }
92 : }
93 : else
94 : {
95 0 : if ( nCode & MOUSE_LEFT )
96 : {
97 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
98 : {
99 0 : if ( !pFloat )
100 : {
101 0 : pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
102 0 : nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
103 0 : pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
104 0 : return true;
105 : }
106 0 : else if ( nHitTest == HITTEST_RECT )
107 : {
108 0 : if ( !(pFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoMouseRectClose) )
109 0 : pFloat->ImplSetMouseDown();
110 0 : return true;
111 : }
112 : }
113 : else
114 : {
115 0 : if ( pFloat )
116 : {
117 0 : if ( nHitTest == HITTEST_RECT )
118 : {
119 0 : if ( pFloat->ImplIsMouseDown() )
120 0 : pFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel );
121 0 : return true;
122 : }
123 : }
124 : else
125 : {
126 0 : pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
127 0 : nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
128 0 : if ( !(nPopupFlags & FloatWinPopupFlags::NoMouseUpClose) )
129 : {
130 0 : pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
131 0 : return true;
132 : }
133 : }
134 : }
135 : }
136 : else
137 : {
138 0 : if ( !pFloat )
139 : {
140 0 : pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
141 0 : nPopupFlags = pLastLevelFloat->GetPopupModeFlags();
142 0 : if ( nPopupFlags & FloatWinPopupFlags::AllMouseButtonClose )
143 : {
144 0 : if ( (nPopupFlags & FloatWinPopupFlags::NoMouseUpClose) &&
145 0 : (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
146 0 : return true;
147 0 : pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
148 0 : return true;
149 : }
150 : else
151 0 : return true;
152 : }
153 : }
154 : }
155 : }
156 :
157 0 : return false;
158 : }
159 :
160 0 : static void ImplHandleMouseHelpRequest( vcl::Window* pChild, const Point& rMousePos )
161 : {
162 0 : ImplSVData* pSVData = ImplGetSVData();
163 0 : if ( !pSVData->maHelpData.mpHelpWin ||
164 0 : !( pSVData->maHelpData.mpHelpWin->IsWindowOrChild( pChild ) ||
165 0 : pChild->IsWindowOrChild( pSVData->maHelpData.mpHelpWin ) ) )
166 : {
167 0 : HelpEventMode nHelpMode = HelpEventMode::NONE;
168 0 : if ( pSVData->maHelpData.mbQuickHelp )
169 0 : nHelpMode = HelpEventMode::QUICK;
170 0 : if ( pSVData->maHelpData.mbBalloonHelp )
171 0 : nHelpMode |= HelpEventMode::BALLOON;
172 0 : if ( bool(nHelpMode) )
173 : {
174 0 : if ( pChild->IsInputEnabled() && !pChild->IsInModalMode() )
175 : {
176 0 : HelpEvent aHelpEvent( rMousePos, nHelpMode );
177 0 : pSVData->maHelpData.mbRequestingHelp = true;
178 0 : pChild->RequestHelp( aHelpEvent );
179 0 : pSVData->maHelpData.mbRequestingHelp = false;
180 : }
181 : // #104172# do not kill keyboard activated tooltips
182 0 : else if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp)
183 : {
184 0 : ImplDestroyHelpWindow( true );
185 : }
186 : }
187 : }
188 0 : }
189 :
190 0 : static void ImplSetMousePointer( vcl::Window* pChild )
191 : {
192 0 : ImplSVData* pSVData = ImplGetSVData();
193 0 : if ( pSVData->maHelpData.mbExtHelpMode )
194 0 : pChild->ImplGetFrame()->SetPointer( PointerStyle::Help );
195 : else
196 0 : pChild->ImplGetFrame()->SetPointer( pChild->ImplGetMousePointer() );
197 0 : }
198 :
199 0 : static bool ImplCallCommand( vcl::Window* pChild, CommandEventId nEvt, void* pData = NULL,
200 : bool bMouse = false, Point* pPos = NULL )
201 : {
202 0 : Point aPos;
203 0 : if ( pPos )
204 0 : aPos = *pPos;
205 : else
206 : {
207 0 : if( bMouse )
208 0 : aPos = pChild->GetPointerPosPixel();
209 : else
210 : {
211 : // simulate mouseposition at center of window
212 0 : Size aSize( pChild->GetOutputSizePixel() );
213 0 : aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
214 : }
215 : }
216 :
217 0 : CommandEvent aCEvt( aPos, nEvt, bMouse, pData );
218 0 : NotifyEvent aNCmdEvt( MouseNotifyEvent::COMMAND, pChild, &aCEvt );
219 0 : ImplDelData aDelData( pChild );
220 0 : bool bPreNotify = ImplCallPreNotify( aNCmdEvt );
221 0 : if ( aDelData.IsDead() )
222 0 : return false;
223 0 : if ( !bPreNotify )
224 : {
225 0 : pChild->ImplGetWindowImpl()->mbCommand = false;
226 0 : pChild->Command( aCEvt );
227 :
228 0 : if( aDelData.IsDead() )
229 0 : return false;
230 0 : pChild->ImplNotifyKeyMouseCommandEventListeners( aNCmdEvt );
231 0 : if ( aDelData.IsDead() )
232 0 : return false;
233 0 : if ( pChild->ImplGetWindowImpl()->mbCommand )
234 0 : return true;
235 : }
236 :
237 0 : return false;
238 : }
239 :
240 : /* #i34277# delayed context menu activation;
241 : * necessary if there already was a popup menu running.
242 : */
243 :
244 0 : struct ContextMenuEvent
245 : {
246 : VclPtr<vcl::Window> pWindow;
247 : ImplDelData aDelData;
248 : Point aChildPos;
249 : };
250 :
251 0 : static sal_IntPtr ContextMenuEventLink( void* pCEvent, void* )
252 : {
253 0 : ContextMenuEvent* pEv = static_cast<ContextMenuEvent*>(pCEvent);
254 :
255 0 : if( ! pEv->aDelData.IsDead() )
256 : {
257 0 : pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
258 0 : ImplCallCommand( pEv->pWindow, CommandEventId::ContextMenu, NULL, true, &pEv->aChildPos );
259 : }
260 0 : delete pEv;
261 :
262 0 : return 0;
263 : }
264 :
265 0 : bool ImplHandleMouseEvent( vcl::Window* pWindow, MouseNotifyEvent nSVEvent, bool bMouseLeave,
266 : long nX, long nY, sal_uInt64 nMsgTime,
267 : sal_uInt16 nCode, MouseEventModifiers nMode )
268 : {
269 0 : ImplSVData* pSVData = ImplGetSVData();
270 0 : Point aMousePos( nX, nY );
271 0 : vcl::Window* pChild(NULL);
272 0 : bool bRet(false);
273 0 : sal_uInt16 nClicks(0);
274 0 : ImplFrameData* pWinFrameData = pWindow->ImplGetFrameData();
275 0 : sal_uInt16 nOldCode = pWinFrameData->mnMouseCode;
276 :
277 : // we need a mousemove event, before we get a mousebuttondown or a
278 : // mousebuttonup event
279 0 : if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
280 : {
281 0 : if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) && pSVData->maHelpData.mbExtHelpMode )
282 0 : Help::EndExtHelp();
283 0 : if ( pSVData->maHelpData.mpHelpWin )
284 : {
285 0 : if( pWindow->ImplGetWindow() == pSVData->maHelpData.mpHelpWin )
286 : {
287 0 : ImplDestroyHelpWindow( false );
288 0 : return true; // pWindow is dead now - avoid crash!
289 : }
290 : else
291 0 : ImplDestroyHelpWindow( true );
292 : }
293 :
294 0 : if ( (pWinFrameData->mnLastMouseX != nX) ||
295 0 : (pWinFrameData->mnLastMouseY != nY) )
296 : {
297 0 : ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, false, nX, nY, nMsgTime, nCode, nMode );
298 : }
299 : }
300 :
301 : // update frame data
302 0 : pWinFrameData->mnBeforeLastMouseX = pWinFrameData->mnLastMouseX;
303 0 : pWinFrameData->mnBeforeLastMouseY = pWinFrameData->mnLastMouseY;
304 0 : pWinFrameData->mnLastMouseX = nX;
305 0 : pWinFrameData->mnLastMouseY = nY;
306 0 : pWinFrameData->mnMouseCode = nCode;
307 0 : MouseEventModifiers nTmpMask = MouseEventModifiers::SYNTHETIC | MouseEventModifiers::MODIFIERCHANGED;
308 0 : pWinFrameData->mnMouseMode = nMode & ~nTmpMask;
309 0 : if ( bMouseLeave )
310 : {
311 0 : pWinFrameData->mbMouseIn = false;
312 0 : if ( pSVData->maHelpData.mpHelpWin && !pSVData->maHelpData.mbKeyboardHelp )
313 : {
314 0 : ImplDelData aDelData( pWindow );
315 :
316 0 : ImplDestroyHelpWindow( true );
317 :
318 0 : if ( aDelData.IsDead() )
319 0 : return true; // pWindow is dead now - avoid crash! (#122045#)
320 : }
321 : }
322 : else
323 0 : pWinFrameData->mbMouseIn = true;
324 :
325 : DBG_ASSERT( !pSVData->maWinData.mpTrackWin ||
326 : (pSVData->maWinData.mpTrackWin == pSVData->maWinData.mpCaptureWin),
327 : "ImplHandleMouseEvent: TrackWin != CaptureWin" );
328 :
329 : // AutoScrollMode
330 0 : if ( pSVData->maWinData.mpAutoScrollWin && (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) )
331 : {
332 0 : pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
333 0 : return true;
334 : }
335 :
336 : // find mouse window
337 0 : if ( pSVData->maWinData.mpCaptureWin )
338 : {
339 0 : pChild = pSVData->maWinData.mpCaptureWin;
340 :
341 : DBG_ASSERT( pWindow == pChild->ImplGetFrameWindow(),
342 : "ImplHandleMouseEvent: mouse event is not sent to capture window" );
343 :
344 : // java client cannot capture mouse correctly
345 0 : if ( pWindow != pChild->ImplGetFrameWindow() )
346 0 : return false;
347 :
348 0 : if ( bMouseLeave )
349 0 : return false;
350 : }
351 : else
352 : {
353 0 : if ( bMouseLeave )
354 0 : pChild = NULL;
355 : else
356 0 : pChild = pWindow->ImplFindWindow( aMousePos );
357 : }
358 :
359 : // test this because mouse events are buffered in the remote version
360 : // and size may not be in sync
361 0 : if ( !pChild && !bMouseLeave )
362 0 : return false;
363 :
364 : // execute a few tests and catch the message or implement the status
365 0 : if ( pChild )
366 : {
367 0 : if( pChild->ImplIsAntiparallel() )
368 : {
369 : // - RTL - re-mirror frame pos at pChild
370 0 : const OutputDevice *pChildWinOutDev = pChild->GetOutDev();
371 0 : pChildWinOutDev->ReMirror( aMousePos );
372 : }
373 : // no mouse messages to system object windows ?
374 : // !!!KA: Is it OK to comment this out? !!!
375 : // if ( pChild->ImplGetWindowImpl()->mpSysObj )
376 : // return false;
377 :
378 : // no mouse messages to disabled windows
379 : // #106845# if the window was disabed during capturing we have to pass the mouse events to release capturing
380 0 : if ( pSVData->maWinData.mpCaptureWin.get() != pChild && (!pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() ) )
381 : {
382 0 : ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave );
383 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
384 : {
385 0 : ImplHandleMouseHelpRequest( pChild, aMousePos );
386 0 : if( pWinFrameData->mpMouseMoveWin.get() != pChild )
387 0 : nMode |= MouseEventModifiers::ENTERWINDOW;
388 : }
389 :
390 : // Call the hook also, if Window is disabled
391 0 : Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
392 0 : MouseEvent aMEvt( aChildPos, pWinFrameData->mnClickCount, nMode, nCode, nCode );
393 0 : NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
394 0 : Application::CallEventHooks( aNEvt );
395 :
396 0 : if( pChild->IsCallHandlersOnInputDisabled() )
397 : {
398 0 : pWinFrameData->mpMouseMoveWin = pChild;
399 0 : pChild->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
400 : }
401 :
402 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
403 0 : return true;
404 : else
405 : {
406 : // Set normal MousePointer for disabled windows
407 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
408 0 : ImplSetMousePointer( pChild );
409 :
410 0 : return false;
411 0 : }
412 : }
413 :
414 : // End ExtTextInput-Mode, if the user click in the same TopLevel Window
415 0 : if ( pSVData->maWinData.mpExtTextInputWin &&
416 0 : ((nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) ||
417 0 : (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP)) )
418 0 : pSVData->maWinData.mpExtTextInputWin->EndExtTextInput( EndExtTextInputFlags::Complete );
419 : }
420 :
421 : // determine mouse event data
422 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
423 : {
424 : // check if MouseMove belongs to same window and if the
425 : // status did not change
426 0 : if ( pChild )
427 : {
428 0 : Point aChildMousePos = pChild->ImplFrameToOutput( aMousePos );
429 0 : if ( !bMouseLeave &&
430 0 : (pChild == pWinFrameData->mpMouseMoveWin) &&
431 0 : (aChildMousePos.X() == pWinFrameData->mnLastMouseWinX) &&
432 0 : (aChildMousePos.Y() == pWinFrameData->mnLastMouseWinY) &&
433 0 : (nOldCode == pWinFrameData->mnMouseCode) )
434 : {
435 : // set mouse pointer anew, as it could have changed
436 : // due to the mode switch
437 0 : ImplSetMousePointer( pChild );
438 0 : return false;
439 : }
440 :
441 0 : pWinFrameData->mnLastMouseWinX = aChildMousePos.X();
442 0 : pWinFrameData->mnLastMouseWinY = aChildMousePos.Y();
443 : }
444 :
445 : // mouse click
446 0 : nClicks = pWinFrameData->mnClickCount;
447 :
448 : // call Start-Drag handler if required
449 : // Warning: should be called before Move, as otherwise during
450 : // fast mouse movements the applications move to the selection state
451 0 : vcl::Window* pMouseDownWin = pWinFrameData->mpMouseDownWin;
452 0 : if ( pMouseDownWin )
453 : {
454 : // check for matching StartDrag mode. We only compare
455 : // the status of the mouse buttons, such that e. g. Mod1 can
456 : // change immediately to the copy mode
457 0 : const MouseSettings& rMSettings = pMouseDownWin->GetSettings().GetMouseSettings();
458 0 : if ( (nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
459 0 : (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) )
460 : {
461 0 : if ( !pMouseDownWin->ImplGetFrameData()->mbStartDragCalled )
462 : {
463 0 : long nDragW = rMSettings.GetStartDragWidth();
464 0 : long nDragH = rMSettings.GetStartDragHeight();
465 : //long nMouseX = nX;
466 : //long nMouseY = nY;
467 0 : long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
468 0 : long nMouseY = aMousePos.Y();
469 0 : if ( !(((nMouseX-nDragW) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX) &&
470 0 : ((nMouseX+nDragW) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseX)) ||
471 0 : !(((nMouseY-nDragH) <= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY) &&
472 0 : ((nMouseY+nDragH) >= pMouseDownWin->ImplGetFrameData()->mnFirstMouseY)) )
473 : {
474 0 : pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = true;
475 :
476 : // Check if drag source provides it's own recognizer
477 0 : if( pMouseDownWin->ImplGetFrameData()->mbInternalDragGestureRecognizer )
478 : {
479 : // query DropTarget from child window
480 : ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > xDragGestureRecognizer =
481 0 : ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragGestureRecognizer > ( pMouseDownWin->ImplGetWindowImpl()->mxDNDListenerContainer,
482 0 : ::com::sun::star::uno::UNO_QUERY );
483 :
484 0 : if( xDragGestureRecognizer.is() )
485 : {
486 : // retrieve mouse position relative to mouse down window
487 : Point relLoc = pMouseDownWin->ImplFrameToOutput( Point(
488 0 : pMouseDownWin->ImplGetFrameData()->mnFirstMouseX,
489 0 : pMouseDownWin->ImplGetFrameData()->mnFirstMouseY ) );
490 :
491 : // create a uno mouse event out of the available data
492 : ::com::sun::star::awt::MouseEvent aMouseEvent(
493 : static_cast < ::com::sun::star::uno::XInterface * > ( 0 ),
494 : #ifdef MACOSX
495 : nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3),
496 : #else
497 : nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2),
498 : #endif
499 : nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE),
500 : nMouseX,
501 : nMouseY,
502 : nClicks,
503 0 : false );
504 :
505 0 : SolarMutexReleaser aReleaser;
506 :
507 : // FIXME: where do I get Action from ?
508 0 : ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDragSource > xDragSource = pMouseDownWin->GetDragSource();
509 :
510 0 : if( xDragSource.is() )
511 : {
512 0 : static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent( 0,
513 0 : relLoc.X(), relLoc.Y(), xDragSource, ::com::sun::star::uno::makeAny( aMouseEvent ) );
514 0 : }
515 0 : }
516 : }
517 : }
518 : }
519 : }
520 : else
521 0 : pMouseDownWin->ImplGetFrameData()->mbStartDragCalled = true;
522 : }
523 :
524 : // test for mouseleave and mouseenter
525 0 : vcl::Window* pMouseMoveWin = pWinFrameData->mpMouseMoveWin;
526 0 : if ( pChild != pMouseMoveWin )
527 : {
528 0 : if ( pMouseMoveWin )
529 : {
530 0 : Point aLeaveMousePos = pMouseMoveWin->ImplFrameToOutput( aMousePos );
531 0 : MouseEvent aMLeaveEvt( aLeaveMousePos, nClicks, nMode | MouseEventModifiers::LEAVEWINDOW, nCode, nCode );
532 0 : NotifyEvent aNLeaveEvt( MouseNotifyEvent::MOUSEMOVE, pMouseMoveWin, &aMLeaveEvt );
533 0 : ImplDelData aDelData;
534 0 : ImplDelData aDelData2;
535 0 : pWinFrameData->mbInMouseMove = true;
536 0 : pMouseMoveWin->ImplGetWinData()->mbMouseOver = false;
537 0 : pMouseMoveWin->ImplAddDel( &aDelData );
538 :
539 : // A MouseLeave can destroy this window
540 0 : if ( pChild )
541 0 : pChild->ImplAddDel( &aDelData2 );
542 0 : if ( !ImplCallPreNotify( aNLeaveEvt ) )
543 : {
544 0 : pMouseMoveWin->MouseMove( aMLeaveEvt );
545 0 : if( !aDelData.IsDead() )
546 0 : aNLeaveEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNLeaveEvt );
547 : }
548 :
549 0 : pWinFrameData->mpMouseMoveWin = NULL;
550 0 : pWinFrameData->mbInMouseMove = false;
551 :
552 0 : if ( pChild )
553 : {
554 0 : if ( aDelData2.IsDead() )
555 0 : pChild = NULL;
556 : else
557 0 : pChild->ImplRemoveDel( &aDelData2 );
558 : }
559 0 : if ( aDelData.IsDead() )
560 0 : return true;
561 0 : pMouseMoveWin->ImplRemoveDel( &aDelData );
562 : }
563 :
564 0 : nMode |= MouseEventModifiers::ENTERWINDOW;
565 : }
566 0 : pWinFrameData->mpMouseMoveWin = pChild;
567 0 : if( pChild )
568 0 : pChild->ImplGetWinData()->mbMouseOver = true;
569 :
570 : // MouseLeave
571 0 : if ( !pChild )
572 0 : return false;
573 : }
574 : else
575 : {
576 0 : if (pChild)
577 : {
578 : // mouse click
579 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
580 : {
581 0 : const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
582 0 : sal_uInt64 nDblClkTime = rMSettings.GetDoubleClickTime();
583 0 : long nDblClkW = rMSettings.GetDoubleClickWidth();
584 0 : long nDblClkH = rMSettings.GetDoubleClickHeight();
585 : //long nMouseX = nX;
586 : //long nMouseY = nY;
587 0 : long nMouseX = aMousePos.X(); // #106074# use the possibly re-mirrored coordinates (RTL) ! nX,nY are unmodified !
588 0 : long nMouseY = aMousePos.Y();
589 :
590 0 : if ( (pChild == pChild->ImplGetFrameData()->mpMouseDownWin) &&
591 0 : (nCode == pChild->ImplGetFrameData()->mnFirstMouseCode) &&
592 0 : ((nMsgTime-pChild->ImplGetFrameData()->mnMouseDownTime) < nDblClkTime) &&
593 0 : ((nMouseX-nDblClkW) <= pChild->ImplGetFrameData()->mnFirstMouseX) &&
594 0 : ((nMouseX+nDblClkW) >= pChild->ImplGetFrameData()->mnFirstMouseX) &&
595 0 : ((nMouseY-nDblClkH) <= pChild->ImplGetFrameData()->mnFirstMouseY) &&
596 0 : ((nMouseY+nDblClkH) >= pChild->ImplGetFrameData()->mnFirstMouseY) )
597 : {
598 0 : pChild->ImplGetFrameData()->mnClickCount++;
599 0 : pChild->ImplGetFrameData()->mbStartDragCalled = true;
600 : }
601 : else
602 : {
603 0 : pChild->ImplGetFrameData()->mpMouseDownWin = pChild;
604 0 : pChild->ImplGetFrameData()->mnClickCount = 1;
605 0 : pChild->ImplGetFrameData()->mnFirstMouseX = nMouseX;
606 0 : pChild->ImplGetFrameData()->mnFirstMouseY = nMouseY;
607 0 : pChild->ImplGetFrameData()->mnFirstMouseCode = nCode;
608 0 : pChild->ImplGetFrameData()->mbStartDragCalled = !((nCode & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)) ==
609 0 : (rMSettings.GetStartDragCode() & (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)));
610 : }
611 0 : pChild->ImplGetFrameData()->mnMouseDownTime = nMsgTime;
612 : }
613 0 : nClicks = pChild->ImplGetFrameData()->mnClickCount;
614 : }
615 :
616 0 : pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
617 : }
618 :
619 : DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild == NULL" );
620 :
621 0 : if (!pChild)
622 0 : return false;
623 :
624 : // create mouse event
625 0 : Point aChildPos = pChild->ImplFrameToOutput( aMousePos );
626 0 : MouseEvent aMEvt( aChildPos, nClicks, nMode, nCode, nCode );
627 :
628 :
629 : // tracking window gets the mouse events
630 0 : if ( pSVData->maWinData.mpTrackWin )
631 0 : pChild = pSVData->maWinData.mpTrackWin;
632 :
633 : // handle FloatingMode
634 0 : if ( !pSVData->maWinData.mpTrackWin && pSVData->maWinData.mpFirstFloat )
635 : {
636 0 : ImplDelData aDelData;
637 0 : pChild->ImplAddDel( &aDelData );
638 0 : if ( ImplHandleMouseFloatMode( pChild, aMousePos, nCode, nSVEvent, bMouseLeave ) )
639 : {
640 0 : if ( !aDelData.IsDead() )
641 : {
642 0 : pChild->ImplRemoveDel( &aDelData );
643 0 : pChild->ImplGetFrameData()->mbStartDragCalled = true;
644 : }
645 0 : return true;
646 : }
647 : else
648 0 : pChild->ImplRemoveDel( &aDelData );
649 : }
650 :
651 : // call handler
652 0 : bool bDrag = false;
653 0 : bool bCallHelpRequest = true;
654 : DBG_ASSERT( pChild, "ImplHandleMouseEvent: pChild is NULL" );
655 :
656 0 : if (!pChild)
657 0 : return false;
658 :
659 0 : ImplDelData aDelData;
660 0 : NotifyEvent aNEvt( nSVEvent, pChild, &aMEvt );
661 0 : pChild->ImplAddDel( &aDelData );
662 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
663 0 : pChild->ImplGetFrameData()->mbInMouseMove = true;
664 :
665 : // bring window into foreground on mouseclick
666 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
667 : {
668 0 : if( !pSVData->maWinData.mpFirstFloat && // totop for floating windows in popup would change the focus and would close them immediately
669 0 : !(pChild->ImplGetFrameWindow()->GetStyle() & WB_OWNERDRAWDECORATION) ) // ownerdrawdecorated windows must never grab focus
670 0 : pChild->ToTop();
671 0 : if ( aDelData.IsDead() )
672 0 : return true;
673 : }
674 :
675 0 : if ( ImplCallPreNotify( aNEvt ) || aDelData.IsDead() )
676 0 : bRet = true;
677 : else
678 : {
679 0 : bRet = false;
680 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
681 : {
682 0 : if ( pSVData->maWinData.mpTrackWin )
683 : {
684 0 : TrackingEvent aTEvt( aMEvt );
685 0 : pChild->Tracking( aTEvt );
686 0 : if ( !aDelData.IsDead() )
687 : {
688 : // When ScrollRepeat, we restart the timer
689 0 : if ( pSVData->maWinData.mpTrackTimer &&
690 0 : (pSVData->maWinData.mnTrackFlags & StartTrackingFlags::ScrollRepeat) )
691 0 : pSVData->maWinData.mpTrackTimer->Start();
692 : }
693 0 : bCallHelpRequest = false;
694 0 : bRet = true;
695 : }
696 : else
697 : {
698 : // Auto-ToTop
699 0 : if ( !pSVData->maWinData.mpCaptureWin &&
700 0 : (pChild->GetSettings().GetMouseSettings().GetOptions() & MouseSettingsOptions::AutoFocus) )
701 0 : pChild->ToTop( ToTopFlags::NoGrabFocus );
702 :
703 0 : if( aDelData.IsDead() )
704 0 : bCallHelpRequest = false;
705 : else
706 : {
707 : // if the MouseMove handler changes the help window's visibility
708 : // the HelpRequest handler should not be called anymore
709 0 : vcl::Window* pOldHelpTextWin = pSVData->maHelpData.mpHelpWin;
710 0 : pChild->ImplGetWindowImpl()->mbMouseMove = false;
711 0 : pChild->MouseMove( aMEvt );
712 0 : if ( pOldHelpTextWin != pSVData->maHelpData.mpHelpWin )
713 0 : bCallHelpRequest = false;
714 : }
715 : }
716 : }
717 0 : else if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
718 : {
719 0 : if ( pSVData->maWinData.mpTrackWin &&
720 0 : !(pSVData->maWinData.mnTrackFlags & StartTrackingFlags::MouseButtonDown) )
721 0 : bRet = true;
722 : else
723 : {
724 0 : pChild->ImplGetWindowImpl()->mbMouseButtonDown = false;
725 0 : pChild->MouseButtonDown( aMEvt );
726 : }
727 : }
728 : else
729 : {
730 0 : if ( pSVData->maWinData.mpTrackWin )
731 : {
732 0 : pChild->EndTracking();
733 0 : bRet = true;
734 : }
735 : else
736 : {
737 0 : pChild->ImplGetWindowImpl()->mbMouseButtonUp = false;
738 0 : pChild->MouseButtonUp( aMEvt );
739 : }
740 : }
741 :
742 0 : if ( !aDelData.IsDead() )
743 0 : aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
744 : }
745 :
746 0 : if ( aDelData.IsDead() )
747 0 : return true;
748 :
749 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
750 0 : pChild->ImplGetWindowImpl()->mpFrameData->mbInMouseMove = false;
751 :
752 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
753 : {
754 0 : if ( bCallHelpRequest && !pSVData->maHelpData.mbKeyboardHelp )
755 0 : ImplHandleMouseHelpRequest( pChild, pChild->OutputToScreenPixel( aMEvt.GetPosPixel() ) );
756 0 : bRet = true;
757 : }
758 0 : else if ( !bRet )
759 : {
760 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN )
761 : {
762 0 : if ( !pChild->ImplGetWindowImpl()->mbMouseButtonDown )
763 0 : bRet = true;
764 : }
765 : else
766 : {
767 0 : if ( !pChild->ImplGetWindowImpl()->mbMouseButtonUp )
768 0 : bRet = true;
769 : }
770 : }
771 :
772 0 : pChild->ImplRemoveDel( &aDelData );
773 :
774 0 : if ( nSVEvent == MouseNotifyEvent::MOUSEMOVE )
775 : {
776 : // set new mouse pointer
777 0 : if ( !bMouseLeave )
778 0 : ImplSetMousePointer( pChild );
779 : }
780 0 : else if ( (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) || (nSVEvent == MouseNotifyEvent::MOUSEBUTTONUP) )
781 : {
782 0 : if ( !bDrag )
783 : {
784 : // Command-Events
785 0 : if ( /*!bRet &&*/ (nClicks == 1) && (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN) &&
786 : (nCode == MOUSE_MIDDLE) )
787 : {
788 0 : MouseMiddleButtonAction nMiddleAction = pChild->GetSettings().GetMouseSettings().GetMiddleButtonAction();
789 0 : if ( nMiddleAction == MouseMiddleButtonAction::AutoScroll )
790 0 : bRet = !ImplCallCommand( pChild, CommandEventId::StartAutoScroll, NULL, true, &aChildPos );
791 0 : else if ( nMiddleAction == MouseMiddleButtonAction::PasteSelection )
792 0 : bRet = !ImplCallCommand( pChild, CommandEventId::PasteSelection, NULL, true, &aChildPos );
793 : }
794 : else
795 : {
796 : // ContextMenu
797 0 : const MouseSettings& rMSettings = pChild->GetSettings().GetMouseSettings();
798 0 : if ( (nCode == rMSettings.GetContextMenuCode()) &&
799 0 : (nClicks == rMSettings.GetContextMenuClicks()) )
800 : {
801 0 : bool bContextMenu = (nSVEvent == MouseNotifyEvent::MOUSEBUTTONDOWN);
802 0 : if ( bContextMenu )
803 : {
804 0 : if( pSVData->maAppData.mpActivePopupMenu )
805 : {
806 : /* #i34277# there already is a context menu open
807 : * that was probably just closed with EndPopupMode.
808 : * We need to give the eventual corresponding
809 : * PopupMenu::Execute a chance to end properly.
810 : * Therefore delay context menu command and
811 : * issue only after popping one frame of the
812 : * Yield stack.
813 : */
814 0 : ContextMenuEvent* pEv = new ContextMenuEvent;
815 0 : pEv->pWindow = pChild;
816 0 : pEv->aChildPos = aChildPos;
817 0 : pChild->ImplAddDel( &pEv->aDelData );
818 0 : Application::PostUserEvent( Link<>( pEv, ContextMenuEventLink ) );
819 : }
820 : else
821 0 : bRet = ! ImplCallCommand( pChild, CommandEventId::ContextMenu, NULL, true, &aChildPos );
822 : }
823 : }
824 : }
825 : }
826 : }
827 :
828 0 : return bRet;
829 : }
830 :
831 0 : static vcl::Window* ImplGetKeyInputWindow( vcl::Window* pWindow )
832 : {
833 0 : ImplSVData* pSVData = ImplGetSVData();
834 :
835 : // determine last input time
836 0 : pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
837 :
838 : // #127104# workaround for destroyed windows
839 0 : if( pWindow->ImplGetWindowImpl() == NULL )
840 0 : return 0;
841 :
842 : // find window - is every time the window which has currently the
843 : // focus or the last time the focus.
844 : // the first floating window always has the focus
845 0 : vcl::Window* pChild = pSVData->maWinData.mpFirstFloat;
846 0 : if( !pChild || ( pChild->ImplGetWindowImpl()->mbFloatWin && !static_cast<FloatingWindow *>(pChild)->GrabsFocus() ) )
847 0 : pChild = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
848 : else
849 : {
850 : // allow floaters to forward keyinput to some member
851 0 : pChild = pChild->GetPreferredKeyInputWindow();
852 : }
853 :
854 : // no child - than no input
855 0 : if ( !pChild )
856 0 : return 0;
857 :
858 : // We call also KeyInput if we haven't the focus, because on Unix
859 : // system this is often the case when a Lookup Choise Window has
860 : // the focus - because this windows send the KeyInput directly to
861 : // the window without resetting the focus
862 : DBG_ASSERTWARNING( pChild == pSVData->maWinData.mpFocusWin,
863 : "ImplHandleKey: Keyboard-Input is sent to a frame without focus" );
864 :
865 : // no keyinput to disabled windows
866 0 : if ( !pChild->IsEnabled() || !pChild->IsInputEnabled() || pChild->IsInModalMode() )
867 0 : return 0;
868 :
869 0 : return pChild;
870 : }
871 :
872 0 : static bool ImplHandleKey( vcl::Window* pWindow, MouseNotifyEvent nSVEvent,
873 : sal_uInt16 nKeyCode, sal_uInt16 nCharCode, sal_uInt16 nRepeat, bool bForward )
874 : {
875 0 : ImplSVData* pSVData = ImplGetSVData();
876 0 : vcl::KeyCode aKeyCode( nKeyCode, nKeyCode );
877 0 : sal_uInt16 nEvCode = aKeyCode.GetCode();
878 :
879 : // allow application key listeners to remove the key event
880 : // but make sure we're not forwarding external KeyEvents, (ie where bForward is false)
881 : // because those are coming back from the listener itself and MUST be processed
882 0 : KeyEvent aKeyEvent( (sal_Unicode)nCharCode, aKeyCode, nRepeat );
883 0 : if( bForward )
884 : {
885 : sal_uInt16 nVCLEvent;
886 0 : switch( nSVEvent )
887 : {
888 : case MouseNotifyEvent::KEYINPUT:
889 0 : nVCLEvent = VCLEVENT_WINDOW_KEYINPUT;
890 0 : break;
891 : case MouseNotifyEvent::KEYUP:
892 0 : nVCLEvent = VCLEVENT_WINDOW_KEYUP;
893 0 : break;
894 : default:
895 0 : nVCLEvent = 0;
896 0 : break;
897 : }
898 0 : if( nVCLEvent && Application::HandleKey( nVCLEvent, pWindow, &aKeyEvent ) )
899 0 : return true;
900 : }
901 :
902 : // #i1820# use locale specific decimal separator
903 0 : if( nEvCode == KEY_DECIMAL )
904 : {
905 0 : if( Application::GetSettings().GetMiscSettings().GetEnableLocalizedDecimalSep() )
906 : {
907 0 : OUString aSep( pWindow->GetSettings().GetLocaleDataWrapper().getNumDecimalSep() );
908 0 : nCharCode = (sal_uInt16) aSep[0];
909 : }
910 : }
911 :
912 0 : bool bCtrlF6 = (aKeyCode.GetCode() == KEY_F6) && aKeyCode.IsMod1();
913 :
914 : // determine last input time
915 0 : pSVData->maAppData.mnLastInputTime = tools::Time::GetSystemTicks();
916 :
917 : // handle tracking window
918 0 : if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
919 : {
920 : #ifdef DBG_UTIL
921 : // #105224# use Ctrl-Alt-Shift-D, Ctrl-Shift-D must be useable by app
922 : if ( aKeyCode.IsShift() && aKeyCode.IsMod1() && (aKeyCode.IsMod2() || aKeyCode.IsMod3()) && (aKeyCode.GetCode() == KEY_D) )
923 : {
924 : DBGGUI_START();
925 : return true;
926 : }
927 : #endif
928 :
929 0 : if ( pSVData->maHelpData.mbExtHelpMode )
930 : {
931 0 : Help::EndExtHelp();
932 0 : if ( nEvCode == KEY_ESCAPE )
933 0 : return true;
934 : }
935 0 : if ( pSVData->maHelpData.mpHelpWin )
936 0 : ImplDestroyHelpWindow( false );
937 :
938 : // AutoScrollMode
939 0 : if ( pSVData->maWinData.mpAutoScrollWin )
940 : {
941 0 : pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
942 0 : if ( nEvCode == KEY_ESCAPE )
943 0 : return true;
944 : }
945 :
946 0 : if ( pSVData->maWinData.mpTrackWin )
947 : {
948 0 : sal_uInt16 nOrigCode = aKeyCode.GetCode();
949 :
950 0 : if ( (nOrigCode == KEY_ESCAPE) && !(pSVData->maWinData.mnTrackFlags & StartTrackingFlags::NoKeyCancel) )
951 : {
952 0 : pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key );
953 0 : if ( pSVData->maWinData.mpFirstFloat )
954 : {
955 0 : FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
956 0 : if ( !(pLastLevelFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose) )
957 : {
958 0 : sal_uInt16 nEscCode = aKeyCode.GetCode();
959 :
960 0 : if ( nEscCode == KEY_ESCAPE )
961 0 : pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
962 : }
963 : }
964 0 : return true;
965 : }
966 0 : else if ( nOrigCode == KEY_RETURN )
967 : {
968 0 : pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Key );
969 0 : return true;
970 : }
971 0 : else if ( !(pSVData->maWinData.mnTrackFlags & StartTrackingFlags::KeyInput) )
972 0 : return true;
973 : }
974 :
975 : // handle FloatingMode
976 0 : if ( pSVData->maWinData.mpFirstFloat )
977 : {
978 0 : FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
979 0 : if ( !(pLastLevelFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoKeyClose) )
980 : {
981 0 : sal_uInt16 nCode = aKeyCode.GetCode();
982 :
983 0 : if ( (nCode == KEY_ESCAPE) || bCtrlF6)
984 : {
985 0 : pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
986 0 : if( !bCtrlF6 )
987 0 : return true;
988 : }
989 : }
990 : }
991 :
992 : // test for accel
993 0 : if ( pSVData->maAppData.mpAccelMgr )
994 : {
995 0 : if ( pSVData->maAppData.mpAccelMgr->IsAccelKey( aKeyCode, nRepeat ) )
996 0 : return true;
997 : }
998 : }
999 :
1000 : // find window
1001 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
1002 0 : if ( !pChild )
1003 0 : return false;
1004 :
1005 : // --- RTL --- mirror cursor keys
1006 0 : const OutputDevice *pChildOutDev = pChild->GetOutDev();
1007 0 : if( (aKeyCode.GetCode() == KEY_LEFT || aKeyCode.GetCode() == KEY_RIGHT) &&
1008 0 : pChildOutDev->HasMirroredGraphics() && pChild->IsRTLEnabled() )
1009 0 : aKeyCode = vcl::KeyCode( aKeyCode.GetCode() == KEY_LEFT ? KEY_RIGHT : KEY_LEFT, aKeyCode.GetModifier() );
1010 :
1011 : // call handler
1012 0 : ImplDelData aDelData;
1013 0 : pChild->ImplAddDel( &aDelData );
1014 :
1015 0 : KeyEvent aKeyEvt( (sal_Unicode)nCharCode, aKeyCode, nRepeat );
1016 0 : NotifyEvent aNotifyEvt( nSVEvent, pChild, &aKeyEvt );
1017 0 : bool bKeyPreNotify = ImplCallPreNotify( aNotifyEvt );
1018 0 : bool nRet = true;
1019 :
1020 0 : if ( !bKeyPreNotify && !aDelData.IsDead() )
1021 : {
1022 0 : if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
1023 : {
1024 0 : pChild->ImplGetWindowImpl()->mbKeyInput = false;
1025 0 : pChild->KeyInput( aKeyEvt );
1026 : }
1027 : else
1028 : {
1029 0 : pChild->ImplGetWindowImpl()->mbKeyUp = false;
1030 0 : pChild->KeyUp( aKeyEvt );
1031 : }
1032 0 : if( !aDelData.IsDead() )
1033 0 : aNotifyEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNotifyEvt );
1034 : }
1035 :
1036 0 : if ( aDelData.IsDead() )
1037 0 : return true;
1038 :
1039 0 : pChild->ImplRemoveDel( &aDelData );
1040 :
1041 0 : if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
1042 : {
1043 0 : if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyInput )
1044 : {
1045 0 : sal_uInt16 nCode = aKeyCode.GetCode();
1046 :
1047 : // #101999# is focus in or below toolbox
1048 0 : bool bToolboxFocus=false;
1049 0 : if( (nCode == KEY_F1) && aKeyCode.IsShift() )
1050 : {
1051 0 : vcl::Window *pWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1052 0 : while( pWin )
1053 : {
1054 0 : if( pWin->ImplGetWindowImpl()->mbToolBox )
1055 : {
1056 0 : bToolboxFocus = true;
1057 0 : break;
1058 : }
1059 : else
1060 0 : pWin = pWin->GetParent();
1061 : }
1062 : }
1063 :
1064 : // ContextMenu
1065 0 : if ( (nCode == KEY_CONTEXTMENU) || ((nCode == KEY_F10) && aKeyCode.IsShift() && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) )
1066 0 : nRet = !ImplCallCommand( pChild, CommandEventId::ContextMenu, NULL, false );
1067 0 : else if ( ( (nCode == KEY_F2) && aKeyCode.IsShift() ) || ( (nCode == KEY_F1) && aKeyCode.IsMod1() ) ||
1068 : // #101999# no active help when focus in toolbox, simulate BallonHelp instead
1069 0 : ( (nCode == KEY_F1) && aKeyCode.IsShift() && bToolboxFocus ) )
1070 : {
1071 : // TipHelp via Keyboard (Shift-F2 or Ctrl-F1)
1072 : // simulate mouseposition at center of window
1073 :
1074 0 : Size aSize = pChild->GetOutputSize();
1075 0 : Point aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
1076 0 : aPos = pChild->OutputToScreenPixel( aPos );
1077 :
1078 0 : HelpEvent aHelpEvent( aPos, HelpEventMode::BALLOON );
1079 0 : aHelpEvent.SetKeyboardActivated( true );
1080 0 : pSVData->maHelpData.mbSetKeyboardHelp = true;
1081 0 : pChild->RequestHelp( aHelpEvent );
1082 0 : pSVData->maHelpData.mbSetKeyboardHelp = false;
1083 : }
1084 0 : else if ( (nCode == KEY_F1) || (nCode == KEY_HELP) )
1085 : {
1086 0 : if ( !aKeyCode.GetModifier() )
1087 : {
1088 0 : if ( pSVData->maHelpData.mbContextHelp )
1089 : {
1090 0 : Point aMousePos = pChild->OutputToScreenPixel( pChild->GetPointerPosPixel() );
1091 0 : HelpEvent aHelpEvent( aMousePos, HelpEventMode::CONTEXT );
1092 0 : pChild->RequestHelp( aHelpEvent );
1093 : }
1094 : else
1095 0 : nRet = false;
1096 : }
1097 0 : else if ( aKeyCode.IsShift() )
1098 : {
1099 0 : if ( pSVData->maHelpData.mbExtHelp )
1100 0 : Help::StartExtHelp();
1101 : else
1102 0 : nRet = false;
1103 0 : }
1104 : }
1105 : else
1106 : {
1107 0 : if ( ImplCallHotKey( aKeyCode ) )
1108 0 : nRet = true;
1109 : else
1110 0 : nRet = false;
1111 : }
1112 : }
1113 : }
1114 : else
1115 : {
1116 0 : if ( !bKeyPreNotify && pChild->ImplGetWindowImpl()->mbKeyUp )
1117 0 : nRet = false;
1118 : }
1119 :
1120 : // #105591# send keyinput to parent if we are a floating window and the key was not pocessed yet
1121 0 : if( !nRet && pWindow->ImplGetWindowImpl()->mbFloatWin && pWindow->GetParent() && (pWindow->ImplGetWindowImpl()->mpFrame != pWindow->GetParent()->ImplGetWindowImpl()->mpFrame) )
1122 : {
1123 0 : pChild = pWindow->GetParent();
1124 :
1125 : // call handler
1126 0 : ImplDelData aChildDelData( pChild );
1127 0 : KeyEvent aKEvt( (sal_Unicode)nCharCode, aKeyCode, nRepeat );
1128 0 : NotifyEvent aNEvt( nSVEvent, pChild, &aKEvt );
1129 0 : bool bPreNotify = ImplCallPreNotify( aNEvt );
1130 0 : if ( aChildDelData.IsDead() )
1131 0 : return true;
1132 :
1133 0 : if ( !bPreNotify )
1134 : {
1135 0 : if ( nSVEvent == MouseNotifyEvent::KEYINPUT )
1136 : {
1137 0 : pChild->ImplGetWindowImpl()->mbKeyInput = false;
1138 0 : pChild->KeyInput( aKEvt );
1139 : }
1140 : else
1141 : {
1142 0 : pChild->ImplGetWindowImpl()->mbKeyUp = false;
1143 0 : pChild->KeyUp( aKEvt );
1144 : }
1145 :
1146 0 : if( !aChildDelData.IsDead() )
1147 0 : aNEvt.GetWindow()->ImplNotifyKeyMouseCommandEventListeners( aNEvt );
1148 0 : if ( aChildDelData.IsDead() )
1149 0 : return true;
1150 : }
1151 :
1152 0 : if( bPreNotify || !pChild->ImplGetWindowImpl()->mbKeyInput )
1153 0 : nRet = true;
1154 : }
1155 :
1156 0 : return nRet;
1157 : }
1158 :
1159 0 : static bool ImplHandleExtTextInput( vcl::Window* pWindow,
1160 : const OUString& rText,
1161 : const sal_uInt16* pTextAttr,
1162 : sal_Int32 nCursorPos, sal_uInt16 nCursorFlags )
1163 : {
1164 0 : ImplSVData* pSVData = ImplGetSVData();
1165 0 : vcl::Window* pChild = NULL;
1166 :
1167 0 : int nTries = 200;
1168 0 : while( nTries-- )
1169 : {
1170 0 : pChild = pSVData->maWinData.mpExtTextInputWin;
1171 0 : if ( !pChild )
1172 : {
1173 0 : pChild = ImplGetKeyInputWindow( pWindow );
1174 0 : if ( !pChild )
1175 0 : return false;
1176 : }
1177 0 : if( !pChild->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1178 0 : break;
1179 0 : Application::Yield();
1180 : }
1181 :
1182 : // If it is the first ExtTextInput call, we inform the information
1183 : // and allocate the data, which we must store in this mode
1184 0 : ImplWinData* pWinData = pChild->ImplGetWinData();
1185 0 : if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1186 : {
1187 0 : pChild->ImplGetWindowImpl()->mbExtTextInput = true;
1188 0 : pWinData->mpExtOldText = new OUString;
1189 0 : if ( pWinData->mpExtOldAttrAry )
1190 : {
1191 0 : delete [] pWinData->mpExtOldAttrAry;
1192 0 : pWinData->mpExtOldAttrAry = NULL;
1193 : }
1194 0 : pSVData->maWinData.mpExtTextInputWin = pChild;
1195 0 : ImplCallCommand( pChild, CommandEventId::StartExtTextInput );
1196 : }
1197 :
1198 : // be aware of being recursively called in StartExtTextInput
1199 0 : if ( !pChild->ImplGetWindowImpl()->mbExtTextInput )
1200 0 : return false;
1201 :
1202 : // Test for changes
1203 0 : bool bOnlyCursor = false;
1204 0 : sal_Int32 nMinLen = std::min( pWinData->mpExtOldText->getLength(), rText.getLength() );
1205 0 : sal_Int32 nDeltaStart = 0;
1206 0 : while ( nDeltaStart < nMinLen )
1207 : {
1208 0 : if ( (*pWinData->mpExtOldText)[nDeltaStart] != rText[nDeltaStart] )
1209 0 : break;
1210 0 : nDeltaStart++;
1211 : }
1212 0 : if ( pWinData->mpExtOldAttrAry || pTextAttr )
1213 : {
1214 0 : if ( !pWinData->mpExtOldAttrAry || !pTextAttr )
1215 0 : nDeltaStart = 0;
1216 : else
1217 : {
1218 0 : sal_Int32 i = 0;
1219 0 : while ( i < nDeltaStart )
1220 : {
1221 0 : if ( pWinData->mpExtOldAttrAry[i] != pTextAttr[i] )
1222 : {
1223 0 : nDeltaStart = i;
1224 0 : break;
1225 : }
1226 0 : i++;
1227 : }
1228 : }
1229 : }
1230 0 : if ( (nDeltaStart >= nMinLen) &&
1231 0 : (pWinData->mpExtOldText->getLength() == rText.getLength()) )
1232 0 : bOnlyCursor = true;
1233 :
1234 : // Call Event and store the information
1235 : CommandExtTextInputData aData( rText, pTextAttr,
1236 : nCursorPos, nCursorFlags,
1237 0 : bOnlyCursor );
1238 0 : *pWinData->mpExtOldText = rText;
1239 0 : if ( pWinData->mpExtOldAttrAry )
1240 : {
1241 0 : delete [] pWinData->mpExtOldAttrAry;
1242 0 : pWinData->mpExtOldAttrAry = NULL;
1243 : }
1244 0 : if ( pTextAttr )
1245 : {
1246 0 : pWinData->mpExtOldAttrAry = new sal_uInt16[rText.getLength()];
1247 0 : memcpy( pWinData->mpExtOldAttrAry, pTextAttr, rText.getLength()*sizeof( sal_uInt16 ) );
1248 : }
1249 0 : return !ImplCallCommand( pChild, CommandEventId::ExtTextInput, &aData );
1250 : }
1251 :
1252 0 : static bool ImplHandleEndExtTextInput( vcl::Window* /* pWindow */ )
1253 : {
1254 0 : ImplSVData* pSVData = ImplGetSVData();
1255 0 : vcl::Window* pChild = pSVData->maWinData.mpExtTextInputWin;
1256 0 : bool nRet = false;
1257 :
1258 0 : if ( pChild )
1259 : {
1260 0 : pChild->ImplGetWindowImpl()->mbExtTextInput = false;
1261 0 : pSVData->maWinData.mpExtTextInputWin = NULL;
1262 0 : ImplWinData* pWinData = pChild->ImplGetWinData();
1263 0 : if ( pWinData->mpExtOldText )
1264 : {
1265 0 : delete pWinData->mpExtOldText;
1266 0 : pWinData->mpExtOldText = NULL;
1267 : }
1268 0 : if ( pWinData->mpExtOldAttrAry )
1269 : {
1270 0 : delete [] pWinData->mpExtOldAttrAry;
1271 0 : pWinData->mpExtOldAttrAry = NULL;
1272 : }
1273 0 : nRet = !ImplCallCommand( pChild, CommandEventId::EndExtTextInput );
1274 : }
1275 :
1276 0 : return nRet;
1277 : }
1278 :
1279 0 : static void ImplHandleExtTextInputPos( vcl::Window* pWindow,
1280 : Rectangle& rRect, long& rInputWidth,
1281 : bool * pVertical )
1282 : {
1283 0 : ImplSVData* pSVData = ImplGetSVData();
1284 0 : vcl::Window* pChild = pSVData->maWinData.mpExtTextInputWin;
1285 :
1286 0 : if ( !pChild )
1287 0 : pChild = ImplGetKeyInputWindow( pWindow );
1288 : else
1289 : {
1290 : // Test, if the Window is related to the frame
1291 0 : if ( !pWindow->ImplIsWindowOrChild( pChild ) )
1292 0 : pChild = ImplGetKeyInputWindow( pWindow );
1293 : }
1294 :
1295 0 : if ( pChild )
1296 : {
1297 0 : const OutputDevice *pChildOutDev = pChild->GetOutDev();
1298 0 : ImplCallCommand( pChild, CommandEventId::CursorPos );
1299 0 : const Rectangle* pRect = pChild->GetCursorRect();
1300 0 : if ( pRect )
1301 0 : rRect = pChildOutDev->ImplLogicToDevicePixel( *pRect );
1302 : else
1303 : {
1304 0 : vcl::Cursor* pCursor = pChild->GetCursor();
1305 0 : if ( pCursor )
1306 : {
1307 0 : Point aPos = pChildOutDev->ImplLogicToDevicePixel( pCursor->GetPos() );
1308 0 : Size aSize = pChild->LogicToPixel( pCursor->GetSize() );
1309 0 : if ( !aSize.Width() )
1310 0 : aSize.Width() = pChild->GetSettings().GetStyleSettings().GetCursorSize();
1311 0 : rRect = Rectangle( aPos, aSize );
1312 : }
1313 : else
1314 0 : rRect = Rectangle( Point( pChild->GetOutOffXPixel(), pChild->GetOutOffYPixel() ), Size() );
1315 : }
1316 0 : rInputWidth = pChild->ImplLogicWidthToDevicePixel( pChild->GetCursorExtTextInputWidth() );
1317 0 : if ( !rInputWidth )
1318 0 : rInputWidth = rRect.GetWidth();
1319 : }
1320 0 : if (pVertical != 0)
1321 : *pVertical
1322 0 : = pChild != 0 && pChild->GetInputContext().GetFont().IsVertical();
1323 0 : }
1324 :
1325 0 : static bool ImplHandleInputContextChange( vcl::Window* pWindow, LanguageType eNewLang )
1326 : {
1327 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
1328 0 : CommandInputContextData aData( eNewLang );
1329 0 : return !ImplCallCommand( pChild, CommandEventId::InputContextChange, &aData );
1330 : }
1331 :
1332 0 : static bool ImplCallWheelCommand( vcl::Window* pWindow, const Point& rPos,
1333 : const CommandWheelData* pWheelData )
1334 : {
1335 0 : Point aCmdMousePos = pWindow->ImplFrameToOutput( rPos );
1336 0 : CommandEvent aCEvt( aCmdMousePos, CommandEventId::Wheel, true, pWheelData );
1337 0 : NotifyEvent aNCmdEvt( MouseNotifyEvent::COMMAND, pWindow, &aCEvt );
1338 0 : ImplDelData aDelData( pWindow );
1339 0 : bool bPreNotify = ImplCallPreNotify( aNCmdEvt );
1340 0 : if ( aDelData.IsDead() )
1341 0 : return false;
1342 0 : if ( !bPreNotify )
1343 : {
1344 0 : pWindow->ImplGetWindowImpl()->mbCommand = false;
1345 0 : pWindow->Command( aCEvt );
1346 0 : if ( aDelData.IsDead() )
1347 0 : return false;
1348 0 : if ( pWindow->ImplGetWindowImpl()->mbCommand )
1349 0 : return true;
1350 : }
1351 0 : return false;
1352 : }
1353 :
1354 0 : static bool acceptableWheelScrollTarget(const vcl::Window *pMouseWindow)
1355 : {
1356 0 : return (pMouseWindow && pMouseWindow->IsInputEnabled() && !pMouseWindow->IsInModalMode());
1357 : }
1358 :
1359 : //If the last event at the same absolute screen position was handled by a
1360 : //different window then reuse that window if the event occurs within 1/2 a
1361 : //second, i.e. so scrolling down something like the calc sidebar that contains
1362 : //widgets that respond to wheel events will continue to send the event to the
1363 : //scrolling widget in favour of the widget that happens to end up under the
1364 : //mouse.
1365 0 : static bool shouldReusePreviousMouseWindow(const SalWheelMouseEvent& rPrevEvt, const SalWheelMouseEvent& rEvt)
1366 : {
1367 0 : return (rEvt.mnX == rPrevEvt.mnX && rEvt.mnY == rPrevEvt.mnY && rEvt.mnTime-rPrevEvt.mnTime < 500/*ms*/);
1368 : }
1369 :
1370 : class HandleGestureEventBase
1371 : {
1372 : protected:
1373 : ImplSVData* m_pSVData;
1374 : VclPtr<vcl::Window> m_pWindow;
1375 : Point m_aMousePos;
1376 :
1377 : public:
1378 0 : HandleGestureEventBase(vcl::Window *pWindow, const Point &rMousePos)
1379 0 : : m_pSVData(ImplGetSVData())
1380 : , m_pWindow(pWindow)
1381 0 : , m_aMousePos(rMousePos)
1382 : {
1383 0 : }
1384 : bool Setup();
1385 : vcl::Window* FindTarget();
1386 : vcl::Window* Dispatch(vcl::Window* pTarget);
1387 : virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) = 0;
1388 0 : virtual ~HandleGestureEventBase() {}
1389 : };
1390 :
1391 0 : bool HandleGestureEventBase::Setup()
1392 : {
1393 0 : ImplDelData aDogTag( m_pWindow );
1394 :
1395 0 : if (m_pSVData->maWinData.mpAutoScrollWin)
1396 0 : m_pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1397 0 : if (m_pSVData->maHelpData.mpHelpWin)
1398 0 : ImplDestroyHelpWindow( true );
1399 0 : if (aDogTag.IsDead())
1400 0 : return false;
1401 0 : return true;
1402 : }
1403 :
1404 0 : vcl::Window* HandleGestureEventBase::FindTarget()
1405 : {
1406 : // first check any floating window ( eg. drop down listboxes)
1407 0 : vcl::Window *pMouseWindow = NULL;
1408 :
1409 0 : if (m_pSVData->maWinData.mpFirstFloat && !m_pSVData->maWinData.mpCaptureWin &&
1410 0 : !m_pSVData->maWinData.mpFirstFloat->ImplIsFloatPopupModeWindow( m_pWindow ) )
1411 : {
1412 0 : HitTest nHitTest = HITTEST_OUTSIDE;
1413 0 : pMouseWindow = m_pSVData->maWinData.mpFirstFloat->ImplFloatHitTest( m_pWindow, m_aMousePos, nHitTest );
1414 0 : if (!pMouseWindow)
1415 0 : pMouseWindow = m_pSVData->maWinData.mpFirstFloat;
1416 : }
1417 : // then try the window directly beneath the mouse
1418 0 : if( !pMouseWindow )
1419 : {
1420 0 : pMouseWindow = m_pWindow->ImplFindWindow( m_aMousePos );
1421 : }
1422 : else
1423 : {
1424 : // transform coordinates to float window frame coordinates
1425 : pMouseWindow = pMouseWindow->ImplFindWindow(
1426 : pMouseWindow->OutputToScreenPixel(
1427 : pMouseWindow->AbsoluteScreenToOutputPixel(
1428 : m_pWindow->OutputToAbsoluteScreenPixel(
1429 0 : m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
1430 : }
1431 :
1432 0 : while (acceptableWheelScrollTarget(pMouseWindow))
1433 : {
1434 0 : if (pMouseWindow->IsEnabled())
1435 0 : break;
1436 : //try the parent if this one is disabled
1437 0 : pMouseWindow = pMouseWindow->GetParent();
1438 : }
1439 :
1440 0 : return pMouseWindow;
1441 : }
1442 :
1443 0 : vcl::Window *HandleGestureEventBase::Dispatch(vcl::Window* pMouseWindow)
1444 : {
1445 0 : vcl::Window *pDispatchedTo = NULL;
1446 :
1447 0 : if (acceptableWheelScrollTarget(pMouseWindow) && pMouseWindow->IsEnabled())
1448 : {
1449 : // transform coordinates to float window frame coordinates
1450 : Point aRelMousePos( pMouseWindow->OutputToScreenPixel(
1451 : pMouseWindow->AbsoluteScreenToOutputPixel(
1452 : m_pWindow->OutputToAbsoluteScreenPixel(
1453 0 : m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
1454 0 : bool bPropogate = CallCommand(pMouseWindow, aRelMousePos);
1455 0 : if (!bPropogate)
1456 0 : pDispatchedTo = pMouseWindow;
1457 : }
1458 :
1459 : // if the command was not handled try the focus window
1460 0 : if (!pDispatchedTo)
1461 : {
1462 0 : vcl::Window* pFocusWindow = m_pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1463 0 : if ( pFocusWindow && (pFocusWindow != pMouseWindow) &&
1464 0 : (pFocusWindow == m_pSVData->maWinData.mpFocusWin) )
1465 : {
1466 : // no wheel-messages to disabled windows
1467 0 : if ( pFocusWindow->IsEnabled() && pFocusWindow->IsInputEnabled() && ! pFocusWindow->IsInModalMode() )
1468 : {
1469 : // transform coordinates to focus window frame coordinates
1470 : Point aRelMousePos( pFocusWindow->OutputToScreenPixel(
1471 : pFocusWindow->AbsoluteScreenToOutputPixel(
1472 : m_pWindow->OutputToAbsoluteScreenPixel(
1473 0 : m_pWindow->ScreenToOutputPixel( m_aMousePos ) ) ) ) );
1474 0 : bool bPropogate = CallCommand(pFocusWindow, aRelMousePos);
1475 0 : if (!bPropogate)
1476 0 : pDispatchedTo = pMouseWindow;
1477 : }
1478 : }
1479 : }
1480 0 : return pDispatchedTo;
1481 : }
1482 :
1483 0 : class HandleWheelEvent : public HandleGestureEventBase
1484 : {
1485 : private:
1486 : CommandWheelData m_aWheelData;
1487 : public:
1488 0 : HandleWheelEvent(vcl::Window *pWindow, const SalWheelMouseEvent& rEvt, bool bScaleDirectly)
1489 0 : : HandleGestureEventBase(pWindow, Point(rEvt.mnX, rEvt.mnY))
1490 : {
1491 : CommandWheelMode nMode;
1492 0 : sal_uInt16 nCode = rEvt.mnCode;
1493 0 : bool bHorz = rEvt.mbHorz;
1494 0 : bool bPixel = rEvt.mbDeltaIsPixel;
1495 0 : if (bScaleDirectly)
1496 0 : nMode = CommandWheelMode::ZOOM_SCALE;
1497 0 : else if ( nCode & KEY_MOD1 )
1498 0 : nMode = CommandWheelMode::ZOOM;
1499 0 : else if ( nCode & KEY_MOD2 )
1500 0 : nMode = CommandWheelMode::DATAZOOM;
1501 : else
1502 : {
1503 0 : nMode = CommandWheelMode::SCROLL;
1504 : // #i85450# interpret shift-wheel as horizontal wheel action
1505 0 : if( (nCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)) == KEY_SHIFT )
1506 0 : bHorz = true;
1507 : }
1508 :
1509 0 : m_aWheelData = CommandWheelData(rEvt.mnDelta, rEvt.mnNotchDelta, rEvt.mnScrollLines, nMode, nCode, bHorz, bPixel);
1510 :
1511 0 : }
1512 0 : virtual bool CallCommand(vcl::Window *pWindow, const Point &rMousePos) SAL_OVERRIDE
1513 : {
1514 0 : return ImplCallWheelCommand(pWindow, rMousePos, &m_aWheelData);
1515 : }
1516 : bool HandleEvent(const SalWheelMouseEvent& rEvt);
1517 : };
1518 :
1519 0 : bool HandleWheelEvent::HandleEvent(const SalWheelMouseEvent& rEvt)
1520 : {
1521 0 : static SalWheelMouseEvent aPreviousEvent;
1522 : static vcl::Window *pPreviousWindow;
1523 :
1524 0 : if (!Setup())
1525 0 : return false;
1526 :
1527 0 : vcl::Window *pMouseWindow = FindTarget();
1528 :
1529 : // avoid the problem that scrolling via wheel to this point brings a widget
1530 : // under the mouse that also accepts wheel commands, so stick with the old
1531 : // widget if the time gap is very small
1532 0 : if (shouldReusePreviousMouseWindow(aPreviousEvent, rEvt) && acceptableWheelScrollTarget(pPreviousWindow))
1533 : {
1534 0 : pMouseWindow = pPreviousWindow;
1535 : }
1536 :
1537 0 : aPreviousEvent = rEvt;
1538 :
1539 0 : pPreviousWindow = Dispatch(pMouseWindow);
1540 :
1541 0 : return pPreviousWindow != NULL;
1542 : }
1543 :
1544 0 : class HandleGestureEvent : public HandleGestureEventBase
1545 : {
1546 : public:
1547 0 : HandleGestureEvent(vcl::Window *pWindow, const Point &rMousePos)
1548 0 : : HandleGestureEventBase(pWindow, rMousePos)
1549 : {
1550 0 : }
1551 : bool HandleEvent();
1552 : };
1553 :
1554 0 : bool HandleGestureEvent::HandleEvent()
1555 : {
1556 0 : if (!Setup())
1557 0 : return false;
1558 :
1559 0 : vcl::Window *pTarget = FindTarget();
1560 :
1561 0 : bool bHandled = Dispatch(pTarget) != NULL;
1562 0 : return bHandled;
1563 : }
1564 :
1565 0 : static bool ImplHandleWheelEvent( vcl::Window* pWindow, const SalWheelMouseEvent& rEvt, bool scaleDirectly = false )
1566 : {
1567 0 : HandleWheelEvent aHandler(pWindow, rEvt, scaleDirectly);
1568 0 : return aHandler.HandleEvent(rEvt);
1569 : }
1570 :
1571 0 : class HandleSwipeEvent : public HandleGestureEvent
1572 : {
1573 : private:
1574 : CommandSwipeData m_aSwipeData;
1575 : public:
1576 0 : HandleSwipeEvent(vcl::Window *pWindow, const SalSwipeEvent& rEvt)
1577 0 : : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY))
1578 : {
1579 0 : m_aSwipeData = CommandSwipeData(rEvt.mnVelocityX, rEvt.mnVelocityY);
1580 0 : }
1581 0 : virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) SAL_OVERRIDE
1582 : {
1583 0 : return ImplCallCommand(pWindow, CommandEventId::Swipe, &m_aSwipeData);
1584 : }
1585 : };
1586 :
1587 0 : static bool ImplHandleSwipe(vcl::Window *pWindow, const SalSwipeEvent& rEvt)
1588 : {
1589 0 : HandleSwipeEvent aHandler(pWindow, rEvt);
1590 0 : return aHandler.HandleEvent();
1591 : }
1592 :
1593 0 : class HandleLongPressEvent : public HandleGestureEvent
1594 : {
1595 : private:
1596 : CommandLongPressData m_aLongPressData;
1597 : public:
1598 0 : HandleLongPressEvent(vcl::Window *pWindow, const SalLongPressEvent& rEvt)
1599 0 : : HandleGestureEvent(pWindow, Point(rEvt.mnX, rEvt.mnY))
1600 : {
1601 0 : m_aLongPressData = CommandLongPressData(rEvt.mnX, rEvt.mnY);
1602 0 : }
1603 0 : virtual bool CallCommand(vcl::Window *pWindow, const Point &/*rMousePos*/) SAL_OVERRIDE
1604 : {
1605 0 : return ImplCallCommand(pWindow, CommandEventId::LongPress, &m_aLongPressData);
1606 : }
1607 : };
1608 :
1609 0 : static bool ImplHandleLongPress(vcl::Window *pWindow, const SalLongPressEvent& rEvt)
1610 : {
1611 0 : HandleLongPressEvent aHandler(pWindow, rEvt);
1612 0 : return aHandler.HandleEvent();
1613 : }
1614 :
1615 : #define IMPL_PAINT_CHECKRTL ((sal_uInt16)0x0020)
1616 :
1617 2944 : static void ImplHandlePaint( vcl::Window* pWindow, const Rectangle& rBoundRect, bool bImmediateUpdate )
1618 : {
1619 : // give up background save when system paints arrive
1620 2944 : vcl::Window* pSaveBackWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFirstBackWin;
1621 5888 : while ( pSaveBackWin )
1622 : {
1623 0 : vcl::Window* pNext = pSaveBackWin->ImplGetWindowImpl()->mpOverlapData->mpNextBackWin;
1624 : Rectangle aRect( Point( pSaveBackWin->GetOutOffXPixel(), pSaveBackWin->GetOutOffYPixel() ),
1625 0 : Size( pSaveBackWin->GetOutputWidthPixel(), pSaveBackWin->GetOutputHeightPixel() ) );
1626 0 : if ( aRect.IsOver( rBoundRect ) )
1627 0 : pSaveBackWin->ImplDeleteOverlapBackground();
1628 0 : pSaveBackWin = pNext;
1629 : }
1630 :
1631 : // system paint events must be checked for re-mirroring
1632 2944 : pWindow->ImplGetWindowImpl()->mnPaintFlags |= IMPL_PAINT_CHECKRTL;
1633 :
1634 : // trigger paint for all windows that live in the new paint region
1635 2944 : vcl::Region aRegion( rBoundRect );
1636 2944 : pWindow->ImplInvalidateOverlapFrameRegion( aRegion );
1637 2944 : if( bImmediateUpdate )
1638 : {
1639 : // #i87663# trigger possible pending resize notifications
1640 : // (GetSizePixel does that for us)
1641 0 : pWindow->GetSizePixel();
1642 : // force drawing inmmediately
1643 0 : pWindow->Update();
1644 2944 : }
1645 2944 : }
1646 :
1647 6249 : static void KillOwnPopups( vcl::Window* pWindow )
1648 : {
1649 6249 : ImplSVData* pSVData = ImplGetSVData();
1650 6249 : vcl::Window *pParent = pWindow->ImplGetWindowImpl()->mpFrameWindow;
1651 6249 : vcl::Window *pChild = pSVData->maWinData.mpFirstFloat;
1652 6249 : if ( pChild && pParent->ImplIsWindowOrChild( pChild, true ) )
1653 : {
1654 0 : if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose) )
1655 0 : pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
1656 : }
1657 6249 : }
1658 :
1659 12359 : void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
1660 : {
1661 12359 : if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1662 : {
1663 6249 : KillOwnPopups( pWindow );
1664 6249 : if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1665 6249 : ImplDestroyHelpWindow( true );
1666 : }
1667 :
1668 12359 : if (
1669 12369 : (nNewWidth > 0 && nNewHeight > 0) ||
1670 10 : pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize
1671 : )
1672 : {
1673 12355 : if ( (nNewWidth != pWindow->GetOutputWidthPixel()) || (nNewHeight != pWindow->GetOutputHeightPixel()) )
1674 : {
1675 7066 : pWindow->mnOutWidth = nNewWidth;
1676 7066 : pWindow->mnOutHeight = nNewHeight;
1677 7066 : pWindow->ImplGetWindowImpl()->mbWaitSystemResize = false;
1678 7066 : if ( pWindow->IsReallyVisible() )
1679 79 : pWindow->ImplSetClipFlag();
1680 17981 : if ( pWindow->IsVisible() || pWindow->ImplGetWindow()->ImplGetWindowImpl()->mbAllResize ||
1681 7726 : ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow ) ) // propagate resize for system border windows
1682 : {
1683 7052 : bool bStartTimer = true;
1684 : // use resize buffering for user resizes
1685 : // ownerdraw decorated windows and floating windows can be resized immediately (i.e. synchronously)
1686 21156 : if( pWindow->ImplGetWindowImpl()->mbFrame && (pWindow->GetStyle() & WB_SIZEABLE)
1687 3200 : && !(pWindow->GetStyle() & WB_OWNERDRAWDECORATION) // synchronous resize for ownerdraw decorated windows (toolbars)
1688 10252 : && !pWindow->ImplGetWindowImpl()->mbFloatWin ) // synchronous resize for floating windows, #i43799#
1689 : {
1690 3200 : if( pWindow->ImplGetWindowImpl()->mpClientWindow )
1691 : {
1692 : // #i42750# presentation wants to be informed about resize
1693 : // as early as possible
1694 3199 : WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow->ImplGetWindowImpl()->mpClientWindow.get());
1695 3199 : if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1696 0 : bStartTimer = false;
1697 : }
1698 : else
1699 : {
1700 1 : WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pWindow);
1701 1 : if( ! pWorkWindow || pWorkWindow->IsPresentationMode() )
1702 1 : bStartTimer = false;
1703 : }
1704 : }
1705 : else
1706 3852 : bStartTimer = false;
1707 :
1708 7052 : if( bStartTimer )
1709 3199 : pWindow->ImplGetWindowImpl()->mpFrameData->maResizeIdle.Start();
1710 : else
1711 3853 : pWindow->ImplCallResize(); // otherwise menus cannot be positioned
1712 : }
1713 : else
1714 14 : pWindow->ImplGetWindowImpl()->mbCallResize = true;
1715 : }
1716 : }
1717 :
1718 24718 : pWindow->ImplGetWindowImpl()->mpFrameData->mbNeedSysWindow = (nNewWidth < IMPL_MIN_NEEDSYSWIN) ||
1719 24718 : (nNewHeight < IMPL_MIN_NEEDSYSWIN);
1720 12359 : bool bMinimized = (nNewWidth <= 0) || (nNewHeight <= 0);
1721 12359 : if( bMinimized != pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized )
1722 16 : pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplNotifyIconifiedState( bMinimized );
1723 12359 : pWindow->ImplGetWindowImpl()->mpFrameData->mbMinimized = bMinimized;
1724 12359 : }
1725 :
1726 0 : static void ImplHandleMove( vcl::Window* pWindow )
1727 : {
1728 0 : if( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplIsFloatingWindow() && pWindow->IsReallyVisible() )
1729 : {
1730 0 : static_cast<FloatingWindow*>(pWindow)->EndPopupMode( FloatWinPopupEndFlags::TearOff );
1731 0 : pWindow->ImplCallMove();
1732 : }
1733 :
1734 0 : if( pWindow->GetStyle() & (WB_MOVEABLE|WB_SIZEABLE) )
1735 : {
1736 0 : KillOwnPopups( pWindow );
1737 0 : if( pWindow->ImplGetWindow() != ImplGetSVData()->maHelpData.mpHelpWin )
1738 0 : ImplDestroyHelpWindow( true );
1739 : }
1740 :
1741 0 : if ( pWindow->IsVisible() )
1742 0 : pWindow->ImplCallMove();
1743 : else
1744 0 : pWindow->ImplGetWindowImpl()->mbCallMove = true; // make sure the framepos will be updated on the next Show()
1745 :
1746 0 : if ( pWindow->ImplGetWindowImpl()->mbFrame && pWindow->ImplGetWindowImpl()->mpClientWindow )
1747 0 : pWindow->ImplGetWindowImpl()->mpClientWindow->ImplCallMove(); // notify client to update geometry
1748 :
1749 0 : }
1750 :
1751 0 : static void ImplHandleMoveResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight )
1752 : {
1753 0 : ImplHandleMove( pWindow );
1754 0 : ImplHandleResize( pWindow, nNewWidth, nNewHeight );
1755 0 : }
1756 :
1757 2758 : static void ImplActivateFloatingWindows( vcl::Window* pWindow, bool bActive )
1758 : {
1759 : // First check all overlapping windows
1760 2758 : vcl::Window* pTempWindow = pWindow->ImplGetWindowImpl()->mpFirstOverlap;
1761 5516 : while ( pTempWindow )
1762 : {
1763 0 : if ( pTempWindow->GetActivateMode() == ActivateModeFlags::NONE )
1764 : {
1765 0 : if ( (pTempWindow->GetType() == WINDOW_BORDERWINDOW) &&
1766 0 : (pTempWindow->ImplGetWindow()->GetType() == WINDOW_FLOATINGWINDOW) )
1767 0 : static_cast<ImplBorderWindow*>(pTempWindow)->SetDisplayActive( bActive );
1768 : }
1769 :
1770 0 : ImplActivateFloatingWindows( pTempWindow, bActive );
1771 0 : pTempWindow = pTempWindow->ImplGetWindowImpl()->mpNext;
1772 : }
1773 2758 : }
1774 :
1775 5522 : IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl)
1776 : {
1777 2761 : ImplGetWindowImpl()->mpFrameData->mnFocusId = 0;
1778 :
1779 : // If the status has been preserved, because we got back the focus
1780 : // in the meantime, we do nothing
1781 2761 : bool bHasFocus = ImplGetWindowImpl()->mpFrameData->mbHasFocus || ImplGetWindowImpl()->mpFrameData->mbSysObjFocus;
1782 :
1783 : // next execute the delayed functions
1784 2761 : if ( bHasFocus )
1785 : {
1786 : // redraw all floating windows inactive
1787 2734 : if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1788 2733 : ImplActivateFloatingWindows( this, bHasFocus );
1789 :
1790 2734 : if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin )
1791 : {
1792 2734 : bool bHandled = false;
1793 5468 : if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInputEnabled() &&
1794 2734 : ! ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsInModalMode() )
1795 : {
1796 2734 : if ( ImplGetWindowImpl()->mpFrameData->mpFocusWin->IsEnabled() )
1797 : {
1798 2734 : ImplGetWindowImpl()->mpFrameData->mpFocusWin->GrabFocus();
1799 2734 : bHandled = true;
1800 : }
1801 0 : else if( ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplHasDlgCtrl() )
1802 : {
1803 : // #109094# if the focus is restored to a disabled dialog control (was disabled meanwhile)
1804 : // try to move it to the next control
1805 0 : ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplDlgCtrlNextWindow();
1806 0 : bHandled = true;
1807 : }
1808 : }
1809 2734 : if ( !bHandled )
1810 : {
1811 0 : ImplSVData* pSVData = ImplGetSVData();
1812 0 : vcl::Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
1813 0 : if ( ( ! pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode() )
1814 0 : && pSVData->maWinData.mpLastExecuteDlg )
1815 0 : pSVData->maWinData.mpLastExecuteDlg->ToTop( ToTopFlags::RestoreWhenMin | ToTopFlags::GrabFocusOnly);
1816 : else
1817 0 : pTopLevelWindow->GrabFocus();
1818 : }
1819 : }
1820 : else
1821 0 : GrabFocus();
1822 : }
1823 : else
1824 : {
1825 27 : vcl::Window* pFocusWin = ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1826 27 : if ( pFocusWin )
1827 : {
1828 27 : ImplSVData* pSVData = ImplGetSVData();
1829 :
1830 27 : if ( pSVData->maWinData.mpFocusWin == pFocusWin )
1831 : {
1832 : // FocusWindow umsetzen
1833 25 : vcl::Window* pOverlapWindow = pFocusWin->ImplGetFirstOverlapWindow();
1834 25 : pOverlapWindow->ImplGetWindowImpl()->mpLastFocusWindow = pFocusWin;
1835 25 : pSVData->maWinData.mpFocusWin = NULL;
1836 :
1837 25 : if ( pFocusWin->ImplGetWindowImpl()->mpCursor )
1838 13 : pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide( true );
1839 :
1840 : // Deaktivate rufen
1841 25 : vcl::Window* pOldFocusWindow = pFocusWin;
1842 25 : if ( pOldFocusWindow )
1843 : {
1844 25 : vcl::Window* pOldOverlapWindow = pOldFocusWindow->ImplGetFirstOverlapWindow();
1845 25 : vcl::Window* pOldRealWindow = pOldOverlapWindow->ImplGetWindow();
1846 :
1847 25 : pOldOverlapWindow->ImplGetWindowImpl()->mbActive = false;
1848 25 : pOldOverlapWindow->Deactivate();
1849 25 : if ( pOldRealWindow != pOldOverlapWindow )
1850 : {
1851 25 : pOldRealWindow->ImplGetWindowImpl()->mbActive = false;
1852 25 : pOldRealWindow->Deactivate();
1853 : }
1854 : }
1855 :
1856 : // TrackingMode is ended in ImplHandleLoseFocus
1857 : #ifdef _WIN32
1858 : // To avoid problems with the Unix IME
1859 : pFocusWin->EndExtTextInput( EndExtTextInputFlags::Complete );
1860 : #endif
1861 :
1862 : // XXX #102010# hack for accessibility: do not close the menu,
1863 : // even after focus lost
1864 25 : static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE");
1865 25 : if( !(pEnv && *pEnv) )
1866 : {
1867 25 : NotifyEvent aNEvt( MouseNotifyEvent::LOSEFOCUS, pFocusWin );
1868 25 : if ( !ImplCallPreNotify( aNEvt ) )
1869 25 : pFocusWin->CompatLoseFocus();
1870 25 : pFocusWin->ImplCallDeactivateListeners( NULL );
1871 : }
1872 : // XXX
1873 : }
1874 : }
1875 :
1876 : // Redraw all floating window inactive
1877 27 : if ( ImplGetWindowImpl()->mpFrameData->mbStartFocusState != bHasFocus )
1878 25 : ImplActivateFloatingWindows( this, bHasFocus );
1879 : }
1880 :
1881 2761 : return 0;
1882 : }
1883 :
1884 2934 : static void ImplHandleGetFocus( vcl::Window* pWindow )
1885 : {
1886 2934 : pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = true;
1887 :
1888 : // execute Focus-Events after a delay, such that SystemChildWindows
1889 : // do not blink when they receive focus
1890 2934 : if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1891 : {
1892 2932 : pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1893 2932 : pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl ), NULL, true);
1894 2932 : vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1895 2932 : if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1896 5 : pFocusWin->ImplGetWindowImpl()->mpCursor->ImplShow();
1897 : }
1898 2934 : }
1899 :
1900 29 : static void ImplHandleLoseFocus( vcl::Window* pWindow )
1901 : {
1902 29 : ImplSVData* pSVData = ImplGetSVData();
1903 :
1904 : // Abort the autoscroll if the frame loses focus
1905 29 : if ( pSVData->maWinData.mpAutoScrollWin )
1906 0 : pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1907 :
1908 : // Abort tracking if the frame loses focus
1909 29 : if ( pSVData->maWinData.mpTrackWin )
1910 : {
1911 0 : if ( pSVData->maWinData.mpTrackWin->ImplGetWindowImpl()->mpFrameWindow == pWindow )
1912 0 : pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
1913 : }
1914 :
1915 29 : pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus = false;
1916 :
1917 : // execute Focus-Events after a delay, such that SystemChildWindows
1918 : // do not flicker when they receive focus
1919 29 : if ( !pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId )
1920 : {
1921 27 : pWindow->ImplGetWindowImpl()->mpFrameData->mbStartFocusState = !pWindow->ImplGetWindowImpl()->mpFrameData->mbHasFocus;
1922 27 : pWindow->ImplGetWindowImpl()->mpFrameData->mnFocusId = Application::PostUserEvent( LINK( pWindow, vcl::Window, ImplAsyncFocusHdl ), NULL, true );
1923 : }
1924 :
1925 29 : vcl::Window* pFocusWin = pWindow->ImplGetWindowImpl()->mpFrameData->mpFocusWin;
1926 29 : if ( pFocusWin && pFocusWin->ImplGetWindowImpl()->mpCursor )
1927 13 : pFocusWin->ImplGetWindowImpl()->mpCursor->ImplHide( true );
1928 29 : }
1929 :
1930 0 : struct DelayedCloseEvent
1931 : {
1932 : VclPtr<vcl::Window> pWindow;
1933 : ImplDelData aDelData;
1934 : };
1935 :
1936 0 : static sal_IntPtr DelayedCloseEventLink( void* pCEvent, void* )
1937 : {
1938 0 : DelayedCloseEvent* pEv = static_cast<DelayedCloseEvent*>(pCEvent);
1939 :
1940 0 : if( ! pEv->aDelData.IsDead() )
1941 : {
1942 0 : pEv->pWindow->ImplRemoveDel( &pEv->aDelData );
1943 : // dispatch to correct window type
1944 0 : if( pEv->pWindow->IsSystemWindow() )
1945 0 : static_cast<SystemWindow*>(pEv->pWindow.get())->Close();
1946 0 : else if( pEv->pWindow->IsDockingWindow() )
1947 0 : static_cast<DockingWindow*>(pEv->pWindow.get())->Close();
1948 : }
1949 0 : delete pEv;
1950 :
1951 0 : return 0;
1952 : }
1953 :
1954 0 : void ImplHandleClose( vcl::Window* pWindow )
1955 : {
1956 0 : ImplSVData* pSVData = ImplGetSVData();
1957 :
1958 0 : bool bWasPopup = false;
1959 0 : if( pWindow->ImplIsFloatingWindow() &&
1960 0 : static_cast<FloatingWindow*>(pWindow)->ImplIsInPrivatePopupMode() )
1961 : {
1962 0 : bWasPopup = true;
1963 : }
1964 :
1965 : // on Close stop all floating modes and end popups
1966 0 : if ( pSVData->maWinData.mpFirstFloat )
1967 : {
1968 : FloatingWindow* pLastLevelFloat;
1969 0 : pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
1970 0 : pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
1971 : }
1972 0 : if ( pSVData->maHelpData.mbExtHelpMode )
1973 0 : Help::EndExtHelp();
1974 0 : if ( pSVData->maHelpData.mpHelpWin )
1975 0 : ImplDestroyHelpWindow( false );
1976 : // AutoScrollMode
1977 0 : if ( pSVData->maWinData.mpAutoScrollWin )
1978 0 : pSVData->maWinData.mpAutoScrollWin->EndAutoScroll();
1979 :
1980 0 : if ( pSVData->maWinData.mpTrackWin )
1981 0 : pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel | TrackingEventFlags::Key );
1982 :
1983 0 : if (bWasPopup)
1984 0 : return;
1985 :
1986 0 : vcl::Window *pWin = pWindow->ImplGetWindow();
1987 0 : SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(pWin);
1988 0 : if (pSysWin)
1989 : {
1990 : // See if the custom close handler is set.
1991 0 : const Link<>& rLink = pSysWin->GetCloseHdl();
1992 0 : if (rLink.IsSet())
1993 : {
1994 0 : rLink.Call(pSysWin);
1995 0 : return;
1996 : }
1997 : }
1998 :
1999 : // check whether close is allowed
2000 0 : if ( pWin->IsEnabled() && pWin->IsInputEnabled() && !pWin->IsInModalMode() )
2001 : {
2002 0 : DelayedCloseEvent* pEv = new DelayedCloseEvent;
2003 0 : pEv->pWindow = pWin;
2004 0 : pWin->ImplAddDel( &pEv->aDelData );
2005 0 : Application::PostUserEvent( Link<>( pEv, DelayedCloseEventLink ) );
2006 : }
2007 : }
2008 :
2009 94096 : static void ImplHandleUserEvent( ImplSVEvent* pSVEvent )
2010 : {
2011 94096 : if ( pSVEvent )
2012 : {
2013 94096 : if ( pSVEvent->mbCall && !pSVEvent->maDelData.IsDead() )
2014 : {
2015 15390 : if ( pSVEvent->mpWindow )
2016 : {
2017 0 : pSVEvent->mpWindow->ImplRemoveDel( &(pSVEvent->maDelData) );
2018 0 : pSVEvent->mpLink->Call( pSVEvent->mpData );
2019 : }
2020 : else
2021 : {
2022 15390 : pSVEvent->mpLink->Call( pSVEvent->mpData );
2023 : }
2024 : }
2025 :
2026 94096 : delete pSVEvent->mpLink;
2027 94096 : delete pSVEvent;
2028 : }
2029 94096 : }
2030 :
2031 0 : static MouseEventModifiers ImplGetMouseMoveMode( SalMouseEvent* pEvent )
2032 : {
2033 0 : MouseEventModifiers nMode = MouseEventModifiers::NONE;
2034 0 : if ( !pEvent->mnCode )
2035 0 : nMode |= MouseEventModifiers::SIMPLEMOVE;
2036 0 : if ( (pEvent->mnCode & MOUSE_LEFT) && !(pEvent->mnCode & KEY_MOD1) )
2037 0 : nMode |= MouseEventModifiers::DRAGMOVE;
2038 0 : if ( (pEvent->mnCode & MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) )
2039 0 : nMode |= MouseEventModifiers::DRAGCOPY;
2040 0 : return nMode;
2041 : }
2042 :
2043 0 : static MouseEventModifiers ImplGetMouseButtonMode( SalMouseEvent* pEvent )
2044 : {
2045 0 : MouseEventModifiers nMode = MouseEventModifiers::NONE;
2046 0 : if ( pEvent->mnButton == MOUSE_LEFT )
2047 0 : nMode |= MouseEventModifiers::SIMPLECLICK;
2048 0 : if ( (pEvent->mnButton == MOUSE_LEFT) && !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT)) )
2049 0 : nMode |= MouseEventModifiers::SELECT;
2050 0 : if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_MOD1) &&
2051 0 : !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_SHIFT)) )
2052 0 : nMode |= MouseEventModifiers::MULTISELECT;
2053 0 : if ( (pEvent->mnButton == MOUSE_LEFT) && (pEvent->mnCode & KEY_SHIFT) &&
2054 0 : !(pEvent->mnCode & (MOUSE_MIDDLE | MOUSE_RIGHT | KEY_MOD1)) )
2055 0 : nMode |= MouseEventModifiers::RANGESELECT;
2056 0 : return nMode;
2057 : }
2058 :
2059 0 : inline bool ImplHandleSalMouseLeave( vcl::Window* pWindow, SalMouseEvent* pEvent )
2060 : {
2061 : return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, true,
2062 : pEvent->mnX, pEvent->mnY,
2063 : pEvent->mnTime, pEvent->mnCode,
2064 0 : ImplGetMouseMoveMode( pEvent ) );
2065 : }
2066 :
2067 0 : inline bool ImplHandleSalMouseMove( vcl::Window* pWindow, SalMouseEvent* pEvent )
2068 : {
2069 : return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEMOVE, false,
2070 : pEvent->mnX, pEvent->mnY,
2071 : pEvent->mnTime, pEvent->mnCode,
2072 0 : ImplGetMouseMoveMode( pEvent ) );
2073 : }
2074 :
2075 0 : inline bool ImplHandleSalMouseButtonDown( vcl::Window* pWindow, SalMouseEvent* pEvent )
2076 : {
2077 : return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEBUTTONDOWN, false,
2078 : pEvent->mnX, pEvent->mnY,
2079 : pEvent->mnTime,
2080 : #ifdef MACOSX
2081 : pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2082 : #else
2083 : pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2084 : #endif
2085 0 : ImplGetMouseButtonMode( pEvent ) );
2086 : }
2087 :
2088 0 : inline bool ImplHandleSalMouseButtonUp( vcl::Window* pWindow, SalMouseEvent* pEvent )
2089 : {
2090 : return ImplHandleMouseEvent( pWindow, MouseNotifyEvent::MOUSEBUTTONUP, false,
2091 : pEvent->mnX, pEvent->mnY,
2092 : pEvent->mnTime,
2093 : #ifdef MACOSX
2094 : pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3)),
2095 : #else
2096 : pEvent->mnButton | (pEvent->mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)),
2097 : #endif
2098 0 : ImplGetMouseButtonMode( pEvent ) );
2099 : }
2100 :
2101 0 : static bool ImplHandleMenuEvent( vcl::Window* pWindow, SalMenuEvent* pEvent, sal_uInt16 nEvent )
2102 : {
2103 : // Find SystemWindow and its Menubar and let it dispatch the command
2104 0 : bool nRet = false;
2105 0 : vcl::Window *pWin = pWindow->ImplGetWindowImpl()->mpFirstChild;
2106 0 : while ( pWin )
2107 : {
2108 0 : if ( pWin->ImplGetWindowImpl()->mbSysWin )
2109 0 : break;
2110 0 : pWin = pWin->ImplGetWindowImpl()->mpNext;
2111 : }
2112 0 : if( pWin )
2113 : {
2114 0 : MenuBar *pMenuBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
2115 0 : if( pMenuBar )
2116 : {
2117 0 : switch( nEvent )
2118 : {
2119 : case SALEVENT_MENUACTIVATE:
2120 0 : nRet = pMenuBar->HandleMenuActivateEvent( static_cast<Menu*>(pEvent->mpMenu) );
2121 0 : break;
2122 : case SALEVENT_MENUDEACTIVATE:
2123 0 : nRet = pMenuBar->HandleMenuDeActivateEvent( static_cast<Menu*>(pEvent->mpMenu) );
2124 0 : break;
2125 : case SALEVENT_MENUHIGHLIGHT:
2126 0 : nRet = pMenuBar->HandleMenuHighlightEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
2127 0 : break;
2128 : case SALEVENT_MENUBUTTONCOMMAND:
2129 0 : nRet = pMenuBar->HandleMenuButtonEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
2130 0 : break;
2131 : case SALEVENT_MENUCOMMAND:
2132 0 : nRet = pMenuBar->HandleMenuCommandEvent( static_cast<Menu*>(pEvent->mpMenu), pEvent->mnId );
2133 0 : break;
2134 : default:
2135 0 : break;
2136 : }
2137 : }
2138 : }
2139 0 : return nRet;
2140 : }
2141 :
2142 0 : static void ImplHandleSalKeyMod( vcl::Window* pWindow, SalKeyModEvent* pEvent )
2143 : {
2144 0 : ImplSVData* pSVData = ImplGetSVData();
2145 0 : vcl::Window* pTrackWin = pSVData->maWinData.mpTrackWin;
2146 0 : if ( pTrackWin )
2147 0 : pWindow = pTrackWin;
2148 : #ifdef MACOSX
2149 : sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2150 : #else
2151 0 : sal_uInt16 nOldCode = pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2152 : #endif
2153 0 : sal_uInt16 nNewCode = pEvent->mnCode;
2154 0 : if ( nOldCode != nNewCode )
2155 : {
2156 : #ifdef MACOSX
2157 : nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_MOD3);
2158 : #else
2159 0 : nNewCode |= pWindow->ImplGetWindowImpl()->mpFrameData->mnMouseCode & ~(KEY_SHIFT | KEY_MOD1 | KEY_MOD2);
2160 : #endif
2161 0 : pWindow->ImplGetWindowImpl()->mpFrameWindow->ImplCallMouseMove( nNewCode, true );
2162 : }
2163 :
2164 : // #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
2165 :
2166 : // find window
2167 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2168 0 : if ( !pChild )
2169 0 : return;
2170 :
2171 : // send modkey events only if useful data is available
2172 0 : if( pEvent->mnModKeyCode != 0 )
2173 : {
2174 0 : CommandModKeyData data( pEvent->mnModKeyCode );
2175 0 : ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
2176 : }
2177 : }
2178 :
2179 0 : static void ImplHandleInputLanguageChange( vcl::Window* pWindow )
2180 : {
2181 : // find window
2182 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2183 0 : if ( !pChild )
2184 0 : return;
2185 :
2186 0 : ImplCallCommand( pChild, CommandEventId::InputLanguageChange );
2187 : }
2188 :
2189 0 : static void ImplHandleSalSettings( sal_uInt16 nEvent )
2190 : {
2191 0 : Application* pApp = GetpApp();
2192 0 : if ( !pApp )
2193 0 : return;
2194 :
2195 0 : if ( nEvent == SALEVENT_SETTINGSCHANGED )
2196 : {
2197 0 : AllSettings aSettings = Application::GetSettings();
2198 0 : Application::MergeSystemSettings( aSettings );
2199 0 : pApp->OverrideSystemSettings( aSettings );
2200 0 : Application::SetSettings( aSettings );
2201 : }
2202 : else
2203 : {
2204 : DataChangedEventType nType;
2205 0 : switch ( nEvent )
2206 : {
2207 : case SALEVENT_PRINTERCHANGED:
2208 0 : ImplDeletePrnQueueList();
2209 0 : nType = DataChangedEventType::PRINTER;
2210 0 : break;
2211 : case SALEVENT_DISPLAYCHANGED:
2212 0 : nType = DataChangedEventType::DISPLAY;
2213 0 : break;
2214 : case SALEVENT_FONTCHANGED:
2215 0 : OutputDevice::ImplUpdateAllFontData( true );
2216 0 : nType = DataChangedEventType::FONTS;
2217 0 : break;
2218 : default:
2219 0 : nType = DataChangedEventType::NONE;
2220 0 : break;
2221 : }
2222 :
2223 0 : if ( nType != DataChangedEventType::NONE )
2224 : {
2225 0 : DataChangedEvent aDCEvt( nType );
2226 0 : Application::NotifyAllWindows( aDCEvt );
2227 : }
2228 : }
2229 : }
2230 :
2231 0 : static void ImplHandleSalExtTextInputPos( vcl::Window* pWindow, SalExtTextInputPosEvent* pEvt )
2232 : {
2233 0 : Rectangle aCursorRect;
2234 0 : ImplHandleExtTextInputPos( pWindow, aCursorRect, pEvt->mnExtWidth, &pEvt->mbVertical );
2235 0 : if ( aCursorRect.IsEmpty() )
2236 : {
2237 0 : pEvt->mnX = -1;
2238 0 : pEvt->mnY = -1;
2239 0 : pEvt->mnWidth = -1;
2240 0 : pEvt->mnHeight = -1;
2241 : }
2242 : else
2243 : {
2244 0 : pEvt->mnX = aCursorRect.Left();
2245 0 : pEvt->mnY = aCursorRect.Top();
2246 0 : pEvt->mnWidth = aCursorRect.GetWidth();
2247 0 : pEvt->mnHeight = aCursorRect.GetHeight();
2248 : }
2249 0 : }
2250 :
2251 0 : static bool ImplHandleShowDialog( vcl::Window* pWindow, ShowDialogId nDialogId )
2252 : {
2253 0 : if( ! pWindow )
2254 0 : return false;
2255 :
2256 0 : if( pWindow->GetType() == WINDOW_BORDERWINDOW )
2257 : {
2258 0 : vcl::Window* pWrkWin = pWindow->GetWindow( GetWindowType::Client );
2259 0 : if( pWrkWin )
2260 0 : pWindow = pWrkWin;
2261 : }
2262 0 : CommandDialogData aCmdData( nDialogId );
2263 0 : return ImplCallCommand( pWindow, CommandEventId::ShowDialog, &aCmdData );
2264 : }
2265 :
2266 0 : static void ImplHandleSurroundingTextRequest( vcl::Window *pWindow,
2267 : OUString& rText,
2268 : Selection &rSelRange )
2269 : {
2270 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2271 :
2272 0 : if ( !pChild )
2273 : {
2274 0 : rText.clear();
2275 0 : rSelRange.setMin( 0 );
2276 0 : rSelRange.setMax( 0 );
2277 : }
2278 : else
2279 : {
2280 0 : rText = pChild->GetSurroundingText();
2281 0 : Selection aSel = pChild->GetSurroundingTextSelection();
2282 0 : rSelRange.setMin( aSel.Min() );
2283 0 : rSelRange.setMax( aSel.Max() );
2284 : }
2285 0 : }
2286 :
2287 0 : static void ImplHandleSalSurroundingTextRequest( vcl::Window *pWindow,
2288 : SalSurroundingTextRequestEvent *pEvt )
2289 : {
2290 0 : Selection aSelRange;
2291 0 : ImplHandleSurroundingTextRequest( pWindow, pEvt->maText, aSelRange );
2292 :
2293 0 : aSelRange.Justify();
2294 :
2295 0 : if( aSelRange.Min() < 0 )
2296 0 : pEvt->mnStart = 0;
2297 0 : else if( aSelRange.Min() > pEvt->maText.getLength() )
2298 0 : pEvt->mnStart = pEvt->maText.getLength();
2299 : else
2300 0 : pEvt->mnStart = aSelRange.Min();
2301 :
2302 0 : if( aSelRange.Max() < 0 )
2303 0 : pEvt->mnStart = 0;
2304 0 : else if( aSelRange.Max() > pEvt->maText.getLength() )
2305 0 : pEvt->mnEnd = pEvt->maText.getLength();
2306 : else
2307 0 : pEvt->mnEnd = aSelRange.Max();
2308 0 : }
2309 :
2310 0 : static void ImplHandleSurroundingTextSelectionChange( vcl::Window *pWindow,
2311 : sal_uLong nStart,
2312 : sal_uLong nEnd )
2313 : {
2314 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2315 0 : if( pChild )
2316 : {
2317 0 : CommandSelectionChangeData data( nStart, nEnd );
2318 0 : ImplCallCommand( pChild, CommandEventId::SelectionChange, &data );
2319 : }
2320 0 : }
2321 :
2322 0 : static void ImplHandleStartReconversion( vcl::Window *pWindow )
2323 : {
2324 0 : vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
2325 0 : if( pChild )
2326 0 : ImplCallCommand( pChild, CommandEventId::PrepareReconversion );
2327 0 : }
2328 :
2329 0 : static void ImplHandleSalQueryCharPosition( vcl::Window *pWindow,
2330 : SalQueryCharPositionEvent *pEvt )
2331 : {
2332 0 : pEvt->mbValid = false;
2333 0 : pEvt->mbVertical = false;
2334 0 : pEvt->mnCursorBoundX = 0;
2335 0 : pEvt->mnCursorBoundY = 0;
2336 0 : pEvt->mnCursorBoundWidth = 0;
2337 0 : pEvt->mnCursorBoundHeight = 0;
2338 :
2339 0 : ImplSVData* pSVData = ImplGetSVData();
2340 0 : vcl::Window* pChild = pSVData->maWinData.mpExtTextInputWin;
2341 :
2342 0 : if ( !pChild )
2343 0 : pChild = ImplGetKeyInputWindow( pWindow );
2344 : else
2345 : {
2346 : // Test, if the Window is related to the frame
2347 0 : if ( !pWindow->ImplIsWindowOrChild( pChild ) )
2348 0 : pChild = ImplGetKeyInputWindow( pWindow );
2349 : }
2350 :
2351 0 : if( pChild )
2352 : {
2353 0 : ImplCallCommand( pChild, CommandEventId::QueryCharPosition );
2354 :
2355 0 : ImplWinData* pWinData = pChild->ImplGetWinData();
2356 0 : if ( pWinData->mpCompositionCharRects && pEvt->mnCharPos < static_cast<sal_uLong>( pWinData->mnCompositionCharRects ) )
2357 : {
2358 0 : const OutputDevice *pChildOutDev = pChild->GetOutDev();
2359 0 : const Rectangle& aRect = pWinData->mpCompositionCharRects[ pEvt->mnCharPos ];
2360 0 : Rectangle aDeviceRect = pChildOutDev->ImplLogicToDevicePixel( aRect );
2361 0 : Point aAbsScreenPos = pChild->OutputToAbsoluteScreenPixel( pChild->ScreenToOutputPixel(aDeviceRect.TopLeft()) );
2362 0 : pEvt->mnCursorBoundX = aAbsScreenPos.X();
2363 0 : pEvt->mnCursorBoundY = aAbsScreenPos.Y();
2364 0 : pEvt->mnCursorBoundWidth = aDeviceRect.GetWidth();
2365 0 : pEvt->mnCursorBoundHeight = aDeviceRect.GetHeight();
2366 0 : pEvt->mbVertical = pWinData->mbVertical;
2367 0 : pEvt->mbValid = true;
2368 : }
2369 : }
2370 0 : }
2371 :
2372 102953 : bool ImplWindowFrameProc( vcl::Window* _pWindow, SalFrame* /*pFrame*/,
2373 : sal_uInt16 nEvent, const void* pEvent )
2374 : {
2375 : DBG_TESTSOLARMUTEX();
2376 :
2377 : // Ensure the window survives during this method.
2378 102953 : VclPtr<vcl::Window> pWindow( _pWindow );
2379 :
2380 102953 : bool nRet = false;
2381 :
2382 : // #119709# for some unknown reason it is possible to receive events (in this case key events)
2383 : // although the corresponding VCL window must have been destroyed already
2384 : // at least ImplGetWindowImpl() was NULL in these cases, so check this here
2385 102953 : if( pWindow->ImplGetWindowImpl() == NULL )
2386 0 : return false;
2387 :
2388 102953 : switch ( nEvent )
2389 : {
2390 : case SALEVENT_MOUSEMOVE:
2391 0 : nRet = ImplHandleSalMouseMove( pWindow, const_cast<SalMouseEvent *>(static_cast<SalMouseEvent const *>(pEvent)) );
2392 0 : break;
2393 : case SALEVENT_EXTERNALMOUSEMOVE:
2394 : {
2395 0 : MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
2396 : SalMouseEvent aSalMouseEvent;
2397 :
2398 0 : aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
2399 0 : aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2400 0 : aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2401 0 : aSalMouseEvent.mnButton = 0;
2402 0 : aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2403 :
2404 0 : nRet = ImplHandleSalMouseMove( pWindow, &aSalMouseEvent );
2405 : }
2406 0 : break;
2407 : case SALEVENT_MOUSELEAVE:
2408 0 : nRet = ImplHandleSalMouseLeave( pWindow, const_cast<SalMouseEvent *>(static_cast<SalMouseEvent const *>(pEvent)) );
2409 0 : break;
2410 : case SALEVENT_MOUSEBUTTONDOWN:
2411 0 : nRet = ImplHandleSalMouseButtonDown( pWindow, const_cast<SalMouseEvent *>(static_cast<SalMouseEvent const *>(pEvent)) );
2412 0 : break;
2413 : case SALEVENT_EXTERNALMOUSEBUTTONDOWN:
2414 : {
2415 0 : MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
2416 : SalMouseEvent aSalMouseEvent;
2417 :
2418 0 : aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
2419 0 : aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2420 0 : aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2421 0 : aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2422 0 : aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2423 :
2424 0 : nRet = ImplHandleSalMouseButtonDown( pWindow, &aSalMouseEvent );
2425 : }
2426 0 : break;
2427 : case SALEVENT_MOUSEBUTTONUP:
2428 0 : nRet = ImplHandleSalMouseButtonUp( pWindow, const_cast<SalMouseEvent *>(static_cast<SalMouseEvent const *>(pEvent)) );
2429 0 : break;
2430 : case SALEVENT_EXTERNALMOUSEBUTTONUP:
2431 : {
2432 0 : MouseEvent const * pMouseEvt = static_cast<MouseEvent const *>(pEvent);
2433 : SalMouseEvent aSalMouseEvent;
2434 :
2435 0 : aSalMouseEvent.mnTime = tools::Time::GetSystemTicks();
2436 0 : aSalMouseEvent.mnX = pMouseEvt->GetPosPixel().X();
2437 0 : aSalMouseEvent.mnY = pMouseEvt->GetPosPixel().Y();
2438 0 : aSalMouseEvent.mnButton = pMouseEvt->GetButtons();
2439 0 : aSalMouseEvent.mnCode = pMouseEvt->GetButtons() | pMouseEvt->GetModifier();
2440 :
2441 0 : nRet = ImplHandleSalMouseButtonUp( pWindow, &aSalMouseEvent );
2442 : }
2443 0 : break;
2444 : case SALEVENT_MOUSEACTIVATE:
2445 0 : nRet = false;
2446 0 : break;
2447 : case SALEVENT_KEYINPUT:
2448 : {
2449 0 : SalKeyEvent const * pKeyEvt = static_cast<SalKeyEvent const *>(pEvent);
2450 : nRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYINPUT,
2451 0 : pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, true );
2452 : }
2453 0 : break;
2454 : case SALEVENT_EXTERNALKEYINPUT:
2455 : {
2456 0 : KeyEvent const * pKeyEvt = static_cast<KeyEvent const *>(pEvent);
2457 : nRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYINPUT,
2458 0 : pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), false );
2459 : }
2460 0 : break;
2461 : case SALEVENT_KEYUP:
2462 : {
2463 0 : SalKeyEvent const * pKeyEvt = static_cast<SalKeyEvent const *>(pEvent);
2464 : nRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYUP,
2465 0 : pKeyEvt->mnCode, pKeyEvt->mnCharCode, pKeyEvt->mnRepeat, true );
2466 : }
2467 0 : break;
2468 : case SALEVENT_EXTERNALKEYUP:
2469 : {
2470 0 : KeyEvent const * pKeyEvt = static_cast<KeyEvent const *>(pEvent);
2471 : nRet = ImplHandleKey( pWindow, MouseNotifyEvent::KEYUP,
2472 0 : pKeyEvt->GetKeyCode().GetFullCode(), pKeyEvt->GetCharCode(), pKeyEvt->GetRepeat(), false );
2473 : }
2474 0 : break;
2475 : case SALEVENT_KEYMODCHANGE:
2476 0 : ImplHandleSalKeyMod( pWindow, const_cast<SalKeyModEvent *>(static_cast<SalKeyModEvent const *>(pEvent)) );
2477 0 : break;
2478 :
2479 : case SALEVENT_INPUTLANGUAGECHANGE:
2480 0 : ImplHandleInputLanguageChange( pWindow );
2481 0 : break;
2482 :
2483 : case SALEVENT_MENUACTIVATE:
2484 : case SALEVENT_MENUDEACTIVATE:
2485 : case SALEVENT_MENUHIGHLIGHT:
2486 : case SALEVENT_MENUCOMMAND:
2487 : case SALEVENT_MENUBUTTONCOMMAND:
2488 0 : nRet = ImplHandleMenuEvent( pWindow, const_cast<SalMenuEvent *>(static_cast<SalMenuEvent const *>(pEvent)), nEvent );
2489 0 : break;
2490 :
2491 : case SALEVENT_WHEELMOUSE:
2492 0 : nRet = ImplHandleWheelEvent( pWindow, *static_cast<const SalWheelMouseEvent*>(pEvent));
2493 0 : break;
2494 :
2495 : case SALEVENT_PAINT:
2496 : {
2497 2944 : SalPaintEvent const * pPaintEvt = static_cast<SalPaintEvent const *>(pEvent);
2498 :
2499 2944 : if( AllSettings::GetLayoutRTL() )
2500 : {
2501 : // --- RTL --- (mirror paint rect)
2502 0 : SalFrame* pSalFrame = pWindow->ImplGetWindowImpl()->mpFrame;
2503 0 : const_cast<SalPaintEvent *>(pPaintEvt)->mnBoundX = pSalFrame->maGeometry.nWidth-pPaintEvt->mnBoundWidth-pPaintEvt->mnBoundX;
2504 : }
2505 :
2506 : Rectangle aBoundRect( Point( pPaintEvt->mnBoundX, pPaintEvt->mnBoundY ),
2507 2944 : Size( pPaintEvt->mnBoundWidth, pPaintEvt->mnBoundHeight ) );
2508 2944 : ImplHandlePaint( pWindow, aBoundRect, pPaintEvt->mbImmediateUpdate );
2509 : }
2510 2944 : break;
2511 :
2512 : case SALEVENT_MOVE:
2513 0 : ImplHandleMove( pWindow );
2514 0 : break;
2515 :
2516 : case SALEVENT_RESIZE:
2517 : {
2518 : long nNewWidth;
2519 : long nNewHeight;
2520 2950 : pWindow->ImplGetWindowImpl()->mpFrame->GetClientSize( nNewWidth, nNewHeight );
2521 2950 : ImplHandleResize( pWindow, nNewWidth, nNewHeight );
2522 : }
2523 2950 : break;
2524 :
2525 : case SALEVENT_MOVERESIZE:
2526 : {
2527 0 : SalFrameGeometry g = pWindow->ImplGetWindowImpl()->mpFrame->GetGeometry();
2528 0 : ImplHandleMoveResize( pWindow, g.nWidth, g.nHeight );
2529 : }
2530 0 : break;
2531 :
2532 : case SALEVENT_CLOSEPOPUPS:
2533 : {
2534 0 : KillOwnPopups( pWindow );
2535 : }
2536 0 : break;
2537 :
2538 : case SALEVENT_GETFOCUS:
2539 2934 : ImplHandleGetFocus( pWindow );
2540 2934 : break;
2541 : case SALEVENT_LOSEFOCUS:
2542 29 : ImplHandleLoseFocus( pWindow );
2543 29 : break;
2544 :
2545 : case SALEVENT_CLOSE:
2546 0 : ImplHandleClose( pWindow );
2547 0 : break;
2548 :
2549 : case SALEVENT_SHUTDOWN:
2550 : {
2551 : static bool bInQueryExit = false;
2552 0 : if( !bInQueryExit )
2553 : {
2554 0 : bInQueryExit = true;
2555 0 : if ( GetpApp()->QueryExit() )
2556 : {
2557 : // Message-Schleife beenden
2558 0 : Application::Quit();
2559 0 : return false;
2560 : }
2561 : else
2562 : {
2563 0 : bInQueryExit = false;
2564 0 : return true;
2565 : }
2566 : }
2567 0 : return false;
2568 : }
2569 :
2570 : case SALEVENT_SETTINGSCHANGED:
2571 : case SALEVENT_PRINTERCHANGED:
2572 : case SALEVENT_DISPLAYCHANGED:
2573 : case SALEVENT_FONTCHANGED:
2574 0 : ImplHandleSalSettings( nEvent );
2575 0 : break;
2576 :
2577 : case SALEVENT_USEREVENT:
2578 94096 : ImplHandleUserEvent( const_cast<ImplSVEvent *>(static_cast<ImplSVEvent const *>(pEvent)) );
2579 94096 : break;
2580 :
2581 : case SALEVENT_EXTTEXTINPUT:
2582 : {
2583 0 : SalExtTextInputEvent const * pEvt = static_cast<SalExtTextInputEvent const *>(pEvent);
2584 : nRet = ImplHandleExtTextInput( pWindow,
2585 : pEvt->maText, pEvt->mpTextAttr,
2586 0 : pEvt->mnCursorPos, pEvt->mnCursorFlags );
2587 : }
2588 0 : break;
2589 : case SALEVENT_ENDEXTTEXTINPUT:
2590 0 : nRet = ImplHandleEndExtTextInput( pWindow );
2591 0 : break;
2592 : case SALEVENT_EXTTEXTINPUTPOS:
2593 0 : ImplHandleSalExtTextInputPos( pWindow, const_cast<SalExtTextInputPosEvent *>(static_cast<SalExtTextInputPosEvent const *>(pEvent)) );
2594 0 : break;
2595 : case SALEVENT_INPUTCONTEXTCHANGE:
2596 0 : nRet = ImplHandleInputContextChange( pWindow, static_cast<SalInputContextChangeEvent const *>(pEvent)->meLanguage );
2597 0 : break;
2598 : case SALEVENT_SHOWDIALOG:
2599 : {
2600 0 : ShowDialogId nDialogID = static_cast<ShowDialogId>(reinterpret_cast<sal_IntPtr>(pEvent));
2601 0 : nRet = ImplHandleShowDialog( pWindow, nDialogID );
2602 : }
2603 0 : break;
2604 : case SALEVENT_SURROUNDINGTEXTREQUEST:
2605 0 : ImplHandleSalSurroundingTextRequest( pWindow, const_cast<SalSurroundingTextRequestEvent *>(static_cast<SalSurroundingTextRequestEvent const *>(pEvent)) );
2606 0 : break;
2607 : case SALEVENT_SURROUNDINGTEXTSELECTIONCHANGE:
2608 : {
2609 : SalSurroundingTextSelectionChangeEvent const * pEvt
2610 0 : = static_cast<SalSurroundingTextSelectionChangeEvent const *>(pEvent);
2611 : ImplHandleSurroundingTextSelectionChange( pWindow,
2612 : pEvt->mnStart,
2613 0 : pEvt->mnEnd );
2614 : // Fallthrough really intended?
2615 : }
2616 : case SALEVENT_STARTRECONVERSION:
2617 0 : ImplHandleStartReconversion( pWindow );
2618 0 : break;
2619 : case SALEVENT_EXTERNALZOOM:
2620 : {
2621 0 : ZoomEvent const * pZoomEvent = static_cast<ZoomEvent const *>(pEvent);
2622 0 : SalWheelMouseEvent aSalWheelMouseEvent;
2623 0 : aSalWheelMouseEvent.mnTime = tools::Time::GetSystemTicks();
2624 0 : aSalWheelMouseEvent.mnX = pZoomEvent->GetCenter().getX();
2625 0 : aSalWheelMouseEvent.mnY = pZoomEvent->GetCenter().getY();
2626 : // Pass on the scale as a percentage * 100 of current zoom factor
2627 : // so to assure zoom granularity
2628 0 : aSalWheelMouseEvent.mnDelta = long(double(pZoomEvent->GetScale()) * double(MOBILE_ZOOM_SCALE_MULTIPLIER));
2629 : // Other SalWheelMouseEvent fields ignored when the
2630 : // scaleDirectly parameter to ImplHandleWheelEvent() is
2631 : // true.
2632 0 : nRet = ImplHandleWheelEvent( pWindow, aSalWheelMouseEvent, true );
2633 : }
2634 0 : break;
2635 : case SALEVENT_EXTERNALSCROLL:
2636 : {
2637 0 : ScrollEvent const * pScrollEvent = static_cast<ScrollEvent const *>(pEvent);
2638 0 : SalWheelMouseEvent aSalWheelMouseEvent;
2639 0 : aSalWheelMouseEvent.mnTime = tools::Time::GetSystemTicks();
2640 0 : aSalWheelMouseEvent.mbDeltaIsPixel = true;
2641 : // event location holds delta values instead
2642 0 : aSalWheelMouseEvent.mnX = long(pScrollEvent->GetXOffset());
2643 0 : aSalWheelMouseEvent.mnY = long(pScrollEvent->GetYOffset());
2644 0 : aSalWheelMouseEvent.mnScrollLines = 0;
2645 0 : if (aSalWheelMouseEvent.mnX != 0 || aSalWheelMouseEvent.mnY != 0)
2646 : {
2647 0 : nRet = ImplHandleWheelEvent( pWindow, aSalWheelMouseEvent );
2648 : }
2649 : }
2650 0 : break;
2651 : case SALEVENT_QUERYCHARPOSITION:
2652 0 : ImplHandleSalQueryCharPosition( pWindow, const_cast<SalQueryCharPositionEvent *>(static_cast<SalQueryCharPositionEvent const *>(pEvent)) );
2653 0 : break;
2654 :
2655 : case SALEVENT_SWIPE:
2656 0 : nRet = ImplHandleSwipe(pWindow, *static_cast<const SalSwipeEvent*>(pEvent));
2657 0 : break;
2658 :
2659 : case SALEVENT_LONGPRESS:
2660 0 : nRet = ImplHandleLongPress(pWindow, *static_cast<const SalLongPressEvent*>(pEvent));
2661 0 : break;
2662 :
2663 :
2664 : #ifdef DBG_UTIL
2665 : default:
2666 : SAL_WARN( "vcl.layout", "ImplWindowFrameProc(): unknown event (" << nEvent << ")" );
2667 : break;
2668 : #endif
2669 : }
2670 :
2671 102953 : return nRet;
2672 801 : }
2673 :
2674 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|