summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSilenio Quarti <silenio>2008-07-10 22:04:50 +0000
committerSilenio Quarti <silenio>2008-07-10 22:04:50 +0000
commite771e3576d1e1ba57ba12fa501dc8174c6ca74e8 (patch)
tree2f7ad5b5efd2d5b121c654c8d5130bf507d25c7a
parentfe01df1082b5613213a59b03292c02660626087d (diff)
downloadeclipse.platform.swt-e771e3576d1e1ba57ba12fa501dc8174c6ca74e8.tar.gz
eclipse.platform.swt-e771e3576d1e1ba57ba12fa501dc8174c6ca74e8.tar.xz
eclipse.platform.swt-e771e3576d1e1ba57ba12fa501dc8174c6ca74e8.zip
key events and IME
-rwxr-xr-xbundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.cocoa.OS.properties36
-rwxr-xr-xbundles/org.eclipse.swt/.classpath_cocoa1
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java6
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Canvas.java55
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java9
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java117
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java123
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/IME.java498
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java32
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java123
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ToolItem.java4
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java103
12 files changed, 925 insertions, 182 deletions
diff --git a/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.cocoa.OS.properties b/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.cocoa.OS.properties
index 6207acd300..8122fd68e9 100755
--- a/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.cocoa.OS.properties
+++ b/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.cocoa.OS.properties
@@ -782,6 +782,8 @@ OS_NSBaselineOffsetAttributeName=flags=const
OS_NSBitsPerPixelFromDepth=
OS_NSBitsPerPixelFromDepth_0=
+OS_NSCalibratedRGBColorSpace=flags=const
+
OS_NSDefaultRunLoopMode=flags=const
OS_NSDeviceRGBColorSpace=flags=const
@@ -878,6 +880,12 @@ OS_UnionRgn_0=
OS_UnionRgn_1=
OS_UnionRgn_2=
+OS_attributedSubstringFromRange_CALLBACK=flags=no_gen
+OS_attributedSubstringFromRange_CALLBACK_0=
+
+OS_characterIndexForPoint_CALLBACK=flags=no_gen
+OS_characterIndexForPoint_CALLBACK_0=
+
OS_class_addIvar=
OS_class_addIvar_0=cast=(Class)
OS_class_addIvar_1=cast=(const char *)
@@ -891,12 +899,27 @@ OS_class_addMethod_1=cast=(SEL)
OS_class_addMethod_2=cast=(IMP)
OS_class_addMethod_3=cast=(const char *)
+OS_class_addProtocol=
+OS_class_addProtocol_0=cast=Class
+OS_class_addProtocol_1=cast=Protocol *
+
OS_drawRect_CALLBACK=flags=no_gen
OS_drawRect_CALLBACK_0=
+OS_firstRectForCharacterRange_CALLBACK=flags=no_gen
+OS_firstRectForCharacterRange_CALLBACK_0=
+
OS_hitTest_CALLBACK=flags=no_gen
OS_hitTest_CALLBACK_0=
+OS_markedRange_CALLBACK=flags=no_gen
+OS_markedRange_CALLBACK_0=
+
+OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRange_2I=
+OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRange_2I_0=cast=(void *)
+OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRange_2I_1=cast=(void *)
+OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRange_2I_2=
+
OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRect_2I=
OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRect_2I_0=cast=(void *)
OS_memmove__ILorg_eclipse_swt_internal_cocoa_NSRect_2I_1=cast=(void *)
@@ -930,6 +953,9 @@ OS_objc_allocateClassPair_2=cast=(size_t)
OS_objc_getClass=
OS_objc_getClass_0=cast=(const char *)
+OS_objc_getProtocol=
+OS_objc_getProtocol_0=
+
OS_objc_lookUpClass=
OS_objc_lookUpClass_0=cast=(const char *)
@@ -2875,6 +2901,10 @@ OS_object_getInstanceVariable_0=cast=(id)
OS_object_getInstanceVariable_1=cast=(const char *)
OS_object_getInstanceVariable_2=cast=(void **)
+OS_object_setClass=
+OS_object_setClass_0=cast=(id)
+OS_object_setClass_1=cast=(Class)
+
OS_object_setInstanceVariable=
OS_object_setInstanceVariable_0=cast=(id)
OS_object_setInstanceVariable_1=cast=(const char *)
@@ -2883,6 +2913,9 @@ OS_object_setInstanceVariable_2=cast=(void *)
OS_sel_registerName=
OS_sel_registerName_0=cast=(const char *)
+OS_selectedRange_CALLBACK=flags=no_gen
+OS_selectedRange_CALLBACK_0=
+
OS_setFrameOrigin_CALLBACK=flags=no_gen
OS_setFrameOrigin_CALLBACK_0=
@@ -2892,6 +2925,9 @@ OS_setFrameSize_CALLBACK_0=
OS_setFrame_CALLBACK=flags=no_gen
OS_setFrame_CALLBACK_0=
+OS_setMarkedText_selectedRange_CALLBACK=flags=no_gen
+OS_setMarkedText_selectedRange_CALLBACK_0=
+
OS_webView_setFrame_CALLBACK=flags=no_gen
OS_webView_setFrame_CALLBACK_0=
diff --git a/bundles/org.eclipse.swt/.classpath_cocoa b/bundles/org.eclipse.swt/.classpath_cocoa
index fcd363fe7a..1dbf5d95e7 100755
--- a/bundles/org.eclipse.swt/.classpath_cocoa
+++ b/bundles/org.eclipse.swt/.classpath_cocoa
@@ -7,7 +7,6 @@
<classpathentry kind="src" path="Eclipse SWT/emulated/bidi"/>
<classpathentry kind="src" path="Eclipse SWT/emulated/coolbar"/>
<classpathentry kind="src" path="Eclipse SWT/emulated/expand"/>
- <classpathentry kind="src" path="Eclipse SWT/emulated/ime"/>
<classpathentry kind="src" path="Eclipse SWT/emulated/tooltip"/>
<classpathentry kind="src" path="Eclipse SWT PI/common"/>
<classpathentry kind="src" path="Eclipse SWT PI/cocoa">
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java
index 9e3a1acf39..668b74bb6d 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java
@@ -50,6 +50,8 @@ public final class TextLayout extends Resource {
int[] lineOffsets;
NSRect[] lineBounds;
+
+ static final int UNDERLINE_THICK = 1 << 16;
static class StyleItem {
TextStyle style;
@@ -169,7 +171,6 @@ void computeRuns() {
}
}
if (style.underline) {
- //TODO - IME - thick
int underlineStyle = 0;
switch (style.underlineStyle) {
case SWT.UNDERLINE_SINGLE:
@@ -178,6 +179,9 @@ void computeRuns() {
case SWT.UNDERLINE_DOUBLE:
underlineStyle = OS.NSUnderlineStyleDouble;
break;
+ case UNDERLINE_THICK:
+ underlineStyle = OS.NSUnderlineStyleThick;
+ break;
}
if (underlineStyle != 0) {
textStorage.addAttribute(OS.NSUnderlineStyleAttributeName(), NSNumber.numberWithInt(underlineStyle), range);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Canvas.java
index ac6348e913..f474047fab 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Canvas.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Canvas.java
@@ -45,6 +45,11 @@ Canvas () {
/* Do nothing */
}
+int attributedSubstringFromRange (int id, int sel, int range) {
+ if (ime != null) return ime.attributedSubstringFromRange (id, sel, range);
+ return super.attributedSubstringFromRange(id, sel, range);
+}
+
boolean becomeFirstResponder (int id, int sel) {
if (caret != null) caret.setFocus ();
return super.becomeFirstResponder(id, sel);
@@ -87,6 +92,11 @@ public Canvas (Composite parent, int style) {
super (parent, style);
}
+int characterIndexForPoint (int id, int sel, int point) {
+ if (ime != null) return ime.characterIndexForPoint (id, sel, point);
+ return super.characterIndexForPoint (id, sel, point);
+}
+
/**
* Fills the interior of the rectangle specified by the arguments,
* with the receiver's background.
@@ -158,6 +168,11 @@ void drawRect(int id, NSRect rect) {
}
}
+NSRect firstRectForCharacterRange (int id, int sel, int range) {
+ if (ime != null) return ime.firstRectForCharacterRange (id, sel, range);
+ return super.firstRectForCharacterRange (id, sel, range);
+}
+
/**
* Returns the caret.
* <p>
@@ -198,6 +213,23 @@ public IME getIME () {
return ime;
}
+boolean hasMarkedText (int id, int sel) {
+ if (ime != null) return ime.hasMarkedText (id, sel);
+ return super.hasMarkedText (id, sel);
+}
+
+boolean insertText (int id, int sel, int string) {
+ if (ime != null) {
+ if (!ime.insertText (id, sel, string)) return false;
+ }
+ return super.insertText (id, sel, string);
+}
+
+NSRange markedRange (int id, int sel) {
+ if (ime != null) return ime.markedRange (id, sel);
+ return super.markedRange (id, sel);
+}
+
//void redrawWidget (int control, boolean children) {
// boolean isFocus = OS.VERSION < 0x1040 && caret != null && caret.isFocusCaret ();
// if (isFocus) caret.killFocus ();
@@ -291,9 +323,14 @@ public void scroll (int destX, int destY, int x, int y, int width, int height, b
if (isFocus) caret.setFocus ();
}
-boolean sendKeyEvent(NSEvent nsEvent, int type) {
- if (caret != null) NSCursor.setHiddenUntilMouseMoves(true);
- return super.sendKeyEvent(nsEvent, type);
+NSRange selectedRange (int id, int sel) {
+ if (ime != null) return ime.selectedRange (id, sel);
+ return super.selectedRange (id, sel);
+}
+
+boolean sendKeyEvent (NSEvent nsEvent, int type) {
+ if (caret != null) NSCursor.setHiddenUntilMouseMoves (true);
+ return super.sendKeyEvent (nsEvent, type);
}
/**
@@ -357,4 +394,16 @@ public void setIME (IME ime) {
this.ime = ime;
}
+boolean setMarkedText_selectedRange (int id, int sel, int string, int range) {
+ if (ime != null) {
+ if (!ime.setMarkedText_selectedRange (id, sel, string, range)) return false;
+ }
+ return super.setMarkedText_selectedRange (id, sel, string, range);
+}
+
+int validAttributesForMarkedText (int id, int sel) {
+ if (ime != null) return ime.validAttributesForMarkedText (id, sel);
+ return super.validAttributesForMarkedText(id, sel);
+}
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java
index bd2a060876..dada57388a 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Composite.java
@@ -475,12 +475,13 @@ boolean isTabGroup () {
return super.isTabGroup ();
}
-void keyDown(int id, int sel, int theEvent) {
- /* needed to avoid bells */
- if (hasFocus () && (state & CANVAS) != 0) {
+void keyDown (int id, int sel, int theEvent) {
+ if ((state & CANVAS) != 0) {
+ NSArray array = NSArray.arrayWithObject (new NSEvent (theEvent));
+ view.interpretKeyEvents (array);
return;
}
- super.keyDown(id, sel, theEvent);
+ super.keyDown (id, sel, theEvent);
}
/**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
index 59ac92648e..748a4b02f8 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Control.java
@@ -644,6 +644,21 @@ void destroyWidget () {
releaseHandle ();
}
+boolean doCommandBySelector (int id, int sel, int selector) {
+ NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent ();
+ if (nsEvent != null && nsEvent.type () == OS.NSKeyDown) {
+ boolean [] consume = new boolean [1];
+ if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return false;
+ if (isDisposed ()) return false;
+ if (!sendKeyEvent (nsEvent, SWT.KeyDown)) return false;
+ if (consume [0]) return false;
+ }
+ if ((state & CANVAS) == 0) {
+ return super.doCommandBySelector (id, sel, selector);
+ }
+ return true;
+}
+
/**
* Detects a drag and drop gesture. This method is used
* to detect a drag gesture when called from within a mouse
@@ -839,6 +854,39 @@ void fixFocus (Control focusControl) {
// OS.ClearKeyboardFocus (window);
}
+void flagsChanged (int id, int sel, int theEvent) {
+ if (view.window ().firstResponder ().id == id) {
+ if ((state & SAFARI_EVENTS_FIX) == 0) {
+ int mask = 0;
+ NSEvent nsEvent = new NSEvent (theEvent);
+ int modifiers = nsEvent.modifierFlags ();
+ int keyCode = Display.translateKey (nsEvent.keyCode ());
+ switch (keyCode) {
+ case SWT.ALT: mask = OS.NSAlternateKeyMask; break;
+ case SWT.CONTROL: mask = OS.NSControlKeyMask; break;
+ case SWT.COMMAND: mask = OS.NSCommandKeyMask; break;
+ case SWT.SHIFT: mask = OS.NSShiftKeyMask; break;
+ case SWT.CAPS_LOCK:
+ Event event = new Event();
+ event.keyCode = keyCode;
+ setInputState (event, nsEvent, SWT.KeyDown);
+ sendKeyEvent (SWT.KeyDown, event);
+ setInputState (event, nsEvent, SWT.KeyUp);
+ sendKeyEvent (SWT.KeyUp, event);
+ break;
+ }
+ if (mask != 0) {
+ int type = (mask & modifiers) != 0 ? SWT.KeyDown : SWT.KeyUp;
+ Event event = new Event();
+ event.keyCode = keyCode;
+ setInputState (event, nsEvent, type);
+ if (!sendKeyEvent (type, event)) return;
+ }
+ }
+ }
+ super.flagsChanged (id, sel, theEvent);
+}
+
NSView focusView () {
return view;
}
@@ -1300,6 +1348,29 @@ int hitTest (int id, int sel, NSPoint point) {
return super.hitTest(id, sel, point);
}
+boolean insertText (int id, int sel, int string) {
+ NSEvent nsEvent = NSApplication.sharedApplication ().currentEvent ();
+ if (nsEvent != null && nsEvent.type () == OS.NSKeyDown) {
+ NSString str = new NSString (string);
+ if (str.isKindOfClass (OS.objc_getClass ("NSAttributedString"))) {
+ str = new NSAttributedString (string).string ();
+ }
+ int length = str.length ();
+ char[] buffer = new char [length];
+ str.getCharacters_ (buffer);
+ for (int i = 0; i < buffer.length; i++) {
+ Event event = new Event ();
+ if (length == 1) setKeyState (event, SWT.KeyDown, nsEvent);
+ event.character = buffer [i];
+ sendKeyEvent (SWT.KeyDown, event);
+ }
+ }
+ if ((state & CANVAS) == 0) {
+ return super.insertText (id, sel, string);
+ }
+ return true;
+}
+
/**
* Invokes platform specific functionality to allocate a new GC handle.
* <p>
@@ -1493,7 +1564,34 @@ public boolean isVisible () {
return getVisible () && parent.isVisible ();
}
-int menuForEvent (int nsEvent) {
+void keyDown (int id, int sel, int theEvent) {
+ if (view.window ().firstResponder ().id == id) {
+ boolean textInput = OS.objc_msgSend (id, OS.sel_conformsToProtocol_1, OS.objc_getProtocol ("NSTextInput")) != 0;
+ if (!textInput) {
+ NSEvent nsEvent = new NSEvent (theEvent);
+ boolean [] consume = new boolean [1];
+ if (translateTraversal (nsEvent.keyCode (), nsEvent, consume)) return;
+ if (isDisposed ()) return;
+ if (!sendKeyEvent (nsEvent, SWT.KeyDown)) return;
+ if (consume [0]) return;
+ }
+ }
+ super.keyDown (id, sel, theEvent);
+}
+
+void keyUp (int id, int sel, int theEvent) {
+ if (view.window ().firstResponder ().id == id) {
+ NSEvent nsEvent = new NSEvent (theEvent);
+ if (!sendKeyEvent (nsEvent, SWT.KeyUp)) return;
+ }
+ super.keyUp (id, sel, theEvent);
+}
+
+void markLayout (boolean changed, boolean all) {
+ /* Do nothing */
+}
+
+int menuForEvent (int id, int sel, int theEvent) {
NSPoint pt = NSEvent.mouseLocation();
pt.y = (int) (display.getPrimaryFrame().height - pt.y);
int x = (int) pt.x;
@@ -1510,10 +1608,7 @@ int menuForEvent (int nsEvent) {
}
return menu.nsMenu.id;
}
- objc_super super_struct = new objc_super();
- super_struct.receiver = view.id;
- super_struct.cls = OS.objc_msgSend(view.id, OS.sel_superclass);
- return OS.objc_msgSendSuper(super_struct, OS.sel_menuForEvent_1, nsEvent);
+ return super.menuForEvent (id, sel, theEvent);
}
Decorations menuShell () {
@@ -1545,10 +1640,6 @@ void moved () {
sendEvent (SWT.Move);
}
-void markLayout (boolean changed, boolean all) {
- /* Do nothing */
-}
-
/**
* Moves the receiver above the specified control in the
* drawing order. If the argument is null, then the receiver
@@ -2146,6 +2237,12 @@ void sendFocusEvent (int type, boolean post) {
}
boolean sendMouseEvent (NSEvent nsEvent, int type, boolean send) {
+ NSInputManager manager = NSInputManager.currentInputManager ();
+ if (manager != null && manager.wantsToHandleMouseEvents ()) {
+ if (manager.handleMouseEvent (nsEvent)) {
+ return true;
+ }
+ }
Shell shell = null;
Event event = new Event ();
switch (type) {
@@ -3075,7 +3172,7 @@ boolean translateTraversal (int key, NSEvent theEvent, boolean [] consume) {
}
int traversalCode (int key, NSEvent theEvent) {
- int code = SWT.TRAVERSE_RETURN | SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS;
+ int code = SWT.TRAVERSE_RETURN | SWT.TRAVERSE_TAB_NEXT | SWT.TRAVERSE_TAB_PREVIOUS | SWT.TRAVERSE_PAGE_NEXT | SWT.TRAVERSE_PAGE_PREVIOUS;
Shell shell = getShell ();
if (shell.parent != null) code |= SWT.TRAVERSE_ESCAPE;
return code;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
index 4b65630249..b4dca00c9f 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
@@ -112,6 +112,8 @@ public class Display extends Device {
boolean dragging;
Control currentControl, grabControl, trackingControl;
+ NSDictionary markedAttributes;
+
Menu menuBar;
Menu[] menus;
@@ -1607,6 +1609,12 @@ protected void init () {
initApplicationDelegate();
application.finishLaunching();
timerDelegate = (SWTWindowDelegate)new SWTWindowDelegate().alloc().init();
+
+ NSTextView textView = (NSTextView)new NSTextView().alloc();
+ textView.initWithFrame (new NSRect ());
+ markedAttributes = textView.markedTextAttributes ();
+ markedAttributes.retain ();
+ textView.release ();
}
void initApplicationDelegate() {
@@ -1647,6 +1655,7 @@ void addEventMethods (int cls, int proc2, int proc3) {
OS.class_addMethod(cls, OS.sel_becomeFirstResponder, proc2, "@:");
OS.class_addMethod(cls, OS.sel_keyDown_1, proc3, "@:@");
OS.class_addMethod(cls, OS.sel_keyUp_1, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_flagsChanged_1, proc3, "@:@");
}
void addFrameMethods(int cls, int setFrameOriginProc, int setFrameSizeProc) {
@@ -1679,7 +1688,13 @@ void initClasses () {
int setFrameOriginProc = OS.setFrame_CALLBACK(proc3);
int setFrameSizeProc = OS.setFrame_CALLBACK(proc3);
int hitTestProc = OS.hitTest_CALLBACK(proc3);
-
+ int markedRangeProc = OS.markedRange_CALLBACK(proc2);
+ int selectedRangeProc = OS.selectedRange_CALLBACK(proc2);
+ int setMarkedText_selectedRangeProc = OS.setMarkedText_selectedRange_CALLBACK(proc4);
+ int attributedSubstringFromRangeProc = OS.attributedSubstringFromRange_CALLBACK(proc3);
+ int characterIndexForPointProc = OS.characterIndexForPoint_CALLBACK(proc3);
+ int firstRectForCharacterRangeProc = OS.firstRectForCharacterRange_CALLBACK(proc3);
+
String className = "SWTWindowDelegate";
int cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
OS.class_addIvar(cls, SWT_OBJECT, OS.PTR_SIZEOF, (byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
@@ -1711,12 +1726,27 @@ void initClasses () {
className = "SWTView";
cls = OS.objc_allocateClassPair(OS.class_NSView, className, 0);
+ OS.class_addProtocol(cls, OS.objc_getProtocol("NSTextInput"));
OS.class_addIvar(cls, SWT_OBJECT, OS.PTR_SIZEOF, (byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
OS.class_addMethod(cls, OS.sel_isFlipped, proc2, "@:");
OS.class_addMethod(cls, OS.sel_drawRect_1, drawRectProc, "@:i");
OS.class_addMethod(cls, OS.sel_acceptsFirstResponder, proc2, "@:");
OS.class_addMethod(cls, OS.sel_isOpaque, proc2, "@:");
OS.class_addMethod(cls, OS.sel_hitTest_1, hitTestProc, "@:{NSPoint}");
+
+ //NSTextInput protocol
+ OS.class_addMethod(cls, OS.sel_hasMarkedText, proc2, "@:");
+ OS.class_addMethod(cls, OS.sel_markedRange, markedRangeProc, "@:");
+ OS.class_addMethod(cls, OS.sel_selectedRange, selectedRangeProc, "@:");
+ OS.class_addMethod(cls, OS.sel_setMarkedText_1selectedRange_1, setMarkedText_selectedRangeProc, "@:@{NSRange}");
+ OS.class_addMethod(cls, OS.sel_unmarkText, proc2, "@:");
+ OS.class_addMethod(cls, OS.sel_validAttributesForMarkedText, proc2, "@:");
+ OS.class_addMethod(cls, OS.sel_attributedSubstringFromRange_1, attributedSubstringFromRangeProc, "@:{NSRange}");
+ OS.class_addMethod(cls, OS.sel_insertText_1, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_characterIndexForPoint_1, characterIndexForPointProc, "@:{NSPoint}");
+ OS.class_addMethod(cls, OS.sel_firstRectForCharacterRange_1, firstRectForCharacterRangeProc, "@:{NSRange}");
+ OS.class_addMethod(cls, OS.sel_doCommandBySelector_1, proc3, "@::");
+
addEventMethods(cls, proc2, proc3);
addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
OS.objc_registerClassPair(cls);
@@ -1867,6 +1897,17 @@ void initClasses () {
OS.class_addIvar(cls, SWT_OBJECT, OS.PTR_SIZEOF, (byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
addEventMethods(cls, proc2, proc3);
addFrameMethods(cls, setFrameOriginProc, setFrameSizeProc);
+ OS.class_addMethod(cls, OS.sel_insertText_1, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_doCommandBySelector_1, proc3, "@::");
+ OS.objc_registerClassPair(cls);
+
+ className = "SWTEditorView";
+ cls = OS.objc_allocateClassPair(OS.class_NSTextView, className, 0);
+ OS.class_addIvar(cls, SWT_OBJECT, OS.PTR_SIZEOF, (byte)(Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i");
+ OS.class_addMethod(cls, OS.sel_keyDown_1, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_keyUp_1, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_insertText_1, proc3, "@:@");
+ OS.class_addMethod(cls, OS.sel_doCommandBySelector_1, proc3, "@::");
OS.objc_registerClassPair(cls);
className = "SWTTextField";
@@ -2541,6 +2582,9 @@ void releaseDisplay () {
menuBar = null;
menus = null;
+
+ if (markedAttributes != null) markedAttributes.release();
+ markedAttributes = null;
/* The release pool needs to be released before the call backs. */
if (pool != null) pool.release();
@@ -3416,38 +3460,42 @@ int windowDelegateProc(int id, int sel) {
if (widget == null) return 0;
if (sel == OS.sel_isFlipped) {
return widget.isFlipped() ? 1 : 0;
- }
- if (sel == OS.sel_sendSelection) {
+ } else if (sel == OS.sel_sendSelection) {
widget.sendSelection();
- return 0;
- }
- if (sel == OS.sel_sendArrowSelection) {
+ } else if (sel == OS.sel_sendArrowSelection) {
widget.sendArrowSelection();
- return 0;
- }
- if (sel == OS.sel_sendDoubleSelection) {
+ } else if (sel == OS.sel_sendDoubleSelection) {
widget.sendDoubleSelection();
- return 0;
- }
- if (sel == OS.sel_sendVerticalSelection) {
+ } else if (sel == OS.sel_sendVerticalSelection) {
widget.sendVerticalSelection();
- return 0;
- }
- if (sel == OS.sel_sendHorizontalSelection) {
+ } else if (sel == OS.sel_sendHorizontalSelection) {
widget.sendHorizontalSelection();
- return 0;
- }
- if (sel == OS.sel_acceptsFirstResponder) {
+ } else if (sel == OS.sel_acceptsFirstResponder) {
return widget.acceptsFirstResponder(id, sel) ? 1 : 0;
- }
- if (sel == OS.sel_becomeFirstResponder) {
+ } else if (sel == OS.sel_becomeFirstResponder) {
return widget.becomeFirstResponder(id, sel) ? 1 : 0;
- }
- if (sel == OS.sel_resignFirstResponder) {
+ } else if (sel == OS.sel_resignFirstResponder) {
return widget.resignFirstResponder(id, sel) ? 1 : 0;
- }
- if (sel == OS.sel_isOpaque) {
+ } else if (sel == OS.sel_isOpaque) {
return widget.isOpaque(id, sel) ? 1 : 0;
+ } else if (sel == OS.sel_unmarkText) {
+ //TODO not called?
+ } else if (sel == OS.sel_validAttributesForMarkedText) {
+ return widget.validAttributesForMarkedText (id, sel);
+ } else if (sel == OS.sel_markedRange) {
+ NSRange range = widget.markedRange (id, sel);
+ /* NOTE that this is freed in C */
+ int /*long*/ result = OS.malloc (NSRange.sizeof);
+ OS.memmove (result, range, NSRange.sizeof);
+ return result;
+ } else if (sel == OS.sel_selectedRange) {
+ NSRange range = widget.selectedRange (id, sel);
+ /* NOTE that this is freed in C */
+ int /*long*/ result = OS.malloc (NSRange.sizeof);
+ OS.memmove (result, range, NSRange.sizeof);
+ return result;
+ } else if (sel == OS.sel_hasMarkedText) {
+ return widget.hasMarkedText (id, sel) ? 1 : 0;
}
return 0;
}
@@ -3457,6 +3505,9 @@ int windowDelegateProc(int id, int sel, int arg0) {
return timerProc (arg0);
}
Widget widget = getWidget(id);
+ if (widget == null && (sel == OS.sel_keyDown_1 ||sel == OS.sel_keyUp_1 ||sel == OS.sel_insertText_1 ||sel == OS.sel_doCommandBySelector_1)) {
+ widget = getFocusControl (new NSView (id).window ());
+ }
if (widget == null) return 0;
if (sel == OS.sel_windowWillClose_1) {
widget.windowWillClose(arg0);
@@ -3493,6 +3544,8 @@ int windowDelegateProc(int id, int sel, int arg0) {
widget.keyDown(id, sel, arg0);
} else if (sel == OS.sel_keyUp_1) {
widget.keyUp(id, sel, arg0);
+ } else if (sel == OS.sel_flagsChanged_1) {
+ widget.flagsChanged(id, sel, arg0);
} else if (sel == OS.sel_mouseUp_1) {
widget.mouseUp(id, sel, arg0);
} else if (sel == OS.sel_rightMouseDown_1) {
@@ -3512,7 +3565,7 @@ int windowDelegateProc(int id, int sel, int arg0) {
} else if (sel == OS.sel_mouseExited_1) {
widget.mouseExited(id, sel, arg0);
} else if (sel == OS.sel_menuForEvent_1) {
- return widget.menuForEvent(id);
+ return widget.menuForEvent(id, sel, arg0);
} else if (sel == OS.sel_numberOfRowsInTableView_1) {
return widget.numberOfRowsInTableView(arg0);
} else if (sel == OS.sel_comboBoxSelectionDidChange_1) {
@@ -3545,6 +3598,20 @@ int windowDelegateProc(int id, int sel, int arg0) {
widget.pageDown(id, sel, arg0);
} else if (sel == OS.sel_pageUp_1) {
widget.pageUp(id, sel, arg0);
+ } else if (sel == OS.sel_attributedSubstringFromRange_1) {
+ return widget.attributedSubstringFromRange (id, sel, arg0);
+ } else if (sel == OS.sel_characterIndexForPoint_1) {
+ return widget.characterIndexForPoint (id, sel, arg0);
+ } else if (sel == OS.sel_firstRectForCharacterRange_1) {
+ NSRect rect = widget.firstRectForCharacterRange (id, sel, arg0);
+ /* NOTE that this is freed in C */
+ int /*long*/ result = OS.malloc (NSRect.sizeof);
+ OS.memmove (result, rect, NSRect.sizeof);
+ return result;
+ } else if (sel == OS.sel_insertText_1) {
+ widget.insertText (id, sel, arg0);
+ } else if (sel == OS.sel_doCommandBySelector_1) {
+ widget.doCommandBySelector (id, sel, arg0);
}
return 0;
}
@@ -3564,6 +3631,9 @@ int windowDelegateProc(int delegate, int sel, int arg0, int arg1) {
return widget.outlineView_shouldExpandItem(arg0, arg1) ? 1 : 0;
} else if (sel == OS.sel_menu_1willHighlightItem_1) {
widget.menu_willHighlightItem(arg0, arg1);
+ } else if (sel == OS.sel_setMarkedText_1selectedRange_1) {
+ widget.setMarkedText_selectedRange (delegate, sel, arg0, arg1);
+ return 0;
}
return 0;
}
@@ -3573,8 +3643,7 @@ int windowDelegateProc(int delegate, int sel, int arg0, int arg1, int arg2) {
if (widget == null) return 0;
if (sel == OS.sel_tableView_1objectValueForTableColumn_1row_1) {
return widget.tableView_objectValueForTableColumn_row(arg0, arg1, arg2);
- }
- if (sel == OS.sel_tableView_1shouldEditTableColumn_1row_1) {
+ } else if (sel == OS.sel_tableView_1shouldEditTableColumn_1row_1) {
return widget.tableView_shouldEditTableColumn_row(arg0, arg1, arg2) ? 1 : 0;
} else if (sel == OS.sel_textView_1clickedOnLink_1atIndex_1) {
return widget.clickOnLink(arg0, arg1, arg2) ? 1 : 0;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/IME.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/IME.java
new file mode 100644
index 0000000000..6218a0e100
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/IME.java
@@ -0,0 +1,498 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.cocoa.*;
+
+/**
+ * Instances of this class represent input method editors.
+ * These are typically in-line pre-edit text areas that allow
+ * the user to compose characters from Far Eastern languages
+ * such as Japanese, Chinese or Korean.
+ *
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>ImeComposition</dd>
+ * </dl>
+ * <p>
+ * IMPORTANT: This class is <em>not</em> intended to be subclassed.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ *
+ * @since 3.4
+ */
+public class IME extends Widget {
+ Canvas parent;
+ int caretOffset;
+ int startOffset;
+ int commitCount;
+ String text;
+ int [] ranges;
+ TextStyle [] styles;
+
+ static final int UNDERLINE_THICK = 1 << 16;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+IME () {
+}
+
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>SWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>SWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a canvas control which will be the parent of the new instance (cannot be null)
+ * @param style the style of control to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
+ * </ul>
+ *
+ * @see Widget#checkSubclass
+ * @see Widget#getStyle
+ */
+public IME (Canvas parent, int style) {
+ super (parent, style);
+ this.parent = parent;
+ createWidget ();
+}
+
+int attributedSubstringFromRange (int id, int sel, int rangePtr) {
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_SELECTION;
+ sendEvent (SWT.ImeComposition, event);
+ NSRange range = new NSRange ();
+ OS.memmove (range, rangePtr, NSRange.sizeof);
+ int start = range.location;
+ int end = range.location + range.length;
+ if (event.start <= start && start <= event.end && event.start <= end && end <= event.end) {
+ NSString str = NSString.stringWith (event.text.substring(start - event.start, end - event.start));
+ NSAttributedString attriStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString_attributes_(str, null);
+ attriStr.autorelease ();
+ return attriStr.id;
+ }
+ return 0;
+}
+
+int characterIndexForPoint (int id, int sel, int point) {
+ if (!isInlineEnabled ()) return OS.NSNotFound;
+ NSPoint pt = new NSPoint ();
+ OS.memmove (pt, point, NSPoint.sizeof);
+ NSView view = parent.view;
+ pt = view.window ().convertScreenToBase (pt);
+ pt = view.convertPoint_fromView_ (pt, null);
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_OFFSET;
+ event.x = (int) pt.x;
+ event.y = (int) pt.y;
+ sendEvent (SWT.ImeComposition, event);
+ int offset = event.index + event.count;
+ return offset != -1 ? offset : OS.NSNotFound;
+}
+
+void createWidget () {
+ text = "";
+ startOffset = -1;
+ if (parent.getIME () == null) {
+ parent.setIME (this);
+ }
+}
+
+NSRect firstRectForCharacterRange(int id, int sel, int range) {
+ NSRect rect = new NSRect ();
+ Caret caret = parent.caret;
+ if (caret != null) {
+ NSView view = parent.view;
+ NSPoint pt = new NSPoint ();
+ pt.x = caret.x;
+ pt.y = caret.y + caret.height;
+ pt = view.convertPoint_toView_ (pt, null);
+ pt = view.window ().convertBaseToScreen (pt);
+ rect.x = pt.x;
+ rect.y = pt.y;
+ rect.width = caret.width;
+ rect.height = caret.height;
+ }
+ return rect;
+}
+
+/**
+ * Returns the offset of the caret from the start of the document.
+ * The caret is within the current composition.
+ *
+ * @return the caret offset
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getCaretOffset () {
+ checkWidget ();
+ return startOffset + caretOffset;
+}
+
+/**
+ * Returns the commit count of the composition. This is the
+ * number of characters that have been composed. When the
+ * commit count is equal to the length of the composition
+ * text, then the in-line edit operation is complete.
+ *
+ * @return the commit count
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see IME#getText
+ */
+public int getCommitCount () {
+ checkWidget ();
+ return commitCount;
+}
+
+/**
+ * Returns the offset of the composition from the start of the document.
+ * This is the start offset of the composition within the document and
+ * in not changed by the input method editor itself during the in-line edit
+ * session.
+ *
+ * @return the offset of the composition
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public int getCompositionOffset () {
+ checkWidget ();
+ return startOffset;
+}
+
+/**
+ * Returns the ranges for the style that should be applied during the
+ * in-line edit session.
+ * <p>
+ * The ranges array contains start and end pairs. Each pair refers to
+ * the corresponding style in the styles array. For example, the pair
+ * that starts at ranges[n] and ends at ranges[n+1] uses the style
+ * at styles[n/2] returned by <code>getStyles()</code>.
+ * </p>
+ * @return the ranges for the styles
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see IME#getStyles
+ */
+public int [] getRanges () {
+ checkWidget ();
+ if (ranges == null) return new int [0];
+ int [] result = new int [ranges.length];
+ for (int i = 0; i < result.length; i++) {
+ result [i] = ranges [i] + startOffset;
+ }
+ return result;
+}
+
+/**
+ * Returns the styles for the ranges.
+ * <p>
+ * The ranges array contains start and end pairs. Each pair refers to
+ * the corresponding style in the styles array. For example, the pair
+ * that starts at ranges[n] and ends at ranges[n+1] uses the style
+ * at styles[n/2].
+ * </p>
+ *
+ * @return the ranges for the styles
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @see IME#getRanges
+ */
+public TextStyle [] getStyles () {
+ checkWidget ();
+ if (styles == null) return new TextStyle [0];
+ TextStyle [] result = new TextStyle [styles.length];
+ System.arraycopy (styles, 0, result, 0, styles.length);
+ return result;
+}
+
+TextStyle getStyle (NSDictionary attribs) {
+ NSArray keys = attribs.allKeys ();
+ int count = keys.count ();
+ TextStyle style = new TextStyle ();
+ for (int j = 0; j < count; j++) {
+ NSString key = new NSString (keys.objectAtIndex (j));
+ if (key.isEqualTo (new NSString (OS.NSBackgroundColorAttributeName ()))) {
+ NSColor color = new NSColor (attribs.objectForKey (key).id).colorUsingColorSpaceName_ (OS.NSCalibratedRGBColorSpace);
+ float [] rgbColor = new float []{color.redComponent(), color.greenComponent(), color.blueComponent(), color.alphaComponent()};
+ style.background = Color.cocoa_new (display, rgbColor);
+ } else if (key.isEqualTo (new NSString (OS.NSForegroundColorAttributeName ()))) {
+ NSColor color = new NSColor (attribs.objectForKey (key).id).colorUsingColorSpaceName_ (OS.NSCalibratedRGBColorSpace);
+ float [] rgbColor = new float []{color.redComponent(), color.greenComponent(), color.blueComponent(), color.alphaComponent()};
+ style.foreground = Color.cocoa_new (display, rgbColor);
+ } else if (key.isEqualTo (new NSString (OS.NSUnderlineColorAttributeName ()))) {
+ NSColor color = new NSColor (attribs.objectForKey (key).id).colorUsingColorSpaceName_ (OS.NSCalibratedRGBColorSpace);
+ float [] rgbColor = new float []{color.redComponent(), color.greenComponent(), color.blueComponent(), color.alphaComponent()};
+ style.underlineColor = Color.cocoa_new (display, rgbColor);
+ } else if (key.isEqualTo (new NSString (OS.NSUnderlineStyleAttributeName ()))) {
+ NSNumber value = new NSNumber (attribs.objectForKey (key).id);
+ switch (value.intValue ()) {
+ case OS.NSUnderlineStyleSingle: style.underlineStyle = SWT.UNDERLINE_SINGLE; break;
+ case OS.NSUnderlineStyleDouble: style.underlineStyle = SWT.UNDERLINE_DOUBLE; break;
+ case OS.NSUnderlineStyleThick: style.underlineStyle = UNDERLINE_THICK; break;
+ }
+ style.underline = value.intValue () != OS.NSUnderlineStyleNone;
+ } else if (key.isEqualTo (new NSString (OS.NSStrikethroughColorAttributeName ()))) {
+ NSColor color = new NSColor (attribs.objectForKey (key).id).colorUsingColorSpaceName_ (OS.NSCalibratedRGBColorSpace);
+ float [] rgbColor = new float []{color.redComponent(), color.greenComponent(), color.blueComponent(), color.alphaComponent()};
+ style.strikeoutColor = Color.cocoa_new (display, rgbColor);
+ } else if (key.isEqualTo (new NSString (OS.NSStrikethroughStyleAttributeName ()))) {
+ NSNumber value = new NSNumber (attribs.objectForKey (key).id);
+ style.strikeout = value.intValue () != OS.NSUnderlineStyleNone;
+ } else if (key.isEqualTo (new NSString (OS.NSFontAttributeName ()))) {
+ NSFont font = new NSFont (attribs.objectForKey (key).id);
+ style.font = Font.cocoa_new (display, font);
+ }
+ }
+ return style;
+}
+
+/**
+ * Returns the composition text.
+ * <p>
+ * The text for an IME is the characters in the widget that
+ * are in the current composition. When the commit count is
+ * equal to the length of the composition text, then the
+ * in-line edit operation is complete.
+ * </p>
+ *
+ * @return the widget text
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public String getText () {
+ checkWidget ();
+ return text;
+}
+
+/**
+ * Returns <code>true</code> if the caret should be wide, and
+ * <code>false</code> otherwise. In some languages, for example
+ * Korean, the caret is typically widened to the width of the
+ * current character in the in-line edit session.
+ *
+ * @return the wide caret state
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public boolean getWideCaret() {
+ return false;
+}
+
+boolean hasMarkedText (int id, int sel) {
+ return text.length () != 0;
+}
+
+boolean insertText (int id, int sel, int string) {
+ if (startOffset == -1) return true;
+ NSString str = new NSString (string);
+ if (str.isKindOfClass (OS.objc_getClass ("NSAttributedString"))) {
+ str = new NSAttributedString (string).string ();
+ }
+ int length = str.length ();
+ char[] chars = new char [length];
+ str.getCharacters_ (chars);
+ int end = startOffset + text.length ();
+ ranges = null;
+ styles = null;
+ caretOffset = commitCount = length;
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_CHANGED;
+ event.start = startOffset;
+ event.end = end;
+ event.text = text = new String (chars);
+ sendEvent (SWT.ImeComposition, event);
+ text = "";
+ caretOffset = commitCount = 0;
+ startOffset = -1;
+ return event.doit;
+}
+
+boolean isInlineEnabled () {
+ return hooks (SWT.ImeComposition);
+}
+
+NSRange markedRange (int id, int sel) {
+ if (startOffset == -1) {
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_SELECTION;
+ sendEvent (SWT.ImeComposition, event);
+ startOffset = event.start;
+ }
+ NSRange range = new NSRange ();
+ range.location = startOffset;
+ range.length = text.length ();
+ return range;
+}
+
+void releaseParent () {
+ super.releaseParent ();
+ if (this == parent.getIME ()) parent.setIME (null);
+}
+
+void releaseWidget () {
+ super.releaseWidget ();
+ parent = null;
+ text = null;
+ styles = null;
+ ranges = null;
+}
+
+NSRange selectedRange (int id, int sel) {
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_SELECTION;
+ sendEvent (SWT.ImeComposition, event);
+ NSRange range = new NSRange ();
+ range.location = event.start;
+ range.length = event.text.length ();
+ return range;
+}
+
+/**
+ * Sets the offset of the composition from the start of the document.
+ * This is the start offset of the composition within the document and
+ * in not changed by the input method editor itself during the in-line edit
+ * session but may need to be changed by clients of the IME. For example,
+ * if during an in-line edit operation, a text editor inserts characters
+ * above the IME, then the IME must be informed that the composition
+ * offset has changed.
+ *
+ * @return the offset of the composition
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setCompositionOffset (int offset) {
+ checkWidget ();
+ if (offset < 0) return;
+ if (startOffset != -1) {
+ startOffset = offset;
+ }
+}
+
+boolean setMarkedText_selectedRange (int id, int sel, int string, int selRange) {
+ if (!isInlineEnabled ()) return true;
+ ranges = null;
+ styles = null;
+ caretOffset = commitCount = 0;
+ int end = startOffset + text.length ();
+ if (startOffset == -1) {
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_SELECTION;
+ sendEvent (SWT.ImeComposition, event);
+ startOffset = event.start;
+ end = event.end;
+ }
+ NSString str = new NSString (string);
+ if (str.isKindOfClass (OS.objc_getClass ("NSAttributedString"))) {
+ NSAttributedString attribStr = new NSAttributedString (string);
+ str = attribStr.string ();
+ int length = str.length ();
+ styles = new TextStyle [length];
+ ranges = new int [length * 2];
+ NSRange rangeLimit = new NSRange (), effectiveRange = new NSRange ();
+ rangeLimit.length = length;
+ int rangeCount = 0;
+ int /*long*/ ptr = OS.malloc (NSRange.sizeof);
+ for (int i = 0; i < length;) {
+ NSDictionary attribs = attribStr.attributesAtIndex_longestEffectiveRange_inRange_ (i, ptr, rangeLimit);
+ OS.memmove (effectiveRange, ptr, NSRange.sizeof);
+ i = effectiveRange.location + effectiveRange.length;
+ ranges [rangeCount * 2] = effectiveRange.location;
+ ranges [rangeCount * 2 + 1] = effectiveRange.location + effectiveRange.length - 1;
+ styles [rangeCount++] = getStyle (attribs);
+ }
+ OS.free (ptr);
+ if (rangeCount != styles.length) {
+ TextStyle [] newStyles = new TextStyle [rangeCount];
+ System.arraycopy (styles, 0, newStyles, 0, newStyles.length);
+ styles = newStyles;
+ int [] newRanges = new int [rangeCount * 2];
+ System.arraycopy (ranges, 0, newRanges, 0, newRanges.length);
+ ranges = newRanges;
+ }
+ }
+ int length = str.length ();
+ if (ranges == null && length > 0) {
+ styles = new TextStyle []{getStyle (display.markedAttributes)};
+ ranges = new int[]{0, length - 1};
+ }
+ NSRange range = new NSRange ();
+ OS.memmove (range, selRange, NSRange.sizeof);
+ caretOffset = range.location;
+ char [] chars = new char [length];
+ str.getCharacters_ (chars);
+ Event event = new Event ();
+ event.detail = SWT.COMPOSITION_CHANGED;
+ event.start = startOffset;
+ event.end = end;
+ event.text = text = new String (chars);
+ sendEvent (SWT.ImeComposition, event);
+ return true;
+}
+
+int validAttributesForMarkedText (int id, int sel) {
+ NSMutableArray attribs = NSMutableArray.arrayWithCapacity (6);
+ attribs.addObject (new NSString (OS.NSForegroundColorAttributeName ()));
+ attribs.addObject (new NSString (OS.NSBackgroundColorAttributeName ()));
+ attribs.addObject (new NSString (OS.NSUnderlineStyleAttributeName ()));
+ attribs.addObject (new NSString (OS.NSUnderlineColorAttributeName ()));
+ attribs.addObject (new NSString (OS.NSStrikethroughStyleAttributeName ()));
+ attribs.addObject (new NSString (OS.NSStrikethroughColorAttributeName ()));
+ return attribs.id;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java
index 532b9c5760..ff48f76308 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java
@@ -503,6 +503,11 @@ void createHandle () {
window.setAcceptsMouseMovedEvents(true);
windowDelegate = (SWTWindowDelegate)new SWTWindowDelegate().alloc().init();
window.setDelegate(windowDelegate);
+
+ id id = window.fieldEditor (true, null);
+ if (id != null) {
+ OS.object_setClass (id.id, OS.objc_getClass ("SWTEditorView"));
+ }
}
void deregister () {
@@ -1338,7 +1343,8 @@ void setWindowVisible (boolean visible, boolean key) {
}
void setZOrder () {
- window.setContentView (topView());
+ if (scrollView != null) scrollView.setDocumentView (view);
+ window.setContentView (scrollView != null ? scrollView : view);
}
void setZOrder (Control control, boolean above) {
@@ -1436,28 +1442,4 @@ boolean windowShouldClose(int window) {
void windowWillClose(int notification) {
}
-void windowSendEvent(int id, int event) {
- NSEvent nsEvent = new NSEvent(event);
- int type = nsEvent.type();
- if (type == OS.NSFlagsChanged) {
- Control eventTarget = display.getFocusControl();
- if (eventTarget != null) {
- if (eventTarget.flagsChanged(event)) return;
- }
- } else if (type == OS.NSKeyDown || type == OS.NSKeyUp) {
- Control eventTarget = display.getFocusControl();
- if (eventTarget != null) {
- if (type == OS.NSKeyDown) {
- boolean[] consume = new boolean[1];
- int key = nsEvent.keyCode();
- if (eventTarget.translateTraversal(key, nsEvent, consume)) return;
- if (consume[0]) return;
- if (eventTarget.isDisposed()) return;
- }
- if (!eventTarget.sendKeyEvent(nsEvent, type == OS.NSKeyDown ? SWT.KeyDown : SWT.KeyUp)) return;
- }
- }
- super.windowSendEvent(id, event);
-}
-
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java
index 0f1c8c22a5..33139fee30 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Text.java
@@ -1143,67 +1143,68 @@ public void selectAll () {
}
}
-boolean sendKeyEvent (int type, Event event) {
- if (!super.sendKeyEvent (type, event)) {
- return false;
- }
- if (type != SWT.KeyDown) return true;
- if ((style & SWT.READ_ONLY) != 0) return true;
- if (event.character == 0) return true;
- if ((event.stateMask & SWT.COMMAND) != 0) return true;
- String oldText = "";
- int charCount = getCharCount ();
- Point selection = getSelection ();
- int start = selection.x, end = selection.y;
- switch (event.character) {
- case SWT.BS:
- if (start == end) {
- if (start == 0) return true;
- start = Math.max (0, start - 1);
- }
- break;
- case SWT.DEL:
- if (start == end) {
- if (start == charCount) return true;
- end = Math.min (end + 1, charCount);
- }
- break;
- case SWT.CR:
- if ((style & SWT.SINGLE) != 0) return true;
- oldText = DELIMITER;
- break;
- default:
- if (event.character != '\t' && event.character < 0x20) return true;
- oldText = new String (new char [] {event.character});
- }
- String newText = verifyText (oldText, start, end, event);
- if (newText == null) return false;
- if (charCount - (end - start) + newText.length () > textLimit) {
- return false;
- }
- boolean result = newText == oldText;
- if (newText != oldText || hiddenText != null) {
-// if (txnObject == 0) {
-// String text = new String (getEditText (0, -1));
-// String leftText = text.substring (0, start);
-// String rightText = text.substring (end, text.length ());
-// setEditText (leftText + newText + rightText);
-// start += newText.length ();
-// setSelection (new Point (start, start));
-// result = false;
-// } else {
-// setTXNText (start, end, newText);
-// }
- }
- /*
- * Post the modify event so that the character will be inserted
- * into the widget when the modify event is delivered. Normally,
- * modify events are sent but it is safe to post the event here
- * because this method is called from the event loop.
- */
- postEvent (SWT.Modify);
- return result;
-}
+//boolean sendKeyEvent (int type, Event event) {
+// //TODO
+// if (!super.sendKeyEvent (type, event)) {
+// return false;
+// }
+// if (type != SWT.KeyDown) return true;
+// if ((style & SWT.READ_ONLY) != 0) return true;
+// if (event.character == 0) return true;
+// if ((event.stateMask & SWT.COMMAND) != 0) return true;
+// String oldText = "";
+// int charCount = getCharCount ();
+// Point selection = getSelection ();
+// int start = selection.x, end = selection.y;
+// switch (event.character) {
+// case SWT.BS:
+// if (start == end) {
+// if (start == 0) return true;
+// start = Math.max (0, start - 1);
+// }
+// break;
+// case SWT.DEL:
+// if (start == end) {
+// if (start == charCount) return true;
+// end = Math.min (end + 1, charCount);
+// }
+// break;
+// case SWT.CR:
+// if ((style & SWT.SINGLE) != 0) return true;
+// oldText = DELIMITER;
+// break;
+// default:
+// if (event.character != '\t' && event.character < 0x20) return true;
+// oldText = new String (new char [] {event.character});
+// }
+// String newText = verifyText (oldText, start, end, event);
+// if (newText == null) return false;
+// if (charCount - (end - start) + newText.length () > textLimit) {
+// return false;
+// }
+// boolean result = newText == oldText;
+// if (newText != oldText || hiddenText != null) {
+//// if (txnObject == 0) {
+//// String text = new String (getEditText (0, -1));
+//// String leftText = text.substring (0, start);
+//// String rightText = text.substring (end, text.length ());
+//// setEditText (leftText + newText + rightText);
+//// start += newText.length ();
+//// setSelection (new Point (start, start));
+//// result = false;
+//// } else {
+//// setTXNText (start, end, newText);
+//// }
+// }
+// /*
+// * Post the modify event so that the character will be inserted
+// * into the widget when the modify event is delivered. Normally,
+// * modify events are sent but it is safe to post the event here
+// * because this method is called from the event loop.
+// */
+// postEvent (SWT.Modify);
+// return result;
+//}
void setBackground (float [] color) {
NSColor nsColor;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ToolItem.java
index dad355ce5d..e540f40ce1 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ToolItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/ToolItem.java
@@ -511,8 +511,8 @@ public boolean isEnabled () {
return getEnabled () && parent.isEnabled ();
}
-int menuForEvent (int event) {
- return parent.menuForEvent(event);
+int menuForEvent (int id, int sel, int theEvent) {
+ return parent.menuForEvent (id, sel, theEvent);
}
void register () {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
index 9fc7889356..4d10de8ffd 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
@@ -129,6 +129,10 @@ public Widget (Widget parent, int style) {
display = parent.display;
}
+int attributedSubstringFromRange (int id, int sel, int range) {
+ return 0;
+}
+
void callSuper(int id, int selector, int arg0) {
objc_super super_struct = new objc_super();
super_struct.receiver = id;
@@ -143,6 +147,10 @@ boolean callSuperBoolean(int id, int sel) {
return OS.objc_msgSendSuper(super_struct, sel) != 0;
}
+int characterIndexForPoint (int id, int sel, int point) {
+ return OS.NSNotFound;
+}
+
boolean acceptsFirstResponder (int id, int sel) {
return callSuperBoolean(id, sel);
}
@@ -378,6 +386,11 @@ public void dispose () {
release (true);
}
+boolean doCommandBySelector (int id, int sel, int aSelector) {
+ callSuper (id, sel, aSelector);
+ return true;
+}
+
void drawBackground (int control, int context) {
/* Do nothing */
}
@@ -400,6 +413,10 @@ boolean filters (int eventType) {
return display.filters (eventType);
}
+NSRect firstRectForCharacterRange(int id, int sel, int range) {
+ return new NSRect ();
+}
+
int fixMnemonic (char [] buffer) {
int i=0, j=0;
while (i < buffer.length) {
@@ -559,6 +576,10 @@ public int getStyle () {
return style;
}
+boolean hasMarkedText (int id, int sel) {
+ return false;
+}
+
void helpRequested(int theEvent) {
}
@@ -574,6 +595,11 @@ boolean hooks (int eventType) {
return eventTable.hooks (eventType);
}
+boolean insertText (int id, int sel, int string) {
+ callSuper (id, sel, string);
+ return true;
+}
+
/**
* Returns <code>true</code> if the widget has been disposed,
* and <code>false</code> otherwise.
@@ -626,32 +652,8 @@ boolean isValidThread () {
return getDisplay ().isValidThread ();
}
-boolean flagsChanged (int theEvent) {
- if ((state & SAFARI_EVENTS_FIX) != 0) return true;
- int mask = 0;
- NSEvent nsEvent = new NSEvent (theEvent);
- int modifiers = nsEvent.modifierFlags ();
- int keyCode = Display.translateKey (nsEvent.keyCode ());
- if (keyCode == 0) return true;
- switch (keyCode) {
- case SWT.ALT: mask = OS.NSAlternateKeyMask; break;
- case SWT.CONTROL: mask = OS.NSControlKeyMask; break;
- case SWT.COMMAND: mask = OS.NSCommandKeyMask; break;
- case SWT.SHIFT: mask = OS.NSShiftKeyMask; break;
- case SWT.CAPS_LOCK:
- Event event = new Event();
- event.keyCode = keyCode;
- setInputState (event, nsEvent, SWT.KeyDown);
- sendKeyEvent (SWT.KeyDown, event);
- setInputState (event, nsEvent, SWT.KeyUp);
- sendKeyEvent (SWT.KeyUp, event);
- return true;
- }
- int type = (mask & modifiers) != 0 ? SWT.KeyDown : SWT.KeyUp;
- Event event = new Event();
- event.keyCode = keyCode;
- setInputState (event, nsEvent, type);
- return sendKeyEvent (type, event);
+void flagsChanged (int id, int sel, int theEvent) {
+ callSuper (id, sel, theEvent);
}
void keyDown (int id, int sel, int theEvent) {
@@ -702,13 +704,20 @@ void mouseExited(int id, int sel, int theEvent) {
callSuper(id, sel, theEvent);
}
-int menuForEvent (int event) {
- return 0;
+int menuForEvent (int id, int sel, int theEvent) {
+ objc_super super_struct = new objc_super();
+ super_struct.receiver = id;
+ super_struct.cls = OS.objc_msgSend(id, OS.sel_superclass);
+ return OS.objc_msgSendSuper(super_struct, sel, theEvent);
}
void menuNeedsUpdate(int menu) {
}
+NSRange markedRange (int id, int sel) {
+ return new NSRange ();
+}
+
void menu_willHighlightItem(int menu, int item) {
}
@@ -928,6 +937,10 @@ void scrollWheel (int id, int sel, int theEvent) {
callSuper(id, sel, theEvent);
}
+NSRange selectedRange (int id, int sel) {
+ return new NSRange ();
+}
+
void sendArrowSelection () {
}
@@ -969,23 +982,9 @@ void sendEvent (int eventType, Event event, boolean send) {
boolean sendKeyEvent (NSEvent nsEvent, int type) {
if ((state & SAFARI_EVENTS_FIX) != 0) return true;
- NSString chars = nsEvent.characters ();
- int length = chars.length();
- if (length > 1) {
- for (int i = 0; i < length; i++) {
- Event event = new Event ();
- event.character = (char) chars.characterAtIndex (i);
- setInputState (event, nsEvent, type);
- sendKeyEvent (type, event);
- }
- return true;
- } else if (length == 1) {
- Event event = new Event ();
- if (!setKeyState (event, type, nsEvent)) return true;
- return sendKeyEvent (type, event);
- }
- //TODO dead keys
- return true;
+ Event event = new Event ();
+ if (!setKeyState (event, type, nsEvent)) return true;
+ return sendKeyEvent (type, event);
}
boolean sendKeyEvent (int type, Event event) {
@@ -1207,12 +1206,12 @@ boolean setKeyState (Event event, int type, NSEvent nsEvent) {
default:
if (event.keyCode == 0 || (SWT.KEYPAD_MULTIPLY <= event.keyCode && event.keyCode <= SWT.KEYPAD_CR)) {
NSString chars = nsEvent.characters ();
- event.character = (char)chars.characterAtIndex (0);
+ if (chars.length() > 0) event.character = (char)chars.characterAtIndex (0);
}
if (event.keyCode == 0) {
//TODO this is wrong for shifted keys like ';', '1' and non-english keyboards
- NSString chars = nsEvent.charactersIgnoringModifiers ().lowercaseString();
- event.keyCode = (char)chars.characterAtIndex(0);
+ NSString unmodifiedChars = nsEvent.charactersIgnoringModifiers ().lowercaseString();
+ if (unmodifiedChars.length() > 0) event.keyCode = (char)unmodifiedChars.characterAtIndex(0);
}
}
if (event.keyCode == 0 && event.character == 0) {
@@ -1222,6 +1221,10 @@ boolean setKeyState (Event event, int type, NSEvent nsEvent) {
return true;
}
+boolean setMarkedText_selectedRange (int id, int sel, int string, int range) {
+ return true;
+}
+
void tableViewSelectionDidChange (int aNotification) {
}
@@ -1254,6 +1257,10 @@ public String toString () {
return getName () + " {" + string + "}";
}
+int validAttributesForMarkedText (int id, int sel) {
+ return 0;
+}
+
void willSelectTabViewItem(int tabView, int tabViewItem) {
}