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