1/************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24// MARKER(update_precomp.py): autogen include statement, do not remove 25#include "precompiled_vcl.hxx" 26 27#include <sal/alloca.h> 28 29#include "vcl/window.hxx" 30#include "vcl/svapp.hxx" 31 32#include "aqua/salinst.h" 33#include "aqua/salgdi.h" 34#include "aqua/salframe.h" 35#include "aqua/salframeview.h" 36#include "aqua/aqua11yfactory.h" 37 38#define WHEEL_EVENT_FACTOR 1.5 39 40// for allowing fullscreen support on deployment targets < OSX 10.7 41#if !defined(MAC_OS_X_VERSION_10_7) 42 #define NSWindowCollectionBehaviorFullScreenPrimary (1 << 7) 43 #define NSWindowCollectionBehaviorFullScreenAuxiliary (1 << 8) 44// #define NSFullScreenWindowMask (1 << 14) 45#endif 46 47 48static sal_uInt16 ImplGetModifierMask( unsigned int nMask ) 49{ 50 sal_uInt16 nRet = 0; 51 if( (nMask & NSShiftKeyMask) != 0 ) 52 nRet |= KEY_SHIFT; 53 if( (nMask & NSControlKeyMask) != 0 ) 54 nRet |= KEY_MOD3; 55 if( (nMask & NSAlternateKeyMask) != 0 ) 56 nRet |= KEY_MOD2; 57 if( (nMask & NSCommandKeyMask) != 0 ) 58 nRet |= KEY_MOD1; 59 return nRet; 60} 61 62static sal_uInt16 ImplMapCharCode( sal_Unicode aCode ) 63{ 64 static sal_uInt16 aKeyCodeMap[ 128 ] = 65 { 66 0, 0, 0, 0, 0, 0, 0, 0, 67 KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0, 68 0, 0, 0, 0, 0, 0, 0, 0, 69 0, KEY_TAB, 0, KEY_ESCAPE, 0, 0, 0, 0, 70 KEY_SPACE, 0, 0, 0, 0, 0, 0, 0, 71 0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE, 72 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, 73 KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0, 74 0, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, 75 KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, 76 KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, 77 KEY_X, KEY_Y, KEY_Z, 0, 0, 0, 0, 0, 78 KEY_QUOTELEFT, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, 79 KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, 80 KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, 81 KEY_X, KEY_Y, KEY_Z, 0, 0, 0, KEY_TILDE, KEY_BACKSPACE 82 }; 83 84 // Note: the mapping 0x7f should by rights be KEY_DELETE 85 // however if you press "backspace" 0x7f is reported 86 // whereas for "delete" 0xf728 gets reported 87 88 // Note: the mapping of 0x19 to KEY_TAB is because for unknown reasons 89 // tab alone is reported as 0x09 (as expected) but shift-tab is 90 // reported as 0x19 (end of medium) 91 92 static sal_uInt16 aFunctionKeyCodeMap[ 128 ] = 93 { 94 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4, 95 KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, 96 KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20, 97 KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0, 98 0, 0, 0, 0, 0, 0, 0, KEY_INSERT, 99 KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0, 100 0, 0, 0, 0, 0, KEY_MENU, 0, 0, 101 0, 0, 0, 0, 0, 0, 0, 0, 102 0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 0, 103 0, 0, 0, 0, 0, 0, 0, 0, 104 0, 0, 0, 0, 0, 0, 0, 0, 105 0, 0, 0, 0, 0, 0, 0, 0, 106 0, 0, 0, 0, 0, 0, 0, 0, 107 0, 0, 0, 0, 0, 0, 0, 0, 108 0, 0, 0, 0, 0, 0, 0, 0, 109 0, 0, 0, 0, 0, 0, 0, 0 110 }; 111 112 sal_uInt16 nKeyCode = 0; 113 if( aCode < sizeof( aKeyCodeMap) / sizeof( aKeyCodeMap[0] ) ) 114 nKeyCode = aKeyCodeMap[ aCode ]; 115 else if( aCode >= 0xf700 && aCode < 0xf780 ) 116 nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ]; 117 return nKeyCode; 118} 119 120// store the frame the mouse last entered 121static AquaSalFrame* s_pMouseFrame = NULL; 122// store the last pressed button for enter/exit events 123// which lack that information 124static sal_uInt16 s_nLastButton = 0; 125 126// combinations of keys we need to handle ourselves 127static const struct ExceptionalKey 128{ 129 const sal_uInt16 nKeyCode; 130 const unsigned int nModifierMask; 131} aExceptionalKeys[] = 132{ 133 { KEY_D, NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask }, 134 { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask } 135}; 136 137static AquaSalFrame* getMouseContainerFrame() 138{ 139 int nWindows = 0; 140 NSCountWindows( &nWindows ); 141 int* pWindows = (int*)alloca( nWindows * sizeof(int) ); 142 // note: NSWindowList is supposed to be in z-order front to back 143 NSWindowList( nWindows, pWindows ); 144 AquaSalFrame* pDispatchFrame = NULL; 145 for(int i = 0; i < nWindows && ! pDispatchFrame; i++ ) 146 { 147 NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]]; 148 if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] ) 149 pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame]; 150 } 151 return pDispatchFrame; 152} 153 154@implementation SalFrameWindow 155-(id)initWithSalFrame: (AquaSalFrame*)pFrame 156{ 157 mDraggingDestinationHandler = nil; 158 mpFrame = pFrame; 159 NSRect aRect = { { pFrame->maGeometry.nX, pFrame->maGeometry.nY }, 160 { pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight } }; 161 pFrame->VCLToCocoa( aRect ); 162 NSWindow* pNSWindow = [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ]; 163 [pNSWindow useOptimizedDrawing: YES]; // OSX recommendation when there are no overlapping subviews within the receiver 164 165 // enable OSX>=10.7 fullscreen options if available and useful 166 bool bAllowFullScreen = (0 == (mpFrame->mnStyle & (SAL_FRAME_STYLE_DIALOG | SAL_FRAME_STYLE_TOOLTIP | SAL_FRAME_STYLE_SYSTEMCHILD | SAL_FRAME_STYLE_FLOAT | SAL_FRAME_STYLE_TOOLWINDOW | SAL_FRAME_STYLE_INTRO))); 167 bAllowFullScreen &= (0 == (~mpFrame->mnStyle & (SAL_FRAME_STYLE_SIZEABLE))); 168 bAllowFullScreen &= (mpFrame->mpParent == NULL); 169 const SEL setCollectionBehavior = @selector(setCollectionBehavior:); 170 if( bAllowFullScreen && [pNSWindow respondsToSelector: setCollectionBehavior]) 171 { 172 NSNumber* bMode = [NSNumber numberWithInt:(bAllowFullScreen ? NSWindowCollectionBehaviorFullScreenPrimary : NSWindowCollectionBehaviorFullScreenAuxiliary)]; 173 [pNSWindow performSelector:setCollectionBehavior withObject:bMode]; 174 } 175 176 // disable OSX>=10.7 window restoration until we support it directly 177 const SEL setRestorable = @selector(setRestorable:); 178 if( [pNSWindow respondsToSelector: setRestorable]) { 179 NSNumber* bNO = [NSNumber numberWithBool:NO]; 180 [pNSWindow performSelector:setRestorable withObject:bNO]; 181 } 182 183 return pNSWindow; 184} 185 186-(AquaSalFrame*)getSalFrame 187{ 188 return mpFrame; 189} 190 191-(void)displayIfNeeded 192{ 193 if( GetSalData() && GetSalData()->mpFirstInstance ) 194 { 195 vos::IMutex* pMutex = GetSalData()->mpFirstInstance->GetYieldMutex(); 196 if( pMutex ) 197 { 198 pMutex->acquire(); 199 [super displayIfNeeded]; 200 pMutex->release(); 201 } 202 } 203} 204 205-(BOOL)containsMouse 206{ 207 // is this event actually inside that NSWindow ? 208 NSPoint aPt = [NSEvent mouseLocation]; 209 NSRect aFrameRect = [self frame]; 210 BOOL bInRect = NSPointInRect( aPt, aFrameRect ); 211 return bInRect; 212} 213 214-(BOOL)canBecomeKeyWindow 215{ 216 if( (mpFrame->mnStyle & 217 ( SAL_FRAME_STYLE_FLOAT | 218 SAL_FRAME_STYLE_TOOLTIP | 219 SAL_FRAME_STYLE_INTRO 220 )) == 0 ) 221 return YES; 222 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) != 0 ) 223 return YES; 224 if( mpFrame->mbFullScreen ) 225 return YES; 226 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) 227 return YES; 228 return [super canBecomeKeyWindow]; 229} 230 231-(void)windowDidBecomeKey: (NSNotification*)pNotification 232{ 233 (void)pNotification; 234 YIELD_GUARD; 235 236 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 237 { 238 static const sal_uLong nGuessDocument = SAL_FRAME_STYLE_MOVEABLE| 239 SAL_FRAME_STYLE_SIZEABLE| 240 SAL_FRAME_STYLE_CLOSEABLE; 241 242 if( mpFrame->mpMenu ) 243 mpFrame->mpMenu->setMainMenu(); 244 else if( ! mpFrame->mpParent && 245 ( (mpFrame->mnStyle & nGuessDocument) == nGuessDocument || // set default menu for e.g. help 246 mpFrame->mbFullScreen ) ) // ser default menu for e.g. presentation 247 { 248 AquaSalMenu::setDefaultMenu(); 249 } 250 #if 0 251 // FIXME: we should disable menus while in modal mode 252 // however from down here there is currently no reliable way to 253 // find out when to do this 254 if( (mpFrame->mpParent && mpFrame->mpParent->GetWindow()->IsInModalMode()) ) 255 AquaSalMenu::enableMainMenu( false ); 256 #endif 257 mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 ); 258 mpFrame->SendPaintEvent(); // repaint controls as active 259 } 260} 261 262-(void)windowDidResignKey: (NSNotification*)pNotification 263{ 264 (void)pNotification; 265 YIELD_GUARD; 266 267 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 268 { 269 mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0); 270 mpFrame->SendPaintEvent(); // repaint controls as inactive 271 } 272} 273 274-(void)windowDidChangeScreen: (NSNotification*)pNotification 275{ 276 (void)pNotification; 277 YIELD_GUARD; 278 279 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 280 mpFrame->screenParametersChanged(); 281} 282 283-(void)windowDidMove: (NSNotification*)pNotification 284{ 285 (void)pNotification; 286 YIELD_GUARD; 287 288 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 289 { 290 mpFrame->UpdateFrameGeometry(); 291 mpFrame->CallCallback( SALEVENT_MOVE, 0 ); 292 } 293} 294 295-(void)windowDidResize: (NSNotification*)pNotification 296{ 297 (void)pNotification; 298 YIELD_GUARD; 299 300 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 301 { 302 mpFrame->UpdateFrameGeometry(); 303 mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); 304 mpFrame->SendPaintEvent(); 305 } 306} 307 308-(void)windowDidMiniaturize: (NSNotification*)pNotification 309{ 310 (void)pNotification; 311 YIELD_GUARD; 312 313 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 314 { 315 mpFrame->mbShown = false; 316 mpFrame->UpdateFrameGeometry(); 317 mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); 318 } 319} 320 321-(void)windowDidDeminiaturize: (NSNotification*)pNotification 322{ 323 (void)pNotification; 324 YIELD_GUARD; 325 326 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 327 { 328 mpFrame->mbShown = true; 329 mpFrame->UpdateFrameGeometry(); 330 mpFrame->CallCallback( SALEVENT_RESIZE, 0 ); 331 } 332} 333 334-(BOOL)windowShouldClose: (NSNotification*)pNotification 335{ 336 (void)pNotification; 337 YIELD_GUARD; 338 339 BOOL bRet = YES; 340 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 341 { 342 // #i84461# end possible input 343 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 344 if( AquaSalFrame::isAlive( mpFrame ) ) 345 { 346 mpFrame->CallCallback( SALEVENT_CLOSE, 0 ); 347 bRet = NO; // application will close the window or not, AppKit shouldn't 348 } 349 } 350 351 return bRet; 352} 353 354-(void)windowDidEnterFullScreen: (NSNotification*)pNotification 355{ 356 YIELD_GUARD; 357 358 if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) 359 return; 360 mpFrame->mbFullScreen = true; 361 (void)pNotification; 362} 363 364-(void)windowDidExitFullScreen: (NSNotification*)pNotification 365{ 366 YIELD_GUARD; 367 368 if( !mpFrame || !AquaSalFrame::isAlive( mpFrame)) 369 return; 370 mpFrame->mbFullScreen = false; 371 (void)pNotification; 372} 373 374-(void)dockMenuItemTriggered: (id)sender 375{ 376 (void)sender; 377 YIELD_GUARD; 378 379 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 380 mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS ); 381} 382 383-(::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >)accessibleContext 384{ 385 return mpFrame -> GetWindow() -> GetAccessible() -> getAccessibleContext(); 386} 387 388-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 389{ 390 return [mDraggingDestinationHandler draggingEntered: sender]; 391} 392 393-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 394{ 395 return [mDraggingDestinationHandler draggingUpdated: sender]; 396} 397 398-(void)draggingExited:(id <NSDraggingInfo>)sender 399{ 400 [mDraggingDestinationHandler draggingExited: sender]; 401} 402 403-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 404{ 405 return [mDraggingDestinationHandler prepareForDragOperation: sender]; 406} 407 408-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender 409{ 410 return [mDraggingDestinationHandler performDragOperation: sender]; 411} 412 413-(void)concludeDragOperation:(id <NSDraggingInfo>)sender 414{ 415 [mDraggingDestinationHandler concludeDragOperation: sender]; 416} 417 418-(void)registerDraggingDestinationHandler:(id)theHandler 419{ 420 mDraggingDestinationHandler = theHandler; 421} 422 423-(void)unregisterDraggingDestinationHandler:(id)theHandler 424{ 425 (void)theHandler; 426 mDraggingDestinationHandler = nil; 427} 428 429@end 430 431@implementation SalFrameView 432+(void)unsetMouseFrame: (AquaSalFrame*)pFrame 433{ 434 if( pFrame == s_pMouseFrame ) 435 s_pMouseFrame = NULL; 436} 437 438-(id)initWithSalFrame: (AquaSalFrame*)pFrame 439{ 440 if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [pFrame->getWindow() frame] styleMask: pFrame->mnStyleMask]]) != nil) 441 { 442 mDraggingDestinationHandler = nil; 443 mpFrame = pFrame; 444 mMarkedRange = NSMakeRange(NSNotFound, 0); 445 mSelectedRange = NSMakeRange(NSNotFound, 0); 446 mpReferenceWrapper = nil; 447 mpMouseEventListener = nil; 448 mpLastSuperEvent = nil; 449 } 450 451 mfLastMagnifyTime = 0.0; 452 return self; 453} 454 455-(AquaSalFrame*)getSalFrame 456{ 457 return mpFrame; 458} 459 460-(void)resetCursorRects 461{ 462 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 463 { 464 // FIXME: does this leak the returned NSCursor of getCurrentCursor ? 465 NSRect aRect = { { 0, 0 }, { mpFrame->maGeometry.nWidth, mpFrame->maGeometry.nHeight } }; 466 [self addCursorRect: aRect cursor: mpFrame->getCurrentCursor()]; 467 } 468} 469 470-(BOOL)acceptsFirstResponder 471{ 472 return YES; 473} 474 475-(BOOL)acceptsFirstMouse: (NSEvent*)pEvent 476{ 477 (void)pEvent; 478 return YES; 479} 480 481-(BOOL)isOpaque 482{ 483 if( !mpFrame) 484 return YES; 485 if( !AquaSalFrame::isAlive( mpFrame)) 486 return YES; 487 if( !mpFrame->getClipPath()) 488 return YES; 489 return NO; 490} 491 492// helper class similar to a vos::OGuard for the SalYieldMutex 493// the difference is that it only does tryToAcquire instead of aquire 494// so dreaded deadlocks like #i93512# are prevented 495class TryGuard 496{ 497public: 498 TryGuard() { mbGuarded = ImplSalYieldMutexTryToAcquire(); } 499 ~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); } 500 bool IsGuarded() { return mbGuarded; } 501private: 502 bool mbGuarded; 503}; 504 505-(void)drawRect: (NSRect)aRect 506{ 507 // HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex 508 TryGuard aTryGuard; 509 if( !aTryGuard.IsGuarded() ) 510 { 511 // NOTE: the mpFrame access below is not guarded yet! 512 // TODO: mpFrame et al need to be guarded by an independent mutex 513 AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL; 514 if( pGraphics ) 515 { 516 // we did not get the mutex so we cannot draw now => request to redraw later 517 // convert the NSRect to a CGRect for Refreshrect() 518 const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}}; 519 pGraphics->RefreshRect( aCGRect ); 520 } 521 return; 522 } 523 524 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 525 { 526 if( mpFrame->mpGraphics ) 527 { 528 mpFrame->mpGraphics->UpdateWindow( aRect ); 529 if( mpFrame->getClipPath() ) 530 [mpFrame->getWindow() invalidateShadow]; 531 } 532 } 533} 534 535-(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(sal_uInt16)nButton eventtype:(sal_uInt16)nEvent 536{ 537 YIELD_GUARD; 538 539 AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame(); 540 bool bIsCaptured = false; 541 if( pDispatchFrame ) 542 { 543 bIsCaptured = true; 544 if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured 545 nEvent = SALEVENT_MOUSEMOVE; 546 } 547 else if( s_pMouseFrame ) 548 pDispatchFrame = s_pMouseFrame; 549 else 550 pDispatchFrame = mpFrame; 551 552 /* #i81645# Cocoa reports mouse events while a button is pressed 553 to the window in which it was first pressed. This is reasonable and fine and 554 gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer, 555 however vcl expects mouse events to occur in the window the mouse is over, unless the 556 mouse is explicitly captured. So we need to find the window the mouse is actually 557 over for conformance with other platforms. 558 */ 559 if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) ) 560 { 561 // is this event actually inside that NSWindow ? 562 NSPoint aPt = [NSEvent mouseLocation]; 563 NSRect aFrameRect = [pDispatchFrame->getWindow() frame]; 564 565 if ( ! NSPointInRect( aPt, aFrameRect ) ) 566 { 567 // no, it is not 568 // now we need to find the one it may be in 569 /* #i93756# we ant to get enumerate the application windows in z-order 570 to check if any contains the mouse. This could be elegantly done with this 571 code: 572 573 // use NSApp to check windows in ZOrder whether they contain the mouse pointer 574 NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES]; 575 if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] ) 576 pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame]; 577 578 However if a non SalFrameWindow is on screen (like e.g. the file dialog) 579 it can be hit with the containsMouse selector, which it doesn't support. 580 Sadly NSApplication:makeWindowsPerform does not check (for performance reasons 581 I assume) whether a window supports a selector before sending it. 582 */ 583 AquaSalFrame* pMouseFrame = getMouseContainerFrame(); 584 if( pMouseFrame ) 585 pDispatchFrame = pMouseFrame; 586 } 587 } 588 589 if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) ) 590 { 591 pDispatchFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 592 pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags]; 593 594 NSPoint aPt = [NSEvent mouseLocation]; 595 pDispatchFrame->CocoaToVCL( aPt ); 596 597 sal_uInt16 nModMask = ImplGetModifierMask( [pEvent modifierFlags] ); 598 // #i82284# emulate ctrl left 599 if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT ) 600 { 601 nModMask = 0; 602 nButton = MOUSE_RIGHT; 603 } 604 605 SalMouseEvent aEvent; 606 aEvent.mnTime = pDispatchFrame->mnLastEventTime; 607 aEvent.mnX = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX; 608 aEvent.mnY = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY; 609 aEvent.mnButton = nButton; 610 aEvent.mnCode = aEvent.mnButton | nModMask; 611 612 // --- RTL --- (mirror mouse pos) 613 if( Application::GetSettings().GetLayoutRTL() ) 614 aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX; 615 616 pDispatchFrame->CallCallback( nEvent, &aEvent ); 617 } 618} 619 620-(void)mouseDown: (NSEvent*)pEvent 621{ 622 if ( mpMouseEventListener != nil && 623 [mpMouseEventListener respondsToSelector: @selector(mouseDown:)]) 624 { 625 [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]]; 626 } 627 628 s_nLastButton = MOUSE_LEFT; 629 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN]; 630} 631 632-(void)mouseDragged: (NSEvent*)pEvent 633{ 634 if ( mpMouseEventListener != nil && 635 [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)]) 636 { 637 [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]]; 638 } 639 s_nLastButton = MOUSE_LEFT; 640 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE]; 641} 642 643-(void)mouseUp: (NSEvent*)pEvent 644{ 645 s_nLastButton = 0; 646 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP]; 647} 648 649-(void)mouseMoved: (NSEvent*)pEvent 650{ 651 s_nLastButton = 0; 652 [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE]; 653} 654 655-(void)mouseEntered: (NSEvent*)pEvent 656{ 657 s_pMouseFrame = mpFrame; 658 659 // #i107215# the only mouse events we get when inactive are enter/exit 660 // actually we would like to have all of them, but better none than some 661 if( [NSApp isActive] ) 662 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE]; 663} 664 665-(void)mouseExited: (NSEvent*)pEvent 666{ 667 if( s_pMouseFrame == mpFrame ) 668 s_pMouseFrame = NULL; 669 670 // #i107215# the only mouse events we get when inactive are enter/exit 671 // actually we would like to have all of them, but better none than some 672 if( [NSApp isActive] ) 673 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE]; 674} 675 676-(void)rightMouseDown: (NSEvent*)pEvent 677{ 678 s_nLastButton = MOUSE_RIGHT; 679 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN]; 680} 681 682-(void)rightMouseDragged: (NSEvent*)pEvent 683{ 684 s_nLastButton = MOUSE_RIGHT; 685 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE]; 686} 687 688-(void)rightMouseUp: (NSEvent*)pEvent 689{ 690 s_nLastButton = 0; 691 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP]; 692} 693 694-(void)otherMouseDown: (NSEvent*)pEvent 695{ 696 if( [pEvent buttonNumber] == 2 ) 697 { 698 s_nLastButton = MOUSE_MIDDLE; 699 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN]; 700 } 701 else 702 s_nLastButton = 0; 703} 704 705-(void)otherMouseDragged: (NSEvent*)pEvent 706{ 707 if( [pEvent buttonNumber] == 2 ) 708 { 709 s_nLastButton = MOUSE_MIDDLE; 710 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE]; 711 } 712 else 713 s_nLastButton = 0; 714} 715 716-(void)otherMouseUp: (NSEvent*)pEvent 717{ 718 s_nLastButton = 0; 719 if( [pEvent buttonNumber] == 2 ) 720 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP]; 721} 722 723- (void)magnifyWithEvent: (NSEvent*)pEvent 724{ 725 YIELD_GUARD; 726 727 // TODO: ?? -(float)magnification; 728 if( AquaSalFrame::isAlive( mpFrame ) ) 729 { 730 const NSTimeInterval fMagnifyTime = [pEvent timestamp]; 731 mpFrame->mnLastEventTime = static_cast<sal_uLong>( fMagnifyTime * 1000.0 ); 732 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 733 734 // check if this is a new series of magnify events 735 static const NSTimeInterval fMaxDiffTime = 0.3; 736 const bool bNewSeries = (fMagnifyTime - mfLastMagnifyTime > fMaxDiffTime); 737 738 if( bNewSeries ) 739 mfMagnifyDeltaSum = 0.0; 740 mfMagnifyDeltaSum += [pEvent deltaZ]; 741 742 mfLastMagnifyTime = [pEvent timestamp]; 743 // TODO: change to 0.1 when COMMAND_WHEEL_ZOOM handlers allow finer zooming control 744 static const float fMagnifyFactor = 0.25; 745 static const float fMinMagnifyStep = 15.0 / fMagnifyFactor; 746 if( fabs(mfMagnifyDeltaSum) <= fMinMagnifyStep ) 747 return; 748 749 // adapt NSEvent-sensitivity to application expectations 750 // TODO: rather make COMMAND_WHEEL_ZOOM handlers smarter 751 const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor; 752 int nDeltaZ = FRound( fDeltaZ ); 753 if( !nDeltaZ ) 754 { 755 // handle new series immediately 756 if( !bNewSeries ) 757 return; 758 nDeltaZ = (fDeltaZ >= 0.0) ? +1 : -1; 759 } 760 // eventually give credit for delta sum 761 mfMagnifyDeltaSum -= nDeltaZ / fMagnifyFactor; 762 763 NSPoint aPt = [NSEvent mouseLocation]; 764 mpFrame->CocoaToVCL( aPt ); 765 766 SalWheelMouseEvent aEvent; 767 aEvent.mnTime = mpFrame->mnLastEventTime; 768 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 769 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 770 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 771 aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling 772 aEvent.mbDeltaIsPixel = TRUE; 773 774 // --- RTL --- (mirror mouse pos) 775 if( Application::GetSettings().GetLayoutRTL() ) 776 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 777 778 aEvent.mnDelta = nDeltaZ; 779 aEvent.mnNotchDelta = (nDeltaZ >= 0) ? +1 : -1; 780 if( aEvent.mnDelta == 0 ) 781 aEvent.mnDelta = aEvent.mnNotchDelta; 782 aEvent.mbHorz = FALSE; 783 aEvent.mnScrollLines = nDeltaZ; 784 if( aEvent.mnScrollLines == 0 ) 785 aEvent.mnScrollLines = 1; 786 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 787 } 788} 789 790- (void)rotateWithEvent: (NSEvent*)pEvent 791{ 792 //Rotation : -(float)rotation; 793 // TODO: create new CommandType so rotation is available to the applications 794 (void)pEvent; 795} 796 797- (void)swipeWithEvent: (NSEvent*)pEvent 798{ 799 YIELD_GUARD; 800 801 if( AquaSalFrame::isAlive( mpFrame ) ) 802 { 803 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 804 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 805 806 // merge pending scroll wheel events 807 float dX = 0.0; 808 float dY = 0.0; 809 for(;;) 810 { 811 dX += [pEvent deltaX]; 812 dY += [pEvent deltaY]; 813 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask 814 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; 815 if( !pNextEvent ) 816 break; 817 pEvent = pNextEvent; 818 } 819 820 NSPoint aPt = [NSEvent mouseLocation]; 821 mpFrame->CocoaToVCL( aPt ); 822 823 SalWheelMouseEvent aEvent; 824 aEvent.mnTime = mpFrame->mnLastEventTime; 825 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 826 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 827 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 828 aEvent.mbDeltaIsPixel = TRUE; 829 830 // --- RTL --- (mirror mouse pos) 831 if( Application::GetSettings().GetLayoutRTL() ) 832 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 833 834 if( dX != 0.0 ) 835 { 836 aEvent.mnDelta = static_cast<long>(floor(dX)); 837 aEvent.mnNotchDelta = dX < 0 ? -1 : 1; 838 if( aEvent.mnDelta == 0 ) 839 aEvent.mnDelta = aEvent.mnNotchDelta; 840 aEvent.mbHorz = TRUE; 841 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 842 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 843 } 844 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame )) 845 { 846 aEvent.mnDelta = static_cast<long>(floor(dY)); 847 aEvent.mnNotchDelta = dY < 0 ? -1 : 1; 848 if( aEvent.mnDelta == 0 ) 849 aEvent.mnDelta = aEvent.mnNotchDelta; 850 aEvent.mbHorz = FALSE; 851 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 852 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 853 } 854 } 855} 856 857-(void)scrollWheel: (NSEvent*)pEvent 858{ 859 YIELD_GUARD; 860 861 if( AquaSalFrame::isAlive( mpFrame ) ) 862 { 863 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 864 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 865 866 // merge pending scroll wheel events 867 float dX = 0.0; 868 float dY = 0.0; 869 for(;;) 870 { 871 dX += [pEvent deltaX]; 872 dY += [pEvent deltaY]; 873 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask 874 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; 875 if( !pNextEvent ) 876 break; 877 pEvent = pNextEvent; 878 } 879 880 NSPoint aPt = [NSEvent mouseLocation]; 881 mpFrame->CocoaToVCL( aPt ); 882 883 SalWheelMouseEvent aEvent; 884 aEvent.mnTime = mpFrame->mnLastEventTime; 885 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 886 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 887 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 888 aEvent.mbDeltaIsPixel = TRUE; 889 890 // --- RTL --- (mirror mouse pos) 891 if( Application::GetSettings().GetLayoutRTL() ) 892 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 893 894 if( dX != 0.0 ) 895 { 896 aEvent.mnDelta = static_cast<long>(floor(dX)); 897 aEvent.mnNotchDelta = dX < 0 ? -1 : 1; 898 if( aEvent.mnDelta == 0 ) 899 aEvent.mnDelta = aEvent.mnNotchDelta; 900 aEvent.mbHorz = TRUE; 901 aEvent.mnScrollLines = dY > 0 ? dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR; 902 if( aEvent.mnScrollLines == 0 ) 903 aEvent.mnScrollLines = 1; 904 905 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 906 } 907 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) ) 908 { 909 aEvent.mnDelta = static_cast<long>(floor(dY)); 910 aEvent.mnNotchDelta = dY < 0 ? -1 : 1; 911 if( aEvent.mnDelta == 0 ) 912 aEvent.mnDelta = aEvent.mnNotchDelta; 913 aEvent.mbHorz = FALSE; 914 aEvent.mnScrollLines = dY > 0 ? dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR; 915 if( aEvent.mnScrollLines < 1 ) 916 aEvent.mnScrollLines = 1; 917 918 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 919 } 920 } 921} 922 923 924-(void)keyDown: (NSEvent*)pEvent 925{ 926 YIELD_GUARD; 927 928 if( AquaSalFrame::isAlive( mpFrame ) ) 929 { 930 mpLastEvent = pEvent; 931 mbInKeyInput = true; 932 mbNeedSpecialKeyHandle = false; 933 mbKeyHandled = false; 934 935 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 936 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 937 938 if( ! [self handleKeyDownException: pEvent] ) 939 { 940 NSArray* pArray = [NSArray arrayWithObject: pEvent]; 941 [self interpretKeyEvents: pArray]; 942 } 943 944 mbInKeyInput = false; 945 } 946} 947 948-(BOOL)handleKeyDownException:(NSEvent*)pEvent 949{ 950 // check for a very special set of modified characters 951 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 952 953 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 954 { 955 /* #i103102# key events with command and alternate don't make it through 956 interpretKeyEvents (why ?). Try to dispatch them here first, 957 if not successful continue normally 958 */ 959 if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask)) 960 == (NSAlternateKeyMask | NSCommandKeyMask) ) 961 { 962 if( [self sendSingleCharacter: mpLastEvent] ) 963 return YES; 964 } 965 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 966 sal_uInt16 nKeyCode = ImplMapCharCode( keyChar ); 967 968 // Caution: should the table grow to more than 5 or 6 entries, 969 // we must consider moving it to a kind of hash map 970 const unsigned int nExceptions = sizeof( aExceptionalKeys ) / sizeof( aExceptionalKeys[0] ); 971 for( unsigned int i = 0; i < nExceptions; i++ ) 972 { 973 if( nKeyCode == aExceptionalKeys[i].nKeyCode && 974 (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask) 975 == aExceptionalKeys[i].nModifierMask ) 976 { 977 [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0]; 978 979 return YES; 980 } 981 } 982 } 983 return NO; 984} 985 986-(void)flagsChanged: (NSEvent*)pEvent 987{ 988 YIELD_GUARD; 989 990 if( AquaSalFrame::isAlive( mpFrame ) ) 991 { 992 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 993 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 994 } 995} 996 997-(void)insertText:(id)aString 998{ 999 YIELD_GUARD; 1000 1001 if( AquaSalFrame::isAlive( mpFrame ) ) 1002 { 1003 NSString* pInsert = nil; 1004 if( [aString isMemberOfClass: [NSAttributedString class]] ) 1005 pInsert = [aString string]; 1006 else 1007 pInsert = aString; 1008 1009 int nLen = 0; 1010 if( pInsert && ( nLen = [pInsert length] ) > 0 ) 1011 { 1012 OUString aInsertString( GetOUString( pInsert ) ); 1013 // aCharCode initializer is safe since aInsertString will at least contain '\0' 1014 sal_Unicode aCharCode = *aInsertString.getStr(); 1015 1016 if( nLen == 1 && 1017 aCharCode < 0x80 && 1018 aCharCode > 0x1f && 1019 ! [self hasMarkedText ] 1020 ) 1021 { 1022 sal_uInt16 nKeyCode = ImplMapCharCode( aCharCode ); 1023 unsigned int nLastModifiers = mpFrame->mnLastModifierFlags; 1024 1025 // #i99567# 1026 // find out the unmodified key code 1027 1028 // sanity check 1029 if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) ) 1030 { 1031 // get unmodified string 1032 NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers]; 1033 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 1034 { 1035 // map the unmodified key code 1036 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 1037 nKeyCode = ImplMapCharCode( keyChar ); 1038 } 1039 nLastModifiers = [mpLastEvent modifierFlags]; 1040 1041 } 1042 // #i99567# 1043 // applications and vcl's edit fields ignore key events with ALT 1044 // however we're at a place where we know text should be inserted 1045 // so it seems we need to strip the Alt modifier here 1046 if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)) 1047 == NSAlternateKeyMask ) 1048 { 1049 nLastModifiers = 0; 1050 } 1051 [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers]; 1052 } 1053 else 1054 { 1055 SalExtTextInputEvent aEvent; 1056 aEvent.mnTime = mpFrame->mnLastEventTime; 1057 aEvent.maText = aInsertString; 1058 aEvent.mpTextAttr = NULL; 1059 aEvent.mnCursorPos = aInsertString.getLength(); 1060 aEvent.mnDeltaStart = 0; 1061 aEvent.mnCursorFlags = 0; 1062 aEvent.mbOnlyCursor = FALSE; 1063 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); 1064 if( AquaSalFrame::isAlive( mpFrame ) ) 1065 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1066 } 1067 } 1068 else 1069 { 1070 SalExtTextInputEvent aEvent; 1071 aEvent.mnTime = mpFrame->mnLastEventTime; 1072 aEvent.maText = String(); 1073 aEvent.mpTextAttr = NULL; 1074 aEvent.mnCursorPos = 0; 1075 aEvent.mnDeltaStart = 0; 1076 aEvent.mnCursorFlags = 0; 1077 aEvent.mbOnlyCursor = FALSE; 1078 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); 1079 if( AquaSalFrame::isAlive( mpFrame ) ) 1080 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1081 1082 } 1083 mbKeyHandled = true; 1084 [self unmarkText]; 1085 } 1086} 1087 1088-(void)insertTab: (id)aSender 1089{ 1090 (void)aSender; 1091 [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0]; 1092} 1093 1094-(void)insertBacktab: (id)aSender 1095{ 1096 (void)aSender; 1097 [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0]; 1098} 1099 1100-(void)moveLeft: (id)aSender 1101{ 1102 (void)aSender; 1103 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0]; 1104} 1105 1106-(void)moveLeftAndModifySelection: (id)aSender 1107{ 1108 (void)aSender; 1109 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask]; 1110} 1111 1112-(void)moveBackwardAndModifySelection: (id)aSender 1113{ 1114 (void)aSender; 1115 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0 modifiers: 0]; 1116} 1117 1118-(void)moveRight: (id)aSender 1119{ 1120 (void)aSender; 1121 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0]; 1122} 1123 1124-(void)moveRightAndModifySelection: (id)aSender 1125{ 1126 (void)aSender; 1127 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask]; 1128} 1129 1130-(void)moveForwardAndModifySelection: (id)aSender 1131{ 1132 (void)aSender; 1133 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0 modifiers: 0]; 1134} 1135 1136-(void)moveWordLeft: (id)aSender 1137{ 1138 (void)aSender; 1139 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0]; 1140} 1141 1142-(void)moveWordBackward: (id)aSender 1143{ 1144 (void)aSender; 1145 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0]; 1146} 1147 1148-(void)moveWordBackwardAndModifySelection: (id)aSender 1149{ 1150 (void)aSender; 1151 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0]; 1152} 1153 1154-(void)moveWordLeftAndModifySelection: (id)aSender 1155{ 1156 (void)aSender; 1157 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0]; 1158} 1159 1160-(void)moveWordRight: (id)aSender 1161{ 1162 (void)aSender; 1163 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0]; 1164} 1165 1166-(void)moveWordForward: (id)aSender 1167{ 1168 (void)aSender; 1169 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0]; 1170} 1171 1172-(void)moveWordForwardAndModifySelection: (id)aSender 1173{ 1174 (void)aSender; 1175 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0]; 1176} 1177 1178-(void)moveWordRightAndModifySelection: (id)aSender 1179{ 1180 (void)aSender; 1181 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0]; 1182} 1183 1184-(void)moveToEndOfLine: (id)aSender 1185{ 1186 (void)aSender; 1187 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0 modifiers: 0]; 1188} 1189 1190-(void)moveToRightEndOfLine: (id)aSender 1191{ 1192 (void)aSender; 1193 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0 modifiers: 0]; 1194} 1195 1196-(void)moveToEndOfLineAndModifySelection: (id)aSender 1197{ 1198 (void)aSender; 1199 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0 modifiers: 0]; 1200} 1201 1202-(void)moveToRightEndOfLineAndModifySelection: (id)aSender 1203{ 1204 (void)aSender; 1205 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0 modifiers: 0]; 1206} 1207 1208-(void)moveToBeginningOfLine: (id)aSender 1209{ 1210 (void)aSender; 1211 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1212} 1213 1214-(void)moveToLeftEndOfLine: (id)aSender 1215{ 1216 (void)aSender; 1217 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1218} 1219 1220-(void)moveToBeginningOfLineAndModifySelection: (id)aSender 1221{ 1222 (void)aSender; 1223 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1224} 1225 1226-(void)moveToLeftEndOfLineAndModifySelection: (id)aSender 1227{ 1228 (void)aSender; 1229 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1230} 1231 1232-(void)moveToEndOfParagraph: (id)aSender 1233{ 1234 (void)aSender; 1235 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1236} 1237 1238-(void)moveToEndOfParagraphAndModifySelection: (id)aSender 1239{ 1240 (void)aSender; 1241 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1242} 1243 1244-(void)moveParagraphForward: (id)aSender 1245{ 1246 (void)aSender; 1247 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1248} 1249 1250-(void)moveParagraphForwardAndModifySelection: (id)aSender 1251{ 1252 (void)aSender; 1253 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1254} 1255 1256-(void)moveToBeginningOfParagraph: (id)aSender 1257{ 1258 (void)aSender; 1259 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1260} 1261 1262-(void)moveParagraphBackward: (id)aSender 1263{ 1264 (void)aSender; 1265 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1266} 1267 1268-(void)moveToBeginningOfParagraphAndModifySelection: (id)aSender 1269{ 1270 (void)aSender; 1271 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1272} 1273 1274-(void)moveParagraphBackwardAndModifySelection: (id)aSender 1275{ 1276 (void)aSender; 1277 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1278} 1279 1280-(void)moveToEndOfDocument: (id)aSender 1281{ 1282 (void)aSender; 1283 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1284} 1285 1286-(void)scrollToEndOfDocument: (id)aSender 1287{ 1288 (void)aSender; 1289 // this is not exactly what we should do, but it makes "End" and "Shift-End" behave consistent 1290 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1291} 1292 1293-(void)moveToEndOfDocumentAndModifySelection: (id)aSender 1294{ 1295 (void)aSender; 1296 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1297} 1298 1299-(void)moveToBeginningOfDocument: (id)aSender 1300{ 1301 (void)aSender; 1302 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1303} 1304 1305-(void)scrollToBeginningOfDocument: (id)aSender 1306{ 1307 (void)aSender; 1308 // this is not exactly what we should do, but it makes "Home" and "Shift-Home" behave consistent 1309 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1310} 1311 1312-(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender 1313{ 1314 (void)aSender; 1315 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1316} 1317 1318-(void)moveUp: (id)aSender 1319{ 1320 (void)aSender; 1321 [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0]; 1322} 1323 1324-(void)moveDown: (id)aSender 1325{ 1326 (void)aSender; 1327 [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0]; 1328} 1329 1330-(void)insertNewline: (id)aSender 1331{ 1332 (void)aSender; 1333 // #i91267# make enter and shift-enter work by evaluating the modifiers 1334 [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags]; 1335} 1336 1337-(void)deleteBackward: (id)aSender 1338{ 1339 (void)aSender; 1340 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0]; 1341} 1342 1343-(void)deleteForward: (id)aSender 1344{ 1345 (void)aSender; 1346 [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0]; 1347} 1348 1349-(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender 1350{ 1351 (void)aSender; 1352 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0]; 1353} 1354 1355-(void)deleteWordBackward: (id)aSender 1356{ 1357 (void)aSender; 1358 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0 modifiers: 0]; 1359} 1360 1361-(void)deleteWordForward: (id)aSender 1362{ 1363 (void)aSender; 1364 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0 modifiers: 0]; 1365} 1366 1367-(void)deleteToBeginningOfLine: (id)aSender 1368{ 1369 (void)aSender; 1370 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1371} 1372 1373-(void)deleteToEndOfLine: (id)aSender 1374{ 1375 (void)aSender; 1376 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0 modifiers: 0]; 1377} 1378 1379-(void)deleteToBeginningOfParagraph: (id)aSender 1380{ 1381 (void)aSender; 1382 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1383} 1384 1385-(void)deleteToEndOfParagraph: (id)aSender 1386{ 1387 (void)aSender; 1388 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1389} 1390 1391-(void)insertLineBreak: (id)aSender 1392{ 1393 (void)aSender; 1394 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0 modifiers: 0]; 1395} 1396 1397-(void)insertParagraphSeparator: (id)aSender 1398{ 1399 (void)aSender; 1400 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0 modifiers: 0]; 1401} 1402 1403-(void)selectWord: (id)aSender 1404{ 1405 (void)aSender; 1406 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0 modifiers: 0]; 1407} 1408 1409-(void)selectLine: (id)aSender 1410{ 1411 (void)aSender; 1412 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0 modifiers: 0]; 1413} 1414 1415-(void)selectParagraph: (id)aSender 1416{ 1417 (void)aSender; 1418 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0 modifiers: 0]; 1419} 1420 1421-(void)selectAll: (id)aSender 1422{ 1423 (void)aSender; 1424 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0 modifiers: 0]; 1425} 1426 1427-(void)cancelOperation: (id)aSender 1428{ 1429 (void)aSender; 1430 [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0]; 1431} 1432 1433-(void)noop: (id)aSender 1434{ 1435 (void)aSender; 1436 if( ! mbKeyHandled ) 1437 { 1438 if( ! [self sendSingleCharacter:mpLastEvent] ) 1439 { 1440 /* prevent recursion */ 1441 if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] ) 1442 { 1443 id pLastSuperEvent = mpLastSuperEvent; 1444 mpLastSuperEvent = mpLastEvent; 1445 [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent]; 1446 mpLastSuperEvent = pLastSuperEvent; 1447 1448 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent ); 1449 if( it != GetSalData()->maKeyEventAnswer.end() ) 1450 it->second = true; 1451 } 1452 } 1453 } 1454} 1455 1456-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar 1457{ 1458 return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags]; 1459} 1460 1461-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod 1462{ 1463 return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] || 1464 [self sendSingleCharacter: mpLastEvent]; 1465} 1466 1467-(BOOL)sendKeyToFrameDirect: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod 1468{ 1469 YIELD_GUARD; 1470 1471 long nRet = 0; 1472 if( AquaSalFrame::isAlive( mpFrame ) ) 1473 { 1474 SalKeyEvent aEvent; 1475 aEvent.mnTime = mpFrame->mnLastEventTime; 1476 aEvent.mnCode = nKeyCode | ImplGetModifierMask( nMod ); 1477 aEvent.mnCharCode = aChar; 1478 aEvent.mnRepeat = FALSE; 1479 nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent ); 1480 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent ); 1481 if( it != GetSalData()->maKeyEventAnswer.end() ) 1482 it->second = nRet ? true : false; 1483 if( AquaSalFrame::isAlive( mpFrame ) ) 1484 mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent ); 1485 } 1486 return nRet ? YES : NO; 1487} 1488 1489 1490-(BOOL)sendSingleCharacter: (NSEvent *)pEvent 1491{ 1492 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 1493 1494 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 1495 { 1496 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 1497 sal_uInt16 nKeyCode = ImplMapCharCode( keyChar ); 1498 if( nKeyCode != 0 ) 1499 { 1500 // don't send unicodes in the private use area 1501 if( keyChar >= 0xf700 && keyChar < 0xf780 ) 1502 keyChar = 0; 1503 BOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags]; 1504 mbInKeyInput = false; 1505 1506 return bRet; 1507 } 1508 } 1509 return NO; 1510} 1511 1512 1513// NSTextInput protocol 1514- (NSArray *)validAttributesForMarkedText 1515{ 1516 return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil]; 1517} 1518 1519- (BOOL)hasMarkedText 1520{ 1521 BOOL bHasMarkedText; 1522 1523 bHasMarkedText = ( mMarkedRange.location != NSNotFound ) && 1524 ( mMarkedRange.length != 0 ); 1525 // hack to check keys like "Control-j" 1526 if( mbInKeyInput ) 1527 { 1528 mbNeedSpecialKeyHandle = true; 1529 } 1530 1531 // FIXME: 1532 // #i106901# 1533 // if we come here outside of mbInKeyInput, this is likely to be because 1534 // of the keyboard viewer. For unknown reasons having no marked range 1535 // in this case causes a crash. So we say we have a marked range anyway 1536 // This is a hack, since it is not understood what a) causes that crash 1537 // and b) why we should have a marked range at this point. 1538 if( ! mbInKeyInput ) 1539 bHasMarkedText = YES; 1540 1541 return bHasMarkedText; 1542} 1543 1544- (NSRange)markedRange 1545{ 1546 // FIXME: 1547 // #i106901# 1548 // if we come here outside of mbInKeyInput, this is likely to be because 1549 // of the keyboard viewer. For unknown reasons having no marked range 1550 // in this case causes a crash. So we say we have a marked range anyway 1551 // This is a hack, since it is not understood what a) causes that crash 1552 // and b) why we should have a marked range at this point. 1553 if( ! mbInKeyInput ) 1554 return NSMakeRange( 0, 0 ); 1555 1556 return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 ); 1557} 1558 1559- (NSRange)selectedRange 1560{ 1561 return mSelectedRange; 1562} 1563 1564- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange 1565{ 1566 if( ![aString isKindOfClass:[NSAttributedString class]] ) 1567 aString = [[[NSAttributedString alloc] initWithString:aString] autorelease]; 1568 NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange]; 1569 if( rangeToReplace.location == NSNotFound ) 1570 { 1571 mMarkedRange = NSMakeRange( selRange.location, [aString length] ); 1572 mSelectedRange = NSMakeRange( selRange.location, selRange.length ); 1573 } 1574 else 1575 { 1576 mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] ); 1577 mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length ); 1578 } 1579 1580 int len = [aString length]; 1581 SalExtTextInputEvent aInputEvent; 1582 aInputEvent.mnTime = mpFrame->mnLastEventTime; 1583 aInputEvent.mnDeltaStart = 0; 1584 aInputEvent.mbOnlyCursor = FALSE; 1585 if( len > 0 ) { 1586 NSString *pString = [aString string]; 1587 OUString aInsertString( GetOUString( pString ) ); 1588 std::vector<sal_uInt16> aInputFlags = std::vector<sal_uInt16>( std::max( 1, len ), 0 ); 1589 for ( int i = 0; i < len; i++ ) 1590 { 1591 unsigned int nUnderlineValue; 1592 NSRange effectiveRange; 1593 1594 effectiveRange = NSMakeRange(i, 1); 1595 nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue]; 1596 1597 switch (nUnderlineValue & 0xff) { 1598 case NSUnderlineStyleSingle: 1599 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE; 1600 break; 1601 case NSUnderlineStyleThick: 1602 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; 1603 break; 1604 case NSUnderlineStyleDouble: 1605 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE; 1606 break; 1607 default: 1608 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; 1609 break; 1610 } 1611 } 1612 1613 aInputEvent.maText = aInsertString; 1614 aInputEvent.mnCursorPos = selRange.location; 1615 aInputEvent.mpTextAttr = &aInputFlags[0]; 1616 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); 1617 } else { 1618 aInputEvent.maText = String(); 1619 aInputEvent.mnCursorPos = 0; 1620 aInputEvent.mnCursorFlags = 0; 1621 aInputEvent.mpTextAttr = 0; 1622 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); 1623 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1624 } 1625 mbKeyHandled= true; 1626} 1627 1628- (void)unmarkText 1629{ 1630 mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0); 1631} 1632 1633- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange 1634{ 1635 (void)theRange; 1636 // FIXME 1637 return nil; 1638} 1639 1640- (unsigned int)characterIndexForPoint:(NSPoint)thePoint 1641{ 1642 (void)thePoint; 1643 // FIXME 1644 return 0; 1645} 1646 1647#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 1648/* build target 10.5 or greater */ 1649- (NSInteger)conversationIdentifier 1650#else 1651/* build target 10.4 */ 1652- (long)conversationIdentifier 1653#endif 1654{ 1655 return (long)self; 1656} 1657 1658- (void)doCommandBySelector:(SEL)aSelector 1659{ 1660 if( AquaSalFrame::isAlive( mpFrame ) ) 1661 { 1662 #if OSL_DEBUG_LEVEL > 1 1663 // fprintf( stderr, "SalFrameView: doCommandBySelector %s\n", (char*)aSelector ); 1664 #endif 1665 if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 && 1666 aSelector != NULL && [self respondsToSelector: aSelector] ) 1667 { 1668 [self performSelector: aSelector]; 1669 } 1670 else 1671 { 1672 [self sendSingleCharacter:mpLastEvent]; 1673 } 1674 } 1675 1676 mbKeyHandled = true; 1677} 1678 1679-(void)clearLastEvent 1680{ 1681 mpLastEvent = nil; 1682} 1683 1684- (NSRect)firstRectForCharacterRange:(NSRange)theRange 1685{ 1686 (void)theRange; 1687 SalExtTextInputPosEvent aPosEvent; 1688 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent ); 1689 1690 NSRect rect; 1691 1692 rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX; 1693 rect.origin.y = aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines 1694 rect.size.width = aPosEvent.mnWidth; 1695 rect.size.height = aPosEvent.mnHeight; 1696 1697 mpFrame->VCLToCocoa( rect ); 1698 return rect; 1699} 1700 1701-(id)parentAttribute { 1702 return (NSView *) mpFrame -> mpWindow; 1703} 1704 1705-(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext 1706{ 1707 if ( mpReferenceWrapper == nil ) { 1708 // some frames never become visible .. 1709 Window *pWindow = mpFrame -> GetWindow(); 1710 if ( ! pWindow ) 1711 return nil; 1712 1713 mpReferenceWrapper = new ReferenceWrapper; 1714 mpReferenceWrapper -> rAccessibleContext = pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext(); 1715 [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ]; 1716 } 1717 return [ super accessibleContext ]; 1718} 1719 1720-(NSView *)viewElementForParent 1721{ 1722 return (NSView *) mpFrame -> mpWindow; 1723} 1724 1725-(void)registerMouseEventListener: (id)theListener 1726{ 1727 mpMouseEventListener = theListener; 1728} 1729 1730-(void)unregisterMouseEventListener: (id)theListener 1731{ 1732 (void)theListener; 1733 mpMouseEventListener = nil; 1734} 1735 1736-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 1737{ 1738 return [mDraggingDestinationHandler draggingEntered: sender]; 1739} 1740 1741-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 1742{ 1743 return [mDraggingDestinationHandler draggingUpdated: sender]; 1744} 1745 1746-(void)draggingExited:(id <NSDraggingInfo>)sender 1747{ 1748 [mDraggingDestinationHandler draggingExited: sender]; 1749} 1750 1751-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 1752{ 1753 return [mDraggingDestinationHandler prepareForDragOperation: sender]; 1754} 1755 1756-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender 1757{ 1758 return [mDraggingDestinationHandler performDragOperation: sender]; 1759} 1760 1761-(void)concludeDragOperation:(id <NSDraggingInfo>)sender 1762{ 1763 [mDraggingDestinationHandler concludeDragOperation: sender]; 1764} 1765 1766-(void)registerDraggingDestinationHandler:(id)theHandler 1767{ 1768 mDraggingDestinationHandler = theHandler; 1769} 1770 1771-(void)unregisterDraggingDestinationHandler:(id)theHandler 1772{ 1773 (void)theHandler; 1774 mDraggingDestinationHandler = nil; 1775} 1776 1777@end 1778 1779