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