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