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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1699 static void ImplHandleMoveResize( Window* pWindow, long nNewWidth, long nNewHeight ) 1700 { 1701 ImplHandleMove( pWindow ); 1702 ImplHandleResize( pWindow, nNewWidth, nNewHeight ); 1703 } 1704 1705 // ----------------------------------------------------------------------- 1706 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 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 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 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 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 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 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 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 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 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 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 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 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 2088 static long ImplHandleSalMouseActivate( Window* /*pWindow*/, SalMouseActivateEvent* /*pEvent*/ ) 2089 { 2090 return sal_False; 2091 } 2092 2093 // ----------------------------------------------------------------------- 2094 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 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 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 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 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 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 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 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 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 2350 static void ImplHandleStartReconversion( Window *pWindow ) 2351 { 2352 Window* pChild = ImplGetKeyInputWindow( pWindow ); 2353 if( pChild ) 2354 ImplCallCommand( pChild, COMMAND_PREPARERECONVERSION ); 2355 } 2356 2357 // ----------------------------------------------------------------------- 2358 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