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 return mpFrame ? (mpFrame->getClipPath() != 0 ? NO : YES) : YES; 482} 483 484// helper class similar to a vos::OGuard for the SalYieldMutex 485// the difference is that it only does tryToAcquire instead of aquire 486// so dreaded deadlocks like #i93512# are prevented 487class TryGuard 488{ 489public: 490 TryGuard() { mbGuarded = ImplSalYieldMutexTryToAcquire(); } 491 ~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); } 492 bool IsGuarded() { return mbGuarded; } 493private: 494 bool mbGuarded; 495}; 496 497-(void)drawRect: (NSRect)aRect 498{ 499 // HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex 500 TryGuard aTryGuard; 501 if( !aTryGuard.IsGuarded() ) 502 { 503 // NOTE: the mpFrame access below is not guarded yet! 504 // TODO: mpFrame et al need to be guarded by an independent mutex 505 AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL; 506 if( pGraphics ) 507 { 508 // we did not get the mutex so we cannot draw now => request to redraw later 509 // convert the NSRect to a CGRect for Refreshrect() 510 const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}}; 511 pGraphics->RefreshRect( aCGRect ); 512 } 513 return; 514 } 515 516 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) ) 517 { 518 if( mpFrame->mpGraphics ) 519 { 520 mpFrame->mpGraphics->UpdateWindow( aRect ); 521 if( mpFrame->getClipPath() ) 522 [mpFrame->getWindow() invalidateShadow]; 523 } 524 } 525} 526 527-(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(sal_uInt16)nButton eventtype:(sal_uInt16)nEvent 528{ 529 YIELD_GUARD; 530 531 AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame(); 532 bool bIsCaptured = false; 533 if( pDispatchFrame ) 534 { 535 bIsCaptured = true; 536 if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured 537 nEvent = SALEVENT_MOUSEMOVE; 538 } 539 else if( s_pMouseFrame ) 540 pDispatchFrame = s_pMouseFrame; 541 else 542 pDispatchFrame = mpFrame; 543 544 /* #i81645# Cocoa reports mouse events while a button is pressed 545 to the window in which it was first pressed. This is reasonable and fine and 546 gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer, 547 however vcl expects mouse events to occur in the window the mouse is over, unless the 548 mouse is explicitly captured. So we need to find the window the mouse is actually 549 over for conformance with other platforms. 550 */ 551 if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) ) 552 { 553 // is this event actually inside that NSWindow ? 554 NSPoint aPt = [NSEvent mouseLocation]; 555 NSRect aFrameRect = [pDispatchFrame->getWindow() frame]; 556 557 if ( ! NSPointInRect( aPt, aFrameRect ) ) 558 { 559 // no, it is not 560 // now we need to find the one it may be in 561 /* #i93756# we ant to get enumerate the application windows in z-order 562 to check if any contains the mouse. This could be elegantly done with this 563 code: 564 565 // use NSApp to check windows in ZOrder whether they contain the mouse pointer 566 NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES]; 567 if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] ) 568 pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame]; 569 570 However if a non SalFrameWindow is on screen (like e.g. the file dialog) 571 it can be hit with the containsMouse selector, which it doesn't support. 572 Sadly NSApplication:makeWindowsPerform does not check (for performance reasons 573 I assume) whether a window supports a selector before sending it. 574 */ 575 AquaSalFrame* pMouseFrame = getMouseContainerFrame(); 576 if( pMouseFrame ) 577 pDispatchFrame = pMouseFrame; 578 } 579 } 580 581 if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) ) 582 { 583 pDispatchFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 584 pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags]; 585 586 NSPoint aPt = [NSEvent mouseLocation]; 587 pDispatchFrame->CocoaToVCL( aPt ); 588 589 sal_uInt16 nModMask = ImplGetModifierMask( [pEvent modifierFlags] ); 590 // #i82284# emulate ctrl left 591 if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT ) 592 { 593 nModMask = 0; 594 nButton = MOUSE_RIGHT; 595 } 596 597 SalMouseEvent aEvent; 598 aEvent.mnTime = pDispatchFrame->mnLastEventTime; 599 aEvent.mnX = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX; 600 aEvent.mnY = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY; 601 aEvent.mnButton = nButton; 602 aEvent.mnCode = aEvent.mnButton | nModMask; 603 604 // --- RTL --- (mirror mouse pos) 605 if( Application::GetSettings().GetLayoutRTL() ) 606 aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX; 607 608 pDispatchFrame->CallCallback( nEvent, &aEvent ); 609 } 610} 611 612-(void)mouseDown: (NSEvent*)pEvent 613{ 614 if ( mpMouseEventListener != nil && 615 [mpMouseEventListener respondsToSelector: @selector(mouseDown:)]) 616 { 617 [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]]; 618 } 619 620 s_nLastButton = MOUSE_LEFT; 621 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN]; 622} 623 624-(void)mouseDragged: (NSEvent*)pEvent 625{ 626 if ( mpMouseEventListener != nil && 627 [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)]) 628 { 629 [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]]; 630 } 631 s_nLastButton = MOUSE_LEFT; 632 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE]; 633} 634 635-(void)mouseUp: (NSEvent*)pEvent 636{ 637 s_nLastButton = 0; 638 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP]; 639} 640 641-(void)mouseMoved: (NSEvent*)pEvent 642{ 643 s_nLastButton = 0; 644 [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE]; 645} 646 647-(void)mouseEntered: (NSEvent*)pEvent 648{ 649 s_pMouseFrame = mpFrame; 650 651 // #i107215# the only mouse events we get when inactive are enter/exit 652 // actually we would like to have all of them, but better none than some 653 if( [NSApp isActive] ) 654 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE]; 655} 656 657-(void)mouseExited: (NSEvent*)pEvent 658{ 659 if( s_pMouseFrame == mpFrame ) 660 s_pMouseFrame = NULL; 661 662 // #i107215# the only mouse events we get when inactive are enter/exit 663 // actually we would like to have all of them, but better none than some 664 if( [NSApp isActive] ) 665 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE]; 666} 667 668-(void)rightMouseDown: (NSEvent*)pEvent 669{ 670 s_nLastButton = MOUSE_RIGHT; 671 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN]; 672} 673 674-(void)rightMouseDragged: (NSEvent*)pEvent 675{ 676 s_nLastButton = MOUSE_RIGHT; 677 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE]; 678} 679 680-(void)rightMouseUp: (NSEvent*)pEvent 681{ 682 s_nLastButton = 0; 683 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP]; 684} 685 686-(void)otherMouseDown: (NSEvent*)pEvent 687{ 688 if( [pEvent buttonNumber] == 2 ) 689 { 690 s_nLastButton = MOUSE_MIDDLE; 691 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN]; 692 } 693 else 694 s_nLastButton = 0; 695} 696 697-(void)otherMouseDragged: (NSEvent*)pEvent 698{ 699 if( [pEvent buttonNumber] == 2 ) 700 { 701 s_nLastButton = MOUSE_MIDDLE; 702 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE]; 703 } 704 else 705 s_nLastButton = 0; 706} 707 708-(void)otherMouseUp: (NSEvent*)pEvent 709{ 710 s_nLastButton = 0; 711 if( [pEvent buttonNumber] == 2 ) 712 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP]; 713} 714 715- (void)magnifyWithEvent: (NSEvent*)pEvent 716{ 717 YIELD_GUARD; 718 719 // TODO: ?? -(float)magnification; 720 if( AquaSalFrame::isAlive( mpFrame ) ) 721 { 722 const NSTimeInterval fMagnifyTime = [pEvent timestamp]; 723 mpFrame->mnLastEventTime = static_cast<sal_uLong>( fMagnifyTime * 1000.0 ); 724 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 725 726 // check if this is a new series of magnify events 727 static const NSTimeInterval fMaxDiffTime = 0.3; 728 const bool bNewSeries = (fMagnifyTime - mfLastMagnifyTime > fMaxDiffTime); 729 730 if( bNewSeries ) 731 mfMagnifyDeltaSum = 0.0; 732 mfMagnifyDeltaSum += [pEvent deltaZ]; 733 734 mfLastMagnifyTime = [pEvent timestamp]; 735 // TODO: change to 0.1 when COMMAND_WHEEL_ZOOM handlers allow finer zooming control 736 static const float fMagnifyFactor = 0.25; 737 static const float fMinMagnifyStep = 15.0 / fMagnifyFactor; 738 if( fabs(mfMagnifyDeltaSum) <= fMinMagnifyStep ) 739 return; 740 741 // adapt NSEvent-sensitivity to application expectations 742 // TODO: rather make COMMAND_WHEEL_ZOOM handlers smarter 743 const float fDeltaZ = mfMagnifyDeltaSum * fMagnifyFactor; 744 int nDeltaZ = FRound( fDeltaZ ); 745 if( !nDeltaZ ) 746 { 747 // handle new series immediately 748 if( !bNewSeries ) 749 return; 750 nDeltaZ = (fDeltaZ >= 0.0) ? +1 : -1; 751 } 752 // eventually give credit for delta sum 753 mfMagnifyDeltaSum -= nDeltaZ / fMagnifyFactor; 754 755 NSPoint aPt = [NSEvent mouseLocation]; 756 mpFrame->CocoaToVCL( aPt ); 757 758 SalWheelMouseEvent aEvent; 759 aEvent.mnTime = mpFrame->mnLastEventTime; 760 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 761 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 762 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 763 aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling 764 aEvent.mbDeltaIsPixel = TRUE; 765 766 // --- RTL --- (mirror mouse pos) 767 if( Application::GetSettings().GetLayoutRTL() ) 768 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 769 770 aEvent.mnDelta = nDeltaZ; 771 aEvent.mnNotchDelta = (nDeltaZ >= 0) ? +1 : -1; 772 if( aEvent.mnDelta == 0 ) 773 aEvent.mnDelta = aEvent.mnNotchDelta; 774 aEvent.mbHorz = FALSE; 775 aEvent.mnScrollLines = nDeltaZ; 776 if( aEvent.mnScrollLines == 0 ) 777 aEvent.mnScrollLines = 1; 778 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 779 } 780} 781 782- (void)rotateWithEvent: (NSEvent*)pEvent 783{ 784 //Rotation : -(float)rotation; 785 // TODO: create new CommandType so rotation is available to the applications 786 (void)pEvent; 787} 788 789- (void)swipeWithEvent: (NSEvent*)pEvent 790{ 791 YIELD_GUARD; 792 793 if( AquaSalFrame::isAlive( mpFrame ) ) 794 { 795 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 796 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 797 798 // merge pending scroll wheel events 799 float dX = 0.0; 800 float dY = 0.0; 801 for(;;) 802 { 803 dX += [pEvent deltaX]; 804 dY += [pEvent deltaY]; 805 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask 806 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; 807 if( !pNextEvent ) 808 break; 809 pEvent = pNextEvent; 810 } 811 812 NSPoint aPt = [NSEvent mouseLocation]; 813 mpFrame->CocoaToVCL( aPt ); 814 815 SalWheelMouseEvent aEvent; 816 aEvent.mnTime = mpFrame->mnLastEventTime; 817 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 818 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 819 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 820 aEvent.mbDeltaIsPixel = TRUE; 821 822 // --- RTL --- (mirror mouse pos) 823 if( Application::GetSettings().GetLayoutRTL() ) 824 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 825 826 if( dX != 0.0 ) 827 { 828 aEvent.mnDelta = static_cast<long>(floor(dX)); 829 aEvent.mnNotchDelta = dX < 0 ? -1 : 1; 830 if( aEvent.mnDelta == 0 ) 831 aEvent.mnDelta = aEvent.mnNotchDelta; 832 aEvent.mbHorz = TRUE; 833 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 834 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 835 } 836 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame )) 837 { 838 aEvent.mnDelta = static_cast<long>(floor(dY)); 839 aEvent.mnNotchDelta = dY < 0 ? -1 : 1; 840 if( aEvent.mnDelta == 0 ) 841 aEvent.mnDelta = aEvent.mnNotchDelta; 842 aEvent.mbHorz = FALSE; 843 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; 844 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 845 } 846 } 847} 848 849-(void)scrollWheel: (NSEvent*)pEvent 850{ 851 YIELD_GUARD; 852 853 if( AquaSalFrame::isAlive( mpFrame ) ) 854 { 855 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 856 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 857 858 // merge pending scroll wheel events 859 float dX = 0.0; 860 float dY = 0.0; 861 for(;;) 862 { 863 dX += [pEvent deltaX]; 864 dY += [pEvent deltaY]; 865 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask 866 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ]; 867 if( !pNextEvent ) 868 break; 869 pEvent = pNextEvent; 870 } 871 872 NSPoint aPt = [NSEvent mouseLocation]; 873 mpFrame->CocoaToVCL( aPt ); 874 875 SalWheelMouseEvent aEvent; 876 aEvent.mnTime = mpFrame->mnLastEventTime; 877 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX; 878 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY; 879 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags ); 880 aEvent.mbDeltaIsPixel = TRUE; 881 882 // --- RTL --- (mirror mouse pos) 883 if( Application::GetSettings().GetLayoutRTL() ) 884 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX; 885 886 if( dX != 0.0 ) 887 { 888 aEvent.mnDelta = static_cast<long>(floor(dX)); 889 aEvent.mnNotchDelta = dX < 0 ? -1 : 1; 890 if( aEvent.mnDelta == 0 ) 891 aEvent.mnDelta = aEvent.mnNotchDelta; 892 aEvent.mbHorz = TRUE; 893 aEvent.mnScrollLines = dY > 0 ? dX/WHEEL_EVENT_FACTOR : -dX/WHEEL_EVENT_FACTOR; 894 if( aEvent.mnScrollLines == 0 ) 895 aEvent.mnScrollLines = 1; 896 897 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 898 } 899 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) ) 900 { 901 aEvent.mnDelta = static_cast<long>(floor(dY)); 902 aEvent.mnNotchDelta = dY < 0 ? -1 : 1; 903 if( aEvent.mnDelta == 0 ) 904 aEvent.mnDelta = aEvent.mnNotchDelta; 905 aEvent.mbHorz = FALSE; 906 aEvent.mnScrollLines = dY > 0 ? dY/WHEEL_EVENT_FACTOR : -dY/WHEEL_EVENT_FACTOR; 907 if( aEvent.mnScrollLines < 1 ) 908 aEvent.mnScrollLines = 1; 909 910 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); 911 } 912 } 913} 914 915 916-(void)keyDown: (NSEvent*)pEvent 917{ 918 YIELD_GUARD; 919 920 if( AquaSalFrame::isAlive( mpFrame ) ) 921 { 922 mpLastEvent = pEvent; 923 mbInKeyInput = true; 924 mbNeedSpecialKeyHandle = false; 925 mbKeyHandled = false; 926 927 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 928 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 929 930 if( ! [self handleKeyDownException: pEvent] ) 931 { 932 NSArray* pArray = [NSArray arrayWithObject: pEvent]; 933 [self interpretKeyEvents: pArray]; 934 } 935 936 mbInKeyInput = false; 937 } 938} 939 940-(BOOL)handleKeyDownException:(NSEvent*)pEvent 941{ 942 // check for a very special set of modified characters 943 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 944 945 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 946 { 947 /* #i103102# key events with command and alternate don't make it through 948 interpretKeyEvents (why ?). Try to dispatch them here first, 949 if not successful continue normally 950 */ 951 if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask)) 952 == (NSAlternateKeyMask | NSCommandKeyMask) ) 953 { 954 if( [self sendSingleCharacter: mpLastEvent] ) 955 return YES; 956 } 957 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 958 sal_uInt16 nKeyCode = ImplMapCharCode( keyChar ); 959 960 // Caution: should the table grow to more than 5 or 6 entries, 961 // we must consider moving it to a kind of hash map 962 const unsigned int nExceptions = sizeof( aExceptionalKeys ) / sizeof( aExceptionalKeys[0] ); 963 for( unsigned int i = 0; i < nExceptions; i++ ) 964 { 965 if( nKeyCode == aExceptionalKeys[i].nKeyCode && 966 (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask) 967 == aExceptionalKeys[i].nModifierMask ) 968 { 969 [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0]; 970 971 return YES; 972 } 973 } 974 } 975 return NO; 976} 977 978-(void)flagsChanged: (NSEvent*)pEvent 979{ 980 YIELD_GUARD; 981 982 if( AquaSalFrame::isAlive( mpFrame ) ) 983 { 984 mpFrame->mnLastEventTime = static_cast<sal_uLong>( [pEvent timestamp] * 1000.0 ); 985 mpFrame->mnLastModifierFlags = [pEvent modifierFlags]; 986 } 987} 988 989-(void)insertText:(id)aString 990{ 991 YIELD_GUARD; 992 993 if( AquaSalFrame::isAlive( mpFrame ) ) 994 { 995 NSString* pInsert = nil; 996 if( [aString isMemberOfClass: [NSAttributedString class]] ) 997 pInsert = [aString string]; 998 else 999 pInsert = aString; 1000 1001 int nLen = 0; 1002 if( pInsert && ( nLen = [pInsert length] ) > 0 ) 1003 { 1004 OUString aInsertString( GetOUString( pInsert ) ); 1005 // aCharCode initializer is safe since aInsertString will at least contain '\0' 1006 sal_Unicode aCharCode = *aInsertString.getStr(); 1007 1008 if( nLen == 1 && 1009 aCharCode < 0x80 && 1010 aCharCode > 0x1f && 1011 ! [self hasMarkedText ] 1012 ) 1013 { 1014 sal_uInt16 nKeyCode = ImplMapCharCode( aCharCode ); 1015 unsigned int nLastModifiers = mpFrame->mnLastModifierFlags; 1016 1017 // #i99567# 1018 // find out the unmodified key code 1019 1020 // sanity check 1021 if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) ) 1022 { 1023 // get unmodified string 1024 NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers]; 1025 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 1026 { 1027 // map the unmodified key code 1028 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 1029 nKeyCode = ImplMapCharCode( keyChar ); 1030 } 1031 nLastModifiers = [mpLastEvent modifierFlags]; 1032 1033 } 1034 // #i99567# 1035 // applications and vcl's edit fields ignore key events with ALT 1036 // however we're at a place where we know text should be inserted 1037 // so it seems we need to strip the Alt modifier here 1038 if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask)) 1039 == NSAlternateKeyMask ) 1040 { 1041 nLastModifiers = 0; 1042 } 1043 [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers]; 1044 } 1045 else 1046 { 1047 SalExtTextInputEvent aEvent; 1048 aEvent.mnTime = mpFrame->mnLastEventTime; 1049 aEvent.maText = aInsertString; 1050 aEvent.mpTextAttr = NULL; 1051 aEvent.mnCursorPos = aInsertString.getLength(); 1052 aEvent.mnDeltaStart = 0; 1053 aEvent.mnCursorFlags = 0; 1054 aEvent.mbOnlyCursor = FALSE; 1055 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); 1056 if( AquaSalFrame::isAlive( mpFrame ) ) 1057 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1058 } 1059 } 1060 else 1061 { 1062 SalExtTextInputEvent aEvent; 1063 aEvent.mnTime = mpFrame->mnLastEventTime; 1064 aEvent.maText = String(); 1065 aEvent.mpTextAttr = NULL; 1066 aEvent.mnCursorPos = 0; 1067 aEvent.mnDeltaStart = 0; 1068 aEvent.mnCursorFlags = 0; 1069 aEvent.mbOnlyCursor = FALSE; 1070 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent ); 1071 if( AquaSalFrame::isAlive( mpFrame ) ) 1072 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1073 1074 } 1075 mbKeyHandled = true; 1076 [self unmarkText]; 1077 } 1078} 1079 1080-(void)insertTab: (id)aSender 1081{ 1082 (void)aSender; 1083 [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0]; 1084} 1085 1086-(void)insertBacktab: (id)aSender 1087{ 1088 (void)aSender; 1089 [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0]; 1090} 1091 1092-(void)moveLeft: (id)aSender 1093{ 1094 (void)aSender; 1095 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0]; 1096} 1097 1098-(void)moveLeftAndModifySelection: (id)aSender 1099{ 1100 (void)aSender; 1101 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask]; 1102} 1103 1104-(void)moveBackwardAndModifySelection: (id)aSender 1105{ 1106 (void)aSender; 1107 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0 modifiers: 0]; 1108} 1109 1110-(void)moveRight: (id)aSender 1111{ 1112 (void)aSender; 1113 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0]; 1114} 1115 1116-(void)moveRightAndModifySelection: (id)aSender 1117{ 1118 (void)aSender; 1119 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask]; 1120} 1121 1122-(void)moveForwardAndModifySelection: (id)aSender 1123{ 1124 (void)aSender; 1125 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0 modifiers: 0]; 1126} 1127 1128-(void)moveWordLeft: (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)moveWordBackward: (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)moveWordBackwardAndModifySelection: (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)moveWordLeftAndModifySelection: (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)moveWordRight: (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)moveWordForward: (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)moveWordForwardAndModifySelection: (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)moveWordRightAndModifySelection: (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)moveToEndOfLine: (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)moveToRightEndOfLine: (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)moveToEndOfLineAndModifySelection: (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)moveToRightEndOfLineAndModifySelection: (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)moveToBeginningOfLine: (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)moveToLeftEndOfLine: (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)moveToBeginningOfLineAndModifySelection: (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)moveToLeftEndOfLineAndModifySelection: (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)moveToEndOfParagraph: (id)aSender 1225{ 1226 (void)aSender; 1227 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1228} 1229 1230-(void)moveToEndOfParagraphAndModifySelection: (id)aSender 1231{ 1232 (void)aSender; 1233 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1234} 1235 1236-(void)moveParagraphForward: (id)aSender 1237{ 1238 (void)aSender; 1239 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1240} 1241 1242-(void)moveParagraphForwardAndModifySelection: (id)aSender 1243{ 1244 (void)aSender; 1245 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1246} 1247 1248-(void)moveToBeginningOfParagraph: (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)moveParagraphBackward: (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)moveToBeginningOfParagraphAndModifySelection: (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)moveParagraphBackwardAndModifySelection: (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)moveToEndOfDocument: (id)aSender 1273{ 1274 (void)aSender; 1275 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1276} 1277 1278-(void)scrollToEndOfDocument: (id)aSender 1279{ 1280 (void)aSender; 1281 // this is not exactly what we should do, but it makes "End" and "Shift-End" behave consistent 1282 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1283} 1284 1285-(void)moveToEndOfDocumentAndModifySelection: (id)aSender 1286{ 1287 (void)aSender; 1288 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0 modifiers: 0]; 1289} 1290 1291-(void)moveToBeginningOfDocument: (id)aSender 1292{ 1293 (void)aSender; 1294 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1295} 1296 1297-(void)scrollToBeginningOfDocument: (id)aSender 1298{ 1299 (void)aSender; 1300 // this is not exactly what we should do, but it makes "Home" and "Shift-Home" behave consistent 1301 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1302} 1303 1304-(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender 1305{ 1306 (void)aSender; 1307 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0]; 1308} 1309 1310-(void)moveUp: (id)aSender 1311{ 1312 (void)aSender; 1313 [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0]; 1314} 1315 1316-(void)moveDown: (id)aSender 1317{ 1318 (void)aSender; 1319 [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0]; 1320} 1321 1322-(void)insertNewline: (id)aSender 1323{ 1324 (void)aSender; 1325 // #i91267# make enter and shift-enter work by evaluating the modifiers 1326 [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags]; 1327} 1328 1329-(void)deleteBackward: (id)aSender 1330{ 1331 (void)aSender; 1332 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0]; 1333} 1334 1335-(void)deleteForward: (id)aSender 1336{ 1337 (void)aSender; 1338 [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0]; 1339} 1340 1341-(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender 1342{ 1343 (void)aSender; 1344 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0]; 1345} 1346 1347-(void)deleteWordBackward: (id)aSender 1348{ 1349 (void)aSender; 1350 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0 modifiers: 0]; 1351} 1352 1353-(void)deleteWordForward: (id)aSender 1354{ 1355 (void)aSender; 1356 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0 modifiers: 0]; 1357} 1358 1359-(void)deleteToBeginningOfLine: (id)aSender 1360{ 1361 (void)aSender; 1362 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0 modifiers: 0]; 1363} 1364 1365-(void)deleteToEndOfLine: (id)aSender 1366{ 1367 (void)aSender; 1368 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0 modifiers: 0]; 1369} 1370 1371-(void)deleteToBeginningOfParagraph: (id)aSender 1372{ 1373 (void)aSender; 1374 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0]; 1375} 1376 1377-(void)deleteToEndOfParagraph: (id)aSender 1378{ 1379 (void)aSender; 1380 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0]; 1381} 1382 1383-(void)insertLineBreak: (id)aSender 1384{ 1385 (void)aSender; 1386 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0 modifiers: 0]; 1387} 1388 1389-(void)insertParagraphSeparator: (id)aSender 1390{ 1391 (void)aSender; 1392 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0 modifiers: 0]; 1393} 1394 1395-(void)selectWord: (id)aSender 1396{ 1397 (void)aSender; 1398 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0 modifiers: 0]; 1399} 1400 1401-(void)selectLine: (id)aSender 1402{ 1403 (void)aSender; 1404 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0 modifiers: 0]; 1405} 1406 1407-(void)selectParagraph: (id)aSender 1408{ 1409 (void)aSender; 1410 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0 modifiers: 0]; 1411} 1412 1413-(void)selectAll: (id)aSender 1414{ 1415 (void)aSender; 1416 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0 modifiers: 0]; 1417} 1418 1419-(void)cancelOperation: (id)aSender 1420{ 1421 (void)aSender; 1422 [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0]; 1423} 1424 1425-(void)noop: (id)aSender 1426{ 1427 (void)aSender; 1428 if( ! mbKeyHandled ) 1429 { 1430 if( ! [self sendSingleCharacter:mpLastEvent] ) 1431 { 1432 /* prevent recursion */ 1433 if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] ) 1434 { 1435 id pLastSuperEvent = mpLastSuperEvent; 1436 mpLastSuperEvent = mpLastEvent; 1437 [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent]; 1438 mpLastSuperEvent = pLastSuperEvent; 1439 1440 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent ); 1441 if( it != GetSalData()->maKeyEventAnswer.end() ) 1442 it->second = true; 1443 } 1444 } 1445 } 1446} 1447 1448-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar 1449{ 1450 return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags]; 1451} 1452 1453-(BOOL)sendKeyInputAndReleaseToFrame: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod 1454{ 1455 return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] || 1456 [self sendSingleCharacter: mpLastEvent]; 1457} 1458 1459-(BOOL)sendKeyToFrameDirect: (sal_uInt16)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod 1460{ 1461 YIELD_GUARD; 1462 1463 long nRet = 0; 1464 if( AquaSalFrame::isAlive( mpFrame ) ) 1465 { 1466 SalKeyEvent aEvent; 1467 aEvent.mnTime = mpFrame->mnLastEventTime; 1468 aEvent.mnCode = nKeyCode | ImplGetModifierMask( nMod ); 1469 aEvent.mnCharCode = aChar; 1470 aEvent.mnRepeat = FALSE; 1471 nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent ); 1472 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent ); 1473 if( it != GetSalData()->maKeyEventAnswer.end() ) 1474 it->second = nRet ? true : false; 1475 if( AquaSalFrame::isAlive( mpFrame ) ) 1476 mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent ); 1477 } 1478 return nRet ? YES : NO; 1479} 1480 1481 1482-(BOOL)sendSingleCharacter: (NSEvent *)pEvent 1483{ 1484 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers]; 1485 1486 if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) 1487 { 1488 unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; 1489 sal_uInt16 nKeyCode = ImplMapCharCode( keyChar ); 1490 if( nKeyCode != 0 ) 1491 { 1492 // don't send unicodes in the private use area 1493 if( keyChar >= 0xf700 && keyChar < 0xf780 ) 1494 keyChar = 0; 1495 BOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags]; 1496 mbInKeyInput = false; 1497 1498 return bRet; 1499 } 1500 } 1501 return NO; 1502} 1503 1504 1505// NSTextInput protocol 1506- (NSArray *)validAttributesForMarkedText 1507{ 1508 return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil]; 1509} 1510 1511- (BOOL)hasMarkedText 1512{ 1513 BOOL bHasMarkedText; 1514 1515 bHasMarkedText = ( mMarkedRange.location != NSNotFound ) && 1516 ( mMarkedRange.length != 0 ); 1517 // hack to check keys like "Control-j" 1518 if( mbInKeyInput ) 1519 { 1520 mbNeedSpecialKeyHandle = true; 1521 } 1522 1523 // FIXME: 1524 // #i106901# 1525 // if we come here outside of mbInKeyInput, this is likely to be because 1526 // of the keyboard viewer. For unknown reasons having no marked range 1527 // in this case causes a crash. So we say we have a marked range anyway 1528 // This is a hack, since it is not understood what a) causes that crash 1529 // and b) why we should have a marked range at this point. 1530 if( ! mbInKeyInput ) 1531 bHasMarkedText = YES; 1532 1533 return bHasMarkedText; 1534} 1535 1536- (NSRange)markedRange 1537{ 1538 // FIXME: 1539 // #i106901# 1540 // if we come here outside of mbInKeyInput, this is likely to be because 1541 // of the keyboard viewer. For unknown reasons having no marked range 1542 // in this case causes a crash. So we say we have a marked range anyway 1543 // This is a hack, since it is not understood what a) causes that crash 1544 // and b) why we should have a marked range at this point. 1545 if( ! mbInKeyInput ) 1546 return NSMakeRange( 0, 0 ); 1547 1548 return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 ); 1549} 1550 1551- (NSRange)selectedRange 1552{ 1553 return mSelectedRange; 1554} 1555 1556- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange 1557{ 1558 if( ![aString isKindOfClass:[NSAttributedString class]] ) 1559 aString = [[[NSAttributedString alloc] initWithString:aString] autorelease]; 1560 NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange]; 1561 if( rangeToReplace.location == NSNotFound ) 1562 { 1563 mMarkedRange = NSMakeRange( selRange.location, [aString length] ); 1564 mSelectedRange = NSMakeRange( selRange.location, selRange.length ); 1565 } 1566 else 1567 { 1568 mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] ); 1569 mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length ); 1570 } 1571 1572 int len = [aString length]; 1573 SalExtTextInputEvent aInputEvent; 1574 aInputEvent.mnTime = mpFrame->mnLastEventTime; 1575 aInputEvent.mnDeltaStart = 0; 1576 aInputEvent.mbOnlyCursor = FALSE; 1577 if( len > 0 ) { 1578 NSString *pString = [aString string]; 1579 OUString aInsertString( GetOUString( pString ) ); 1580 std::vector<sal_uInt16> aInputFlags = std::vector<sal_uInt16>( std::max( 1, len ), 0 ); 1581 for ( int i = 0; i < len; i++ ) 1582 { 1583 unsigned int nUnderlineValue; 1584 NSRange effectiveRange; 1585 1586 effectiveRange = NSMakeRange(i, 1); 1587 nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue]; 1588 1589 switch (nUnderlineValue & 0xff) { 1590 case NSUnderlineStyleSingle: 1591 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE; 1592 break; 1593 case NSUnderlineStyleThick: 1594 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; 1595 break; 1596 case NSUnderlineStyleDouble: 1597 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE; 1598 break; 1599 default: 1600 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT; 1601 break; 1602 } 1603 } 1604 1605 aInputEvent.maText = aInsertString; 1606 aInputEvent.mnCursorPos = selRange.location; 1607 aInputEvent.mpTextAttr = &aInputFlags[0]; 1608 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); 1609 } else { 1610 aInputEvent.maText = String(); 1611 aInputEvent.mnCursorPos = 0; 1612 aInputEvent.mnCursorFlags = 0; 1613 aInputEvent.mpTextAttr = 0; 1614 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent ); 1615 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 ); 1616 } 1617 mbKeyHandled= true; 1618} 1619 1620- (void)unmarkText 1621{ 1622 mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0); 1623} 1624 1625- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange 1626{ 1627 (void)theRange; 1628 // FIXME 1629 return nil; 1630} 1631 1632- (unsigned int)characterIndexForPoint:(NSPoint)thePoint 1633{ 1634 (void)thePoint; 1635 // FIXME 1636 return 0; 1637} 1638 1639#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 1640/* build target 10.5 or greater */ 1641- (NSInteger)conversationIdentifier 1642#else 1643/* build target 10.4 */ 1644- (long)conversationIdentifier 1645#endif 1646{ 1647 return (long)self; 1648} 1649 1650- (void)doCommandBySelector:(SEL)aSelector 1651{ 1652 if( AquaSalFrame::isAlive( mpFrame ) ) 1653 { 1654 #if OSL_DEBUG_LEVEL > 1 1655 // fprintf( stderr, "SalFrameView: doCommandBySelector %s\n", (char*)aSelector ); 1656 #endif 1657 if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 && 1658 aSelector != NULL && [self respondsToSelector: aSelector] ) 1659 { 1660 [self performSelector: aSelector]; 1661 } 1662 else 1663 { 1664 [self sendSingleCharacter:mpLastEvent]; 1665 } 1666 } 1667 1668 mbKeyHandled = true; 1669} 1670 1671-(void)clearLastEvent 1672{ 1673 mpLastEvent = nil; 1674} 1675 1676- (NSRect)firstRectForCharacterRange:(NSRange)theRange 1677{ 1678 (void)theRange; 1679 SalExtTextInputPosEvent aPosEvent; 1680 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent ); 1681 1682 NSRect rect; 1683 1684 rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX; 1685 rect.origin.y = aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines 1686 rect.size.width = aPosEvent.mnWidth; 1687 rect.size.height = aPosEvent.mnHeight; 1688 1689 mpFrame->VCLToCocoa( rect ); 1690 return rect; 1691} 1692 1693-(id)parentAttribute { 1694 return (NSView *) mpFrame -> mpWindow; 1695} 1696 1697-(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext 1698{ 1699 if ( mpReferenceWrapper == nil ) { 1700 // some frames never become visible .. 1701 Window *pWindow = mpFrame -> GetWindow(); 1702 if ( ! pWindow ) 1703 return nil; 1704 1705 mpReferenceWrapper = new ReferenceWrapper; 1706 mpReferenceWrapper -> rAccessibleContext = pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext(); 1707 [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ]; 1708 } 1709 return [ super accessibleContext ]; 1710} 1711 1712-(NSView *)viewElementForParent 1713{ 1714 return (NSView *) mpFrame -> mpWindow; 1715} 1716 1717-(void)registerMouseEventListener: (id)theListener 1718{ 1719 mpMouseEventListener = theListener; 1720} 1721 1722-(void)unregisterMouseEventListener: (id)theListener 1723{ 1724 (void)theListener; 1725 mpMouseEventListener = nil; 1726} 1727 1728-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 1729{ 1730 return [mDraggingDestinationHandler draggingEntered: sender]; 1731} 1732 1733-(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender 1734{ 1735 return [mDraggingDestinationHandler draggingUpdated: sender]; 1736} 1737 1738-(void)draggingExited:(id <NSDraggingInfo>)sender 1739{ 1740 [mDraggingDestinationHandler draggingExited: sender]; 1741} 1742 1743-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender 1744{ 1745 return [mDraggingDestinationHandler prepareForDragOperation: sender]; 1746} 1747 1748-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender 1749{ 1750 return [mDraggingDestinationHandler performDragOperation: sender]; 1751} 1752 1753-(void)concludeDragOperation:(id <NSDraggingInfo>)sender 1754{ 1755 [mDraggingDestinationHandler concludeDragOperation: sender]; 1756} 1757 1758-(void)registerDraggingDestinationHandler:(id)theHandler 1759{ 1760 mDraggingDestinationHandler = theHandler; 1761} 1762 1763-(void)unregisterDraggingDestinationHandler:(id)theHandler 1764{ 1765 (void)theHandler; 1766 mDraggingDestinationHandler = nil; 1767} 1768 1769@end 1770 1771