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