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