1 /*n***********************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salframeview.mm,v $
10 * $Revision: 1.12.22.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include "salframeview.h"
38 #include "aqua11yfactory.h"
39 #include <sal/alloca.h>
40 #include "vcl/window.hxx"
42 #include "vcl/svapp.hxx"
44 static USHORT ImplGetModifierMask( unsigned int nMask )
47 if( (nMask & NSShiftKeyMask) != 0 )
49 if( (nMask & NSControlKeyMask) != 0 )
51 if( (nMask & NSAlternateKeyMask) != 0 )
53 if( (nMask & NSCommandKeyMask) != 0 )
58 static USHORT ImplMapCharCode( sal_Unicode aCode )
60 static USHORT aKeyCodeMap[ 128 ] =
62 0, 0, 0, 0, 0, 0, 0, 0,
63 KEY_BACKSPACE, KEY_TAB, KEY_RETURN, 0, 0, KEY_RETURN, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0,
65 0, KEY_TAB, 0, KEY_ESCAPE, 0, 0, 0, 0,
66 KEY_SPACE, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, KEY_MULTIPLY, KEY_ADD, KEY_COMMA, KEY_SUBTRACT, KEY_POINT, KEY_DIVIDE,
68 KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
69 KEY_8, KEY_9, 0, 0, KEY_LESS, KEY_EQUAL, KEY_GREATER, 0,
70 0, 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, 0, 0,
74 KEY_QUOTELEFT, 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, KEY_TILDE, KEY_BACKSPACE
80 // Note: the mapping 0x7f should by rights be KEY_DELETE
81 // however if you press "backspace" 0x7f is reported
82 // whereas for "delete" 0xf728 gets reported
84 // Note: the mapping of 0x19 to KEY_TAB is because for unknown reasons
85 // tab alone is reported as 0x09 (as expected) but shift-tab is
86 // reported as 0x19 (end of medium)
88 static USHORT aFunctionKeyCodeMap[ 128 ] =
90 KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_F1, KEY_F2, KEY_F3, KEY_F4,
91 KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12,
92 KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17, KEY_F18, KEY_F19, KEY_F20,
93 KEY_F21, KEY_F22, KEY_F23, KEY_F24, KEY_F25, KEY_F26, 0, 0,
94 0, 0, 0, 0, 0, 0, 0, KEY_INSERT,
95 KEY_DELETE, KEY_HOME, 0, KEY_END, KEY_PAGEUP, KEY_PAGEDOWN, 0, 0,
96 0, 0, 0, 0, 0, KEY_MENU, 0, 0,
97 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, KEY_UNDO, KEY_REPEAT, KEY_FIND, KEY_HELP, 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 0, 0, 0, 0, 0, 0, 0, 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
109 if( aCode < sizeof( aKeyCodeMap) / sizeof( aKeyCodeMap[0] ) )
110 nKeyCode = aKeyCodeMap[ aCode ];
111 else if( aCode >= 0xf700 && aCode < 0xf780 )
112 nKeyCode = aFunctionKeyCodeMap[ aCode - 0xf700 ];
116 // store the frame the mouse last entered
117 static AquaSalFrame* s_pMouseFrame = NULL;
118 // store the last pressed button for enter/exit events
119 // which lack that information
120 static USHORT s_nLastButton = 0;
122 // combinations of keys we need to handle ourselves
123 static const struct ExceptionalKey
125 const USHORT nKeyCode;
126 const unsigned int nModifierMask;
127 } aExceptionalKeys[] =
129 { KEY_D, NSControlKeyMask | NSShiftKeyMask | NSAlternateKeyMask },
130 { KEY_D, NSCommandKeyMask | NSShiftKeyMask | NSAlternateKeyMask }
133 static AquaSalFrame* getMouseContainerFrame()
136 NSCountWindows( &nWindows );
137 int* pWindows = (int*)alloca( nWindows * sizeof(int) );
138 // note: NSWindowList is supposed to be in z-order front to back
139 NSWindowList( nWindows, pWindows );
140 AquaSalFrame* pDispatchFrame = NULL;
141 for(int i = 0; i < nWindows && ! pDispatchFrame; i++ )
143 NSWindow* pWin = [NSApp windowWithWindowNumber: pWindows[i]];
144 if( pWin && [pWin isMemberOfClass: [SalFrameWindow class]] && [(SalFrameWindow*)pWin containsMouse] )
145 pDispatchFrame = [(SalFrameWindow*)pWin getSalFrame];
147 return pDispatchFrame;
150 @implementation SalFrameWindow
151 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
153 mDraggingDestinationHandler = nil;
155 NSRect aRect = { { pFrame->maGeometry.nX, pFrame->maGeometry.nY },
156 { pFrame->maGeometry.nWidth, pFrame->maGeometry.nHeight } };
157 pFrame->VCLToCocoa( aRect );
158 return [super initWithContentRect: aRect styleMask: mpFrame->getStyleMask() backing: NSBackingStoreBuffered defer: NO ];
161 -(AquaSalFrame*)getSalFrame
166 -(MacOSBOOL)containsMouse
168 // is this event actually inside that NSWindow ?
169 NSPoint aPt = [NSEvent mouseLocation];
170 NSRect aFrameRect = [self frame];
171 MacOSBOOL bInRect = NSPointInRect( aPt, aFrameRect );
175 -(MacOSBOOL)canBecomeKeyWindow
177 if( (mpFrame->mnStyle &
178 ( SAL_FRAME_STYLE_FLOAT |
179 SAL_FRAME_STYLE_TOOLTIP |
180 SAL_FRAME_STYLE_INTRO
183 if( (mpFrame->mnStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) != 0 )
185 if( mpFrame->mbFullScreen )
187 return [super canBecomeKeyWindow];
190 -(void)windowDidBecomeKey: (NSNotification*)pNotification
194 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
196 static const ULONG nGuessDocument = SAL_FRAME_STYLE_MOVEABLE|
197 SAL_FRAME_STYLE_SIZEABLE|
198 SAL_FRAME_STYLE_CLOSEABLE;
200 if( mpFrame->mpMenu )
201 mpFrame->mpMenu->setMainMenu();
202 else if( ! mpFrame->mpParent &&
203 ( (mpFrame->mnStyle & nGuessDocument) == nGuessDocument || // set default menu for e.g. help
204 mpFrame->mbFullScreen ) ) // ser default menu for e.g. presentation
206 AquaSalMenu::setDefaultMenu();
209 // FIXME: we should disable menus while in modal mode
210 // however from down here there is currently no reliable way to
211 // find out when to do this
212 if( (mpFrame->mpParent && mpFrame->mpParent->GetWindow()->IsInModalMode()) )
213 AquaSalMenu::enableMainMenu( false );
215 mpFrame->CallCallback( SALEVENT_GETFOCUS, 0 );
219 -(void)windowDidResignKey: (NSNotification*)pNotification
223 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
224 mpFrame->CallCallback(SALEVENT_LOSEFOCUS, 0);
227 -(void)windowDidChangeScreen: (NSNotification*)pNotification
231 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
232 mpFrame->screenParametersChanged();
235 -(void)windowDidMove: (NSNotification*)pNotification
239 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
241 mpFrame->UpdateFrameGeometry();
242 mpFrame->CallCallback( SALEVENT_MOVE, 0 );
246 -(void)windowDidResize: (NSNotification*)pNotification
250 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
252 mpFrame->UpdateFrameGeometry();
253 mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
254 mpFrame->SendPaintEvent();
258 -(void)windowDidMiniaturize: (NSNotification*)pNotification
262 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
264 mpFrame->mbShown = false;
265 mpFrame->UpdateFrameGeometry();
266 mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
270 -(void)windowDidDeminiaturize: (NSNotification*)pNotification
274 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
276 mpFrame->mbShown = true;
277 mpFrame->UpdateFrameGeometry();
278 mpFrame->CallCallback( SALEVENT_RESIZE, 0 );
282 -(MacOSBOOL)windowShouldClose: (NSNotification*)pNotification
286 MacOSBOOL bRet = YES;
287 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
289 // #i84461# end possible input
290 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
291 if( AquaSalFrame::isAlive( mpFrame ) )
293 mpFrame->CallCallback( SALEVENT_CLOSE, 0 );
294 bRet = NO; // application will close the window or not, AppKit shouldn't
301 -(void)dockMenuItemTriggered: (id)sender
305 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
306 mpFrame->ToTop( SAL_FRAME_TOTOP_RESTOREWHENMIN | SAL_FRAME_TOTOP_GRABFOCUS );
309 -(::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessibleContext >)accessibleContext
311 return mpFrame -> GetWindow() -> GetAccessible() -> getAccessibleContext();
314 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
316 return [mDraggingDestinationHandler draggingEntered: sender];
319 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
321 return [mDraggingDestinationHandler draggingUpdated: sender];
324 -(void)draggingExited:(id <NSDraggingInfo>)sender
326 [mDraggingDestinationHandler draggingExited: sender];
329 -(MacOSBOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
331 return [mDraggingDestinationHandler prepareForDragOperation: sender];
334 -(MacOSBOOL)performDragOperation:(id <NSDraggingInfo>)sender
336 return [mDraggingDestinationHandler performDragOperation: sender];
339 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
341 [mDraggingDestinationHandler concludeDragOperation: sender];
344 -(void)registerDraggingDestinationHandler:(id)theHandler
346 mDraggingDestinationHandler = theHandler;
349 -(void)unregisterDraggingDestinationHandler:(id)theHandler
351 mDraggingDestinationHandler = nil;
356 @implementation SalFrameView
357 +(void)unsetMouseFrame: (AquaSalFrame*)pFrame
359 if( pFrame == s_pMouseFrame )
360 s_pMouseFrame = NULL;
363 -(id)initWithSalFrame: (AquaSalFrame*)pFrame
365 if ((self = [super initWithFrame: [NSWindow contentRectForFrameRect: [pFrame->getWindow() frame] styleMask: pFrame->mnStyleMask]]) != nil)
367 mDraggingDestinationHandler = nil;
369 mMarkedRange = NSMakeRange(NSNotFound, 0);
370 mSelectedRange = NSMakeRange(NSNotFound, 0);
371 mpReferenceWrapper = nil;
372 mpMouseEventListener = nil;
373 mpLastSuperEvent = nil;
379 -(void)resetCursorRects
381 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
383 // FIXME: does this leak the returned NSCursor of getCurrentCursor ?
384 NSRect aRect = { { 0, 0 }, { mpFrame->maGeometry.nWidth, mpFrame->maGeometry.nHeight } };
385 [self addCursorRect: aRect cursor: mpFrame->getCurrentCursor()];
389 -(MacOSBOOL)acceptsFirstResponder
394 -(MacOSBOOL)acceptsFirstMouse: (NSEvent*)pEvent
401 return mpFrame ? (mpFrame->getClipPath() != 0 ? NO : YES) : YES;
404 // helper class similar to a vos::OGuard for the SalYieldMutex
405 // the difference is that it only does tryToAcquire instead of aquire
406 // so dreaded deadlocks like #i93512# are prevented
410 TryGuard() { mbGuarded = ImplSalYieldMutexTryToAcquire(); }
411 ~TryGuard() { if( mbGuarded ) ImplSalYieldMutexRelease(); }
412 bool IsGuarded() { return mbGuarded; }
417 -(void)drawRect: (NSRect)aRect
419 // HOTFIX: #i93512# prevent deadlocks if any other thread already has the SalYieldMutex
421 if( !aTryGuard.IsGuarded() )
423 // NOTE: the mpFrame access below is not guarded yet!
424 // TODO: mpFrame et al need to be guarded by an independent mutex
425 AquaSalGraphics* pGraphics = (mpFrame && AquaSalFrame::isAlive(mpFrame)) ? mpFrame->mpGraphics : NULL;
428 // we did not get the mutex so we cannot draw now => request to redraw later
429 // convert the NSRect to a CGRect for Refreshrect()
430 const CGRect aCGRect = {{aRect.origin.x,aRect.origin.y},{aRect.size.width,aRect.size.height}};
431 pGraphics->RefreshRect( aCGRect );
436 if( mpFrame && AquaSalFrame::isAlive( mpFrame ) )
438 if( mpFrame->mpGraphics )
440 mpFrame->mpGraphics->UpdateWindow( aRect );
441 if( mpFrame->getClipPath() )
442 [mpFrame->getWindow() invalidateShadow];
447 -(void)sendMouseEventToFrame: (NSEvent*)pEvent button:(USHORT)nButton eventtype:(USHORT)nEvent
451 AquaSalFrame* pDispatchFrame = AquaSalFrame::GetCaptureFrame();
452 bool bIsCaptured = false;
456 if( nEvent == SALEVENT_MOUSELEAVE ) // no leave events if mouse is captured
457 nEvent = SALEVENT_MOUSEMOVE;
459 else if( s_pMouseFrame )
460 pDispatchFrame = s_pMouseFrame;
462 pDispatchFrame = mpFrame;
464 /* #i81645# Cocoa reports mouse events while a button is pressed
465 to the window in which it was first pressed. This is reasonable and fine and
466 gets one around most cases where on other platforms one uses CaptureMouse or XGrabPointer,
467 however vcl expects mouse events to occur in the window the mouse is over, unless the
468 mouse is explicitly captured. So we need to find the window the mouse is actually
469 over for conformance with other platforms.
471 if( ! bIsCaptured && nButton && pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
473 // is this event actually inside that NSWindow ?
474 NSPoint aPt = [NSEvent mouseLocation];
475 NSRect aFrameRect = [pDispatchFrame->getWindow() frame];
477 if ( ! NSPointInRect( aPt, aFrameRect ) )
480 // now we need to find the one it may be in
481 /* #i93756# we ant to get enumerate the application windows in z-order
482 to check if any contains the mouse. This could be elegantly done with this
485 // use NSApp to check windows in ZOrder whether they contain the mouse pointer
486 NSWindow* pWindow = [NSApp makeWindowsPerform: @selector(containsMouse) inOrder: YES];
487 if( pWindow && [pWindow isMemberOfClass: [SalFrameWindow class]] )
488 pDispatchFrame = [(SalFrameWindow*)pWindow getSalFrame];
490 However if a non SalFrameWindow is on screen (like e.g. the file dialog)
491 it can be hit with the containsMouse selector, which it doesn't support.
492 Sadly NSApplication:makeWindowsPerform does not check (for performance reasons
493 I assume) whether a window supports a selector before sending it.
495 AquaSalFrame* pMouseFrame = getMouseContainerFrame();
497 pDispatchFrame = pMouseFrame;
501 if( pDispatchFrame && AquaSalFrame::isAlive( pDispatchFrame ) )
503 pDispatchFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
504 pDispatchFrame->mnLastModifierFlags = [pEvent modifierFlags];
506 NSPoint aPt = [NSEvent mouseLocation];
507 pDispatchFrame->CocoaToVCL( aPt );
509 USHORT nModMask = ImplGetModifierMask( [pEvent modifierFlags] );
510 // #i82284# emulate ctrl left
511 if( nModMask == KEY_MOD3 && nButton == MOUSE_LEFT )
514 nButton = MOUSE_RIGHT;
517 SalMouseEvent aEvent;
518 aEvent.mnTime = pDispatchFrame->mnLastEventTime;
519 aEvent.mnX = static_cast<long>(aPt.x) - pDispatchFrame->maGeometry.nX;
520 aEvent.mnY = static_cast<long>(aPt.y) - pDispatchFrame->maGeometry.nY;
521 aEvent.mnButton = nButton;
522 aEvent.mnCode = aEvent.mnButton | nModMask;
524 // --- RTL --- (mirror mouse pos)
525 if( Application::GetSettings().GetLayoutRTL() )
526 aEvent.mnX = pDispatchFrame->maGeometry.nWidth-1-aEvent.mnX;
528 pDispatchFrame->CallCallback( nEvent, &aEvent );
532 -(void)mouseDown: (NSEvent*)pEvent
534 if ( mpMouseEventListener != nil &&
535 [mpMouseEventListener respondsToSelector: @selector(mouseDown:)])
537 [mpMouseEventListener mouseDown: [pEvent copyWithZone: NULL]];
540 s_nLastButton = MOUSE_LEFT;
541 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONDOWN];
544 -(void)mouseDragged: (NSEvent*)pEvent
546 if ( mpMouseEventListener != nil &&
547 [mpMouseEventListener respondsToSelector: @selector(mouseDragged:)])
549 [mpMouseEventListener mouseDragged: [pEvent copyWithZone: NULL]];
551 s_nLastButton = MOUSE_LEFT;
552 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEMOVE];
555 -(void)mouseUp: (NSEvent*)pEvent
558 [self sendMouseEventToFrame:pEvent button:MOUSE_LEFT eventtype:SALEVENT_MOUSEBUTTONUP];
561 -(void)mouseMoved: (NSEvent*)pEvent
564 [self sendMouseEventToFrame:pEvent button:0 eventtype:SALEVENT_MOUSEMOVE];
567 -(void)mouseEntered: (NSEvent*)pEvent
569 s_pMouseFrame = mpFrame;
571 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSEMOVE];
574 -(void)mouseExited: (NSEvent*)pEvent
576 if( s_pMouseFrame == mpFrame )
577 s_pMouseFrame = NULL;
579 [self sendMouseEventToFrame:pEvent button:s_nLastButton eventtype:SALEVENT_MOUSELEAVE];
582 -(void)rightMouseDown: (NSEvent*)pEvent
584 s_nLastButton = MOUSE_RIGHT;
585 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONDOWN];
588 -(void)rightMouseDragged: (NSEvent*)pEvent
590 s_nLastButton = MOUSE_RIGHT;
591 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEMOVE];
594 -(void)rightMouseUp: (NSEvent*)pEvent
597 [self sendMouseEventToFrame:pEvent button:MOUSE_RIGHT eventtype:SALEVENT_MOUSEBUTTONUP];
600 -(void)otherMouseDown: (NSEvent*)pEvent
602 if( [pEvent buttonNumber] == 2 )
604 s_nLastButton = MOUSE_MIDDLE;
605 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONDOWN];
611 -(void)otherMouseDragged: (NSEvent*)pEvent
613 if( [pEvent buttonNumber] == 2 )
615 s_nLastButton = MOUSE_MIDDLE;
616 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEMOVE];
622 -(void)otherMouseUp: (NSEvent*)pEvent
625 if( [pEvent buttonNumber] == 2 )
626 [self sendMouseEventToFrame:pEvent button:MOUSE_MIDDLE eventtype:SALEVENT_MOUSEBUTTONUP];
629 - (void)magnifyWithEvent: (NSEvent*)pEvent
633 // TODO: ?? -(float)magnification;
634 if( AquaSalFrame::isAlive( mpFrame ) )
636 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
637 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
642 dZ += [pEvent deltaZ];
643 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
644 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
650 NSPoint aPt = [NSEvent mouseLocation];
651 mpFrame->CocoaToVCL( aPt );
653 SalWheelMouseEvent aEvent;
654 aEvent.mnTime = mpFrame->mnLastEventTime;
655 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
656 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
657 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
658 aEvent.mnCode |= KEY_MOD1; // we want zooming, no scrolling
660 // --- RTL --- (mirror mouse pos)
661 if( Application::GetSettings().GetLayoutRTL() )
662 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
666 aEvent.mnDelta = static_cast<long>(floor(dZ));
667 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
668 if( aEvent.mnNotchDelta == 0 )
669 aEvent.mnNotchDelta = dZ < 0.0 ? -1 : 1;
670 aEvent.mbHorz = FALSE;
671 aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta;
672 if( aEvent.mnScrollLines == 0 )
673 aEvent.mnScrollLines = 1;
674 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
679 - (void)rotateWithEvent: (NSEvent*)pEvent
681 //Rotation : -(float)rotation;
682 // TODO: create new CommandType so rotation is available to the applications
685 - (void)swipeWithEvent: (NSEvent*)pEvent
689 if( AquaSalFrame::isAlive( mpFrame ) )
691 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
692 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
694 // merge pending scroll wheel events
699 dX += [pEvent deltaX];
700 dY += [pEvent deltaY];
701 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
702 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
708 NSPoint aPt = [NSEvent mouseLocation];
709 mpFrame->CocoaToVCL( aPt );
711 SalWheelMouseEvent aEvent;
712 aEvent.mnTime = mpFrame->mnLastEventTime;
713 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
714 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
715 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
717 // --- RTL --- (mirror mouse pos)
718 if( Application::GetSettings().GetLayoutRTL() )
719 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
723 aEvent.mnDelta = static_cast<long>(floor(dX));
724 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
725 if( aEvent.mnNotchDelta == 0 )
726 aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1;
727 aEvent.mbHorz = TRUE;
728 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
729 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
731 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ))
733 aEvent.mnDelta = static_cast<long>(floor(dY));
734 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
735 if( aEvent.mnNotchDelta == 0 )
736 aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1;
737 aEvent.mbHorz = FALSE;
738 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
739 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
744 -(void)scrollWheel: (NSEvent*)pEvent
748 if( AquaSalFrame::isAlive( mpFrame ) )
750 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
751 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
753 // merge pending scroll wheel events
758 dX += [pEvent deltaX];
759 dY += [pEvent deltaY];
760 NSEvent* pNextEvent = [NSApp nextEventMatchingMask: NSScrollWheelMask
761 untilDate: nil inMode: NSDefaultRunLoopMode dequeue: YES ];
767 NSPoint aPt = [NSEvent mouseLocation];
768 mpFrame->CocoaToVCL( aPt );
770 SalWheelMouseEvent aEvent;
771 aEvent.mnTime = mpFrame->mnLastEventTime;
772 aEvent.mnX = static_cast<long>(aPt.x) - mpFrame->maGeometry.nX;
773 aEvent.mnY = static_cast<long>(aPt.y) - mpFrame->maGeometry.nY;
774 aEvent.mnCode = ImplGetModifierMask( mpFrame->mnLastModifierFlags );
776 // --- RTL --- (mirror mouse pos)
777 if( Application::GetSettings().GetLayoutRTL() )
778 aEvent.mnX = mpFrame->maGeometry.nWidth-1-aEvent.mnX;
782 aEvent.mnDelta = static_cast<long>(floor(dX));
783 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
784 if( aEvent.mnNotchDelta == 0 )
785 aEvent.mnNotchDelta = dX < 0.0 ? -1 : 1;
786 aEvent.mbHorz = TRUE;
787 aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta;
788 if( aEvent.mnScrollLines == 0 )
789 aEvent.mnScrollLines = 1;
790 if( aEvent.mnScrollLines > 15 )
791 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
792 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
794 if( dY != 0.0 && AquaSalFrame::isAlive( mpFrame ) )
796 aEvent.mnDelta = static_cast<long>(floor(dY));
797 aEvent.mnNotchDelta = aEvent.mnDelta / 8;
798 if( aEvent.mnNotchDelta == 0 )
799 aEvent.mnNotchDelta = dY < 0.0 ? -1 : 1;
800 aEvent.mbHorz = FALSE;
801 aEvent.mnScrollLines = aEvent.mnNotchDelta > 0 ? aEvent.mnNotchDelta : -aEvent.mnNotchDelta;
802 if( aEvent.mnScrollLines == 0 )
803 aEvent.mnScrollLines = 1;
804 if( aEvent.mnScrollLines > 15 )
805 aEvent.mnScrollLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
807 mpFrame->CallCallback( SALEVENT_WHEELMOUSE, &aEvent );
813 -(void)keyDown: (NSEvent*)pEvent
817 if( AquaSalFrame::isAlive( mpFrame ) )
819 mpLastEvent = pEvent;
821 mbNeedSpecialKeyHandle = false;
822 mbKeyHandled = false;
824 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
825 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
827 if( ! [self handleKeyDownException: pEvent] )
829 NSArray* pArray = [NSArray arrayWithObject: pEvent];
830 [self interpretKeyEvents: pArray];
833 mbInKeyInput = false;
837 -(MacOSBOOL)handleKeyDownException:(NSEvent*)pEvent
839 // check for a very special set of modified characters
840 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers];
842 if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
844 /* #i103102# key events with command and alternate don't make it through
845 interpretKeyEvents (why ?). Try to dispatch them here first,
846 if not successful continue normally
848 if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask))
849 == (NSAlternateKeyMask | NSCommandKeyMask) )
851 if( [self sendSingleCharacter: mpLastEvent] )
854 unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
855 USHORT nKeyCode = ImplMapCharCode( keyChar );
857 // Caution: should the table grow to more than 5 or 6 entries,
858 // we must consider moving it to a kind of hash map
859 const unsigned int nExceptions = sizeof( aExceptionalKeys ) / sizeof( aExceptionalKeys[0] );
860 for( unsigned int i = 0; i < nExceptions; i++ )
862 if( nKeyCode == aExceptionalKeys[i].nKeyCode &&
863 (mpFrame->mnLastModifierFlags & aExceptionalKeys[i].nModifierMask)
864 == aExceptionalKeys[i].nModifierMask )
866 [self sendKeyInputAndReleaseToFrame: nKeyCode character: 0];
875 -(void)flagsChanged: (NSEvent*)pEvent
879 if( AquaSalFrame::isAlive( mpFrame ) )
881 mpFrame->mnLastEventTime = static_cast<ULONG>( [pEvent timestamp] * 1000.0 );
882 mpFrame->mnLastModifierFlags = [pEvent modifierFlags];
886 -(void)insertText:(id)aString
890 if( AquaSalFrame::isAlive( mpFrame ) )
892 NSString* pInsert = nil;
893 if( [aString isMemberOfClass: [NSAttributedString class]] )
894 pInsert = [aString string];
899 if( pInsert && ( nLen = [pInsert length] ) > 0 )
901 OUString aInsertString( GetOUString( pInsert ) );
902 // aCharCode initializer is safe since aInsertString will at least contain '\0'
903 sal_Unicode aCharCode = *aInsertString.getStr();
908 ! [self hasMarkedText ]
911 USHORT nKeyCode = ImplMapCharCode( aCharCode );
912 unsigned int nLastModifiers = mpFrame->mnLastModifierFlags;
915 // find out the unmodified key code
918 if( mpLastEvent && ( [mpLastEvent type] == NSKeyDown || [mpLastEvent type] == NSKeyUp ) )
920 // get unmodified string
921 NSString* pUnmodifiedString = [mpLastEvent charactersIgnoringModifiers];
922 if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
924 // map the unmodified key code
925 unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
926 nKeyCode = ImplMapCharCode( keyChar );
928 nLastModifiers = [mpLastEvent modifierFlags];
932 // applications and vcl's edit fields ignore key events with ALT
933 // however we're at a place where we know text should be inserted
934 // so it seems we need to strip the Alt modifier here
935 if( (nLastModifiers & (NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask))
936 == NSAlternateKeyMask )
940 [self sendKeyInputAndReleaseToFrame: nKeyCode character: aCharCode modifiers: nLastModifiers];
944 SalExtTextInputEvent aEvent;
945 aEvent.mnTime = mpFrame->mnLastEventTime;
946 aEvent.maText = aInsertString;
947 aEvent.mpTextAttr = NULL;
948 aEvent.mnCursorPos = aInsertString.getLength();
949 aEvent.mnDeltaStart = 0;
950 aEvent.mnCursorFlags = 0;
951 aEvent.mbOnlyCursor = FALSE;
952 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
953 if( AquaSalFrame::isAlive( mpFrame ) )
954 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
959 SalExtTextInputEvent aEvent;
960 aEvent.mnTime = mpFrame->mnLastEventTime;
961 aEvent.maText = String();
962 aEvent.mpTextAttr = NULL;
963 aEvent.mnCursorPos = 0;
964 aEvent.mnDeltaStart = 0;
965 aEvent.mnCursorFlags = 0;
966 aEvent.mbOnlyCursor = FALSE;
967 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, &aEvent );
968 if( AquaSalFrame::isAlive( mpFrame ) )
969 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
977 -(void)insertTab: (id)aSender
979 [self sendKeyInputAndReleaseToFrame: KEY_TAB character: '\t' modifiers: 0];
982 -(void)insertBacktab: (id)aSender
984 [self sendKeyInputAndReleaseToFrame: (KEY_TAB | KEY_SHIFT) character: '\t' modifiers: 0];
987 -(void)moveLeft: (id)aSender
989 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: 0];
992 -(void)moveLeftAndModifySelection: (id)aSender
994 [self sendKeyInputAndReleaseToFrame: KEY_LEFT character: 0 modifiers: NSShiftKeyMask];
997 -(void)moveBackwardAndModifySelection: (id)aSender
999 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_BACKWARD character: 0 modifiers: 0];
1002 -(void)moveRight: (id)aSender
1004 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: 0];
1007 -(void)moveRightAndModifySelection: (id)aSender
1009 [self sendKeyInputAndReleaseToFrame: KEY_RIGHT character: 0 modifiers: NSShiftKeyMask];
1012 -(void)moveForwardAndModifySelection: (id)aSender
1014 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_FORWARD character: 0 modifiers: 0];
1017 -(void)moveWordLeft: (id)aSender
1019 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0];
1022 -(void)moveWordBackward: (id)aSender
1024 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_BACKWARD character: 0 modifiers: 0];
1027 -(void)moveWordBackwardAndModifySelection: (id)aSender
1029 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0];
1032 -(void)moveWordLeftAndModifySelection: (id)aSender
1034 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_BACKWARD character: 0 modifiers: 0];
1037 -(void)moveWordRight: (id)aSender
1039 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0];
1042 -(void)moveWordForward: (id)aSender
1044 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_WORD_FORWARD character: 0 modifiers: 0];
1047 -(void)moveWordForwardAndModifySelection: (id)aSender
1049 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0];
1052 -(void)moveWordRightAndModifySelection: (id)aSender
1054 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD_FORWARD character: 0 modifiers: 0];
1057 -(void)moveToEndOfLine: (id)aSender
1059 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_LINE character: 0 modifiers: 0];
1062 -(void)moveToEndOfLineAndModifySelection: (id)aSender
1064 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_LINE character: 0 modifiers: 0];
1067 -(void)moveToBeginningOfLine: (id)aSender
1069 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE character: 0 modifiers: 0];
1072 -(void)moveToBeginningOfLineAndModifySelection: (id)aSender
1074 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE character: 0 modifiers: 0];
1077 -(void)moveToEndOfParagraph: (id)aSender
1079 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1082 -(void)moveToEndOfParagraphAndModifySelection: (id)aSender
1084 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1087 -(void)moveParagraphForward: (id)aSender
1089 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1092 -(void)moveParagraphForwardAndModifySelection: (id)aSender
1094 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1097 -(void)moveToBeginningOfParagraph: (id)aSender
1099 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1102 -(void)moveParagraphBackward: (id)aSender
1104 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1107 -(void)moveToBeginningOfParagraphAndModifySelection: (id)aSender
1109 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1112 -(void)moveParagraphBackwardAndModifySelection: (id)aSender
1114 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1117 -(void)moveToEndOfDocument: (id)aSender
1119 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT character: 0 modifiers: 0];
1122 -(void)moveToEndOfDocumentAndModifySelection: (id)aSender
1124 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT character: 0 modifiers: 0];
1127 -(void)moveToBeginningOfDocument: (id)aSender
1129 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0];
1132 -(void)moveToBeginningOfDocumentAndModifySelection: (id)aSender
1134 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT character: 0 modifiers: 0];
1137 -(void)moveUp: (id)aSender
1139 [self sendKeyInputAndReleaseToFrame: KEY_UP character: 0 modifiers: 0];
1142 -(void)moveDown: (id)aSender
1144 [self sendKeyInputAndReleaseToFrame: KEY_DOWN character: 0 modifiers: 0];
1147 -(void)insertNewline: (id)aSender
1149 // #i91267# make enter and shift-enter work by evaluating the modifiers
1150 [self sendKeyInputAndReleaseToFrame: KEY_RETURN character: '\n' modifiers: mpFrame->mnLastModifierFlags];
1153 -(void)deleteBackward: (id)aSender
1155 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1158 -(void)deleteForward: (id)aSender
1160 [self sendKeyInputAndReleaseToFrame: KEY_DELETE character: 0x7f modifiers: 0];
1163 -(void)deleteBackwardByDecomposingPreviousCharacter: (id)aSender
1165 [self sendKeyInputAndReleaseToFrame: KEY_BACKSPACE character: '\b' modifiers: 0];
1168 -(void)deleteWordBackward: (id)aSender
1170 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_BACKWARD character: 0 modifiers: 0];
1173 -(void)deleteWordForward: (id)aSender
1175 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_WORD_FORWARD character: 0 modifiers: 0];
1178 -(void)deleteToBeginningOfLine: (id)aSender
1180 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE character: 0 modifiers: 0];
1183 -(void)deleteToEndOfLine: (id)aSender
1185 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_LINE character: 0 modifiers: 0];
1188 -(void)deleteToBeginningOfParagraph: (id)aSender
1190 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH character: 0 modifiers: 0];
1193 -(void)deleteToEndOfParagraph: (id)aSender
1195 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::DELETE_TO_END_OF_PARAGRAPH character: 0 modifiers: 0];
1198 -(void)insertLineBreak: (id)aSender
1200 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_LINEBREAK character: 0 modifiers: 0];
1203 -(void)insertParagraphSeparator: (id)aSender
1205 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::INSERT_PARAGRAPH character: 0 modifiers: 0];
1208 -(void)selectWord: (id)aSender
1210 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_WORD character: 0 modifiers: 0];
1213 -(void)selectLine: (id)aSender
1215 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_LINE character: 0 modifiers: 0];
1218 -(void)selectParagraph: (id)aSender
1220 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_PARAGRAPH character: 0 modifiers: 0];
1223 -(void)selectAll: (id)aSender
1225 [self sendKeyInputAndReleaseToFrame: com::sun::star::awt::Key::SELECT_ALL character: 0 modifiers: 0];
1228 -(void)cancelOperation: (id)aSender
1230 [self sendKeyInputAndReleaseToFrame: KEY_ESCAPE character: 0x1b modifiers: 0];
1233 -(void)noop: (id)aSender
1235 if( ! mbKeyHandled )
1237 if( ! [self sendSingleCharacter:mpLastEvent] )
1239 /* prevent recursion */
1240 if( mpLastEvent != mpLastSuperEvent && [NSApp respondsToSelector: @selector(sendSuperEvent:)] )
1242 id pLastSuperEvent = mpLastSuperEvent;
1243 mpLastSuperEvent = mpLastEvent;
1244 [NSApp performSelector:@selector(sendSuperEvent:) withObject: mpLastEvent];
1245 mpLastSuperEvent = pLastSuperEvent;
1247 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1248 if( it != GetSalData()->maKeyEventAnswer.end() )
1255 -(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar
1257 return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags];
1260 -(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1262 return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] ||
1263 [self sendSingleCharacter: mpLastEvent];
1266 -(MacOSBOOL)sendKeyToFrameDirect: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod
1271 if( AquaSalFrame::isAlive( mpFrame ) )
1274 aEvent.mnTime = mpFrame->mnLastEventTime;
1275 aEvent.mnCode = nKeyCode | ImplGetModifierMask( nMod );
1276 aEvent.mnCharCode = aChar;
1277 aEvent.mnRepeat = FALSE;
1278 nRet = mpFrame->CallCallback( SALEVENT_KEYINPUT, &aEvent );
1279 std::map< NSEvent*, bool >::iterator it = GetSalData()->maKeyEventAnswer.find( mpLastEvent );
1280 if( it != GetSalData()->maKeyEventAnswer.end() )
1281 it->second = nRet ? true : false;
1282 if( AquaSalFrame::isAlive( mpFrame ) )
1283 mpFrame->CallCallback( SALEVENT_KEYUP, &aEvent );
1285 return nRet ? YES : NO;
1289 -(MacOSBOOL)sendSingleCharacter: (NSEvent *)pEvent
1291 NSString* pUnmodifiedString = [pEvent charactersIgnoringModifiers];
1293 if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
1295 unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
1296 USHORT nKeyCode = ImplMapCharCode( keyChar );
1299 // don't send unicodes in the private use area
1300 if( keyChar >= 0xf700 && keyChar < 0xf780 )
1302 MacOSBOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags];
1303 mbInKeyInput = false;
1312 // NSTextInput protocol
1313 - (NSArray *)validAttributesForMarkedText
1315 return [NSArray arrayWithObjects:NSUnderlineStyleAttributeName, nil];
1318 - (MacOSBOOL)hasMarkedText
1320 MacOSBOOL bHasMarkedText;
1322 bHasMarkedText = ( mMarkedRange.location != NSNotFound ) &&
1323 ( mMarkedRange.length != 0 );
1324 // hack to check keys like "Control-j"
1327 mbNeedSpecialKeyHandle = true;
1329 return bHasMarkedText;
1332 - (NSRange)markedRange
1334 return [self hasMarkedText] ? mMarkedRange : NSMakeRange( NSNotFound, 0 );
1337 - (NSRange)selectedRange
1339 return mSelectedRange;
1342 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange
1344 if( ![aString isKindOfClass:[NSAttributedString class]] )
1345 aString = [[[NSAttributedString alloc] initWithString:aString] autorelease];
1346 NSRange rangeToReplace = [self hasMarkedText] ? [self markedRange] : [self selectedRange];
1347 if( rangeToReplace.location == NSNotFound )
1349 mMarkedRange = NSMakeRange( selRange.location, [aString length] );
1350 mSelectedRange = NSMakeRange( selRange.location, selRange.length );
1354 mMarkedRange = NSMakeRange( rangeToReplace.location, [aString length] );
1355 mSelectedRange = NSMakeRange( rangeToReplace.location + selRange.location, selRange.length );
1358 int len = [aString length];
1359 SalExtTextInputEvent aInputEvent;
1360 aInputEvent.mnTime = mpFrame->mnLastEventTime;
1361 aInputEvent.mnDeltaStart = 0;
1362 aInputEvent.mbOnlyCursor = FALSE;
1364 NSString *pString = [aString string];
1365 OUString aInsertString( GetOUString( pString ) );
1366 std::vector<USHORT> aInputFlags = std::vector<USHORT>( std::max( 1, len ), 0 );
1367 for ( int i = 0; i < len; i++ )
1369 unsigned int nUnderlineValue;
1370 NSRange effectiveRange;
1372 effectiveRange = NSMakeRange(i, 1);
1373 nUnderlineValue = [[aString attribute:NSUnderlineStyleAttributeName atIndex:i effectiveRange:&effectiveRange] unsignedIntValue];
1375 switch (nUnderlineValue & 0xff) {
1376 case NSUnderlineStyleSingle:
1377 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
1379 case NSUnderlineStyleThick:
1380 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_UNDERLINE | SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
1382 case NSUnderlineStyleDouble:
1383 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_BOLDUNDERLINE;
1386 aInputFlags[i] = SAL_EXTTEXTINPUT_ATTR_HIGHLIGHT;
1391 aInputEvent.maText = aInsertString;
1392 aInputEvent.mnCursorPos = selRange.location;
1393 aInputEvent.mpTextAttr = &aInputFlags[0];
1394 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1396 aInputEvent.maText = String();
1397 aInputEvent.mnCursorPos = 0;
1398 aInputEvent.mnCursorFlags = 0;
1399 aInputEvent.mpTextAttr = 0;
1400 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void *)&aInputEvent );
1401 mpFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, 0 );
1408 mSelectedRange = mMarkedRange = NSMakeRange(NSNotFound, 0);
1411 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange
1417 - (unsigned int)characterIndexForPoint:(NSPoint)thePoint
1423 #ifdef MAC_OS_X_VERSION_10_5
1424 /* build target 10.5 or greater */
1425 - (NSInteger)conversationIdentifier
1427 /* build target 10.4 */
1428 - (long)conversationIdentifier
1434 - (void)doCommandBySelector:(SEL)aSelector
1436 if( AquaSalFrame::isAlive( mpFrame ) )
1438 if( (mpFrame->mnICOptions & SAL_INPUTCONTEXT_TEXT) != 0 &&
1439 aSelector != NULL && [self respondsToSelector: aSelector] )
1441 [self performSelector: aSelector];
1445 [self sendSingleCharacter:mpLastEvent];
1449 mbKeyHandled = true;
1452 - (NSRect)firstRectForCharacterRange:(NSRange)theRange
1454 SalExtTextInputPosEvent aPosEvent;
1455 mpFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void *)&aPosEvent );
1459 rect.origin.x = aPosEvent.mnX + mpFrame->maGeometry.nX;
1460 rect.origin.y = aPosEvent.mnY + mpFrame->maGeometry.nY + 4; // add some space for underlines
1461 rect.size.width = aPosEvent.mnWidth;
1462 rect.size.height = aPosEvent.mnHeight;
1464 mpFrame->VCLToCocoa( rect );
1468 -(id)parentAttribute {
1469 return (NSView *) mpFrame -> mpWindow;
1472 -(::com::sun::star::accessibility::XAccessibleContext *)accessibleContext
1474 if ( mpReferenceWrapper == nil ) {
1475 // some frames never become visible ..
1476 Window *pWindow = mpFrame -> GetWindow();
1480 mpReferenceWrapper = new ReferenceWrapper;
1481 mpReferenceWrapper -> rAccessibleContext = pWindow -> /*GetAccessibleChildWindow( 0 ) ->*/ GetAccessible() -> getAccessibleContext();
1482 [ AquaA11yFactory insertIntoWrapperRepository: self forAccessibleContext: mpReferenceWrapper -> rAccessibleContext ];
1484 return [ super accessibleContext ];
1487 -(NSView *)viewElementForParent
1489 return (NSView *) mpFrame -> mpWindow;
1492 -(void)registerMouseEventListener: (id)theListener
1494 mpMouseEventListener = theListener;
1497 -(void)unregisterMouseEventListener: (id)theListener
1499 mpMouseEventListener = nil;
1502 -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
1504 return [mDraggingDestinationHandler draggingEntered: sender];
1507 -(NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
1509 return [mDraggingDestinationHandler draggingUpdated: sender];
1512 -(void)draggingExited:(id <NSDraggingInfo>)sender
1514 [mDraggingDestinationHandler draggingExited: sender];
1517 -(MacOSBOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
1519 return [mDraggingDestinationHandler prepareForDragOperation: sender];
1522 -(MacOSBOOL)performDragOperation:(id <NSDraggingInfo>)sender
1524 return [mDraggingDestinationHandler performDragOperation: sender];
1527 -(void)concludeDragOperation:(id <NSDraggingInfo>)sender
1529 [mDraggingDestinationHandler concludeDragOperation: sender];
1532 -(void)registerDraggingDestinationHandler:(id)theHandler
1534 mDraggingDestinationHandler = theHandler;
1537 -(void)unregisterDraggingDestinationHandler:(id)theHandler
1539 mDraggingDestinationHandler = nil;