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 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 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 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 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 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 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 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 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, befor 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 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 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, (ie 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 pocessed 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 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 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 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 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 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 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 ( eg. 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 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 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 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 menues 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 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 1702 static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight ) 1703 { 1704 ImplHandleMove( pWindow ); 1705 ImplHandleResize( pWindow, nNewWidth, nNewHeight ); 1706 } 1707 1708 // ----------------------------------------------------------------------- 1709 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 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 // Deaktivate 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 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 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 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 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 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 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 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 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 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 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 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 2091 static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ ) 2092 { 2093 return sal_False; 2094 } 2095 2096 // ----------------------------------------------------------------------- 2097 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 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 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 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 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 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 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 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 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 2353 static void ImplHandleStartReconversion( Window *pWindow ) 2354 { 2355 Window* pChild = ImplGetKeyInputWindow( pWindow ); 2356 if( pChild ) 2357 ImplCallCommand( pChild, COMMAND_PREPARERECONVERSION ); 2358 } 2359 2360 // ----------------------------------------------------------------------- 2361 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