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