diff dwt/widgets/IME.d @ 213:36f5cb12e1a2

Update to SWT 3.4M7
author Frank Benoit <benoit@tionex.de>
date Sat, 17 May 2008 17:34:28 +0200
parents
children a8fed3e56433
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/widgets/IME.d	Sat May 17 17:34:28 2008 +0200
@@ -0,0 +1,429 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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
+ *******************************************************************************/
+module dwt.widgets.IME;
+
+
+import dwt.DWT;
+import dwt.graphics.Color;
+import dwt.graphics.TextStyle;
+import dwt.internal.win32.OS;
+import dwt.internal.win32.WINTYPES;
+
+import dwt.widgets.Widget;
+import dwt.widgets.Canvas;
+import dwt.widgets.Event;
+import dwt.widgets.Display;
+
+import dwt.dwthelper.utils;
+
+/**
+ * TODO - JAVA DOC
+ *
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>(none)</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>(none)</dd>
+ * </dl>
+ * <p>
+ * .
+ * </p>
+ *
+ * @since 3.4
+ */
+
+public class IME : Widget {
+    Canvas parent;
+    int caretOffset;
+    int startOffset;
+    int commitCount;
+    String text;
+    int [] ranges;
+    TextStyle [] styles;
+
+    static const int WM_MSIME_MOUSE;
+
+    static byte [16] IID_ITfInputProcessorProfiles;
+    static byte [16] IID_ITfDisplayAttributeProvider;
+    static byte [16] CLSID_TF_InputProcessorProfiles;
+    static byte [16] GUID_TFCAT_TIP_KEYBOARD;
+    static this() {
+        WM_MSIME_MOUSE = OS.RegisterWindowMessage (StrToTCHARz ("MSIMEMouseOperation"));
+
+        OS.IIDFromString ("{1F02B6C5-7842-4EE6-8A0B-9A24183A95CA}\0"w.ptr, IID_ITfInputProcessorProfiles.ptr);
+        OS.IIDFromString ("{fee47777-163c-4769-996a-6e9c50ad8f54}\0"w.ptr, IID_ITfDisplayAttributeProvider.ptr);
+        OS.IIDFromString ("{33C53A50-F456-4884-B049-85FD643ECFED}\0"w.ptr, CLSID_TF_InputProcessorProfiles.ptr);
+        OS.IIDFromString ("{34745C63-B2F0-4784-8B67-5E12C8701A31}\0"w.ptr, GUID_TFCAT_TIP_KEYBOARD.ptr);
+    }
+
+    /* TextLayout has a copy of these constants */
+    static const int UNDERLINE_IME_DOT = 1 << 16;
+    static const int UNDERLINE_IME_DASH = 2 << 16;
+    static const int UNDERLINE_IME_THICK = 3 << 16;
+
+/**
+ * Prevents uninitialized instances from being created outside the package.
+ */
+this () {
+}
+
+/**
+ *
+ * @see DWT
+ */
+public this (Canvas parent, int style) {
+    super (parent, style);
+    this.parent = parent;
+    createWidget ();
+}
+
+void createWidget () {
+    text = "";
+    startOffset = -1;
+    if (parent.getIME () is null) {
+        parent.setIME (this);
+    }
+}
+
+public int getCaretOffset () {
+    checkWidget ();
+    return startOffset + caretOffset;
+}
+
+public int getCommitCount () {
+    checkWidget ();
+    return commitCount;
+}
+
+public int getCompositionOffset () {
+    checkWidget ();
+    return startOffset;
+}
+
+TF_DISPLAYATTRIBUTE* getDisplayAttribute (short langid, int attInfo) {
+    void* pProfiles;
+    int hr = OS.CoCreateInstance (CLSID_TF_InputProcessorProfiles.ptr, null, OS.CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles.ptr, &pProfiles);
+    TF_DISPLAYATTRIBUTE* pda;
+    if (hr is OS.S_OK) {
+        byte [16] pclsid;
+        byte [16] pguidProfile;
+        /* pProfiles.GetDefaultLanguageProfile () */
+        hr = OS.VtblCall (8, pProfiles, cast(int)langid, cast(int)GUID_TFCAT_TIP_KEYBOARD.ptr, cast(int)pclsid.ptr, cast(int)pguidProfile.ptr);
+        if (hr is OS.S_OK) {
+            void* pProvider;
+            hr = OS.CoCreateInstance (pclsid.ptr, null, OS.CLSCTX_INPROC_SERVER, IID_ITfDisplayAttributeProvider.ptr, &pProvider);
+            if (hr is OS.S_OK) {
+                void* pEnum;
+                /* pProvider.EnumDisplayAttributeInfo () */
+                hr = OS.VtblCall (3, pProvider, cast(int)&pEnum);
+                if (hr is OS.S_OK) {
+                    void* pDispInfo;
+                    TF_DISPLAYATTRIBUTE* tempPda;
+                    /* pEnum.Next () */
+                    while ((hr = OS.VtblCall (4, pEnum, 1, cast(int) &pDispInfo, 0 )) is OS.S_OK) {
+                        /* pDispInfo.GetAttributeInfo(); */
+                        OS.VtblCall (5, pDispInfo, cast(int)&tempPda);
+                        /* pDispInfo.Release () */
+                        OS.VtblCall (2, pDispInfo);
+                        if (tempPda.bAttr is attInfo) {
+                            pda = tempPda;
+                            break;
+                        }
+                    }
+                    /* pEnum.Release () */
+                    hr = OS.VtblCall (2, pEnum);
+                }
+                /* pProvider.Release () */
+                hr = OS.VtblCall (2, pProvider);
+            }
+        }
+        /* pProfiles.Release () */
+        hr = OS.VtblCall (2, pProfiles);
+    }
+    if (pda is null) {
+        pda = new TF_DISPLAYATTRIBUTE ();
+        switch (attInfo) {
+            case OS.TF_ATTR_INPUT:
+                pda.lsStyle = OS.TF_LS_SQUIGGLE;
+                break;
+            case OS.TF_ATTR_CONVERTED:
+            case OS.TF_ATTR_TARGET_CONVERTED:
+                pda.lsStyle = OS.TF_LS_SOLID;
+                pda.fBoldLine = attInfo is OS.TF_ATTR_TARGET_CONVERTED;
+                break;
+        }
+    }
+    return pda;
+}
+
+public int [] getRanges () {
+    checkWidget ();
+    if (ranges is 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;
+}
+
+public TextStyle [] getStyles () {
+    checkWidget ();
+    if (styles is null) return new TextStyle [0];
+    TextStyle [] result = new TextStyle [styles.length];
+    System.arraycopy (styles, 0, result, 0, styles.length);
+    return result;
+}
+
+public String getText () {
+    checkWidget ();
+    return text;
+}
+
+public bool getWideCaret() {
+    checkWidget ();
+    auto layout = OS.GetKeyboardLayout (0);
+    short langID = cast(short)OS.LOWORD ( cast(int) layout);
+    return OS.PRIMARYLANGID (langID) is OS.LANG_KOREAN;
+}
+
+bool isInlineEnabled () {
+    if (OS.IsWinCE || OS.WIN32_VERSION < OS.VERSION (5, 1)) return false;
+    return OS.IsDBLocale && hooks (DWT.ImeComposition);
+}
+
+void releaseParent () {
+    super.releaseParent ();
+    if (this is parent.getIME ()) parent.setIME (null);
+}
+
+void releaseWidget () {
+    super.releaseWidget ();
+    parent = null;
+    text = null;
+    styles = null;
+    ranges = null;
+}
+
+public void setCompositionOffset (int offset) {
+    checkWidget ();
+    if (offset < 0) return;
+    if (startOffset !is -1) {
+        startOffset = offset;
+    }
+}
+
+LRESULT WM_IME_COMPOSITION (int /*long*/ wParam, int /*long*/ lParam) {
+    if (!isInlineEnabled ()) return null;
+    ranges = null;
+    styles = null;
+    caretOffset = commitCount = 0;
+    auto hwnd = parent.handle;
+    auto hIMC = OS.ImmGetContext (hwnd);
+    int codePage = parent.getCodePage ();
+    if (hIMC !is null) {
+        TCHAR[] buffer = null;
+        if ((lParam & OS.GCS_RESULTSTR) !is 0) {
+            int length_ = OS.ImmGetCompositionString (hIMC, OS.GCS_RESULTSTR, null, 0);
+            if (length_ > 0) {
+                buffer = NewTCHARs (codePage, length_ / TCHAR.sizeof);
+                OS.ImmGetCompositionString (hIMC, OS.GCS_RESULTSTR, buffer.ptr, length_);
+                if (startOffset is -1) {
+                    Event event = new Event ();
+                    event.detail = DWT.COMPOSITION_SELECTION;
+                    sendEvent (DWT.ImeComposition, event);
+                    startOffset = event.start;
+                }
+                Event event = new Event ();
+                event.detail = DWT.COMPOSITION_CHANGED;
+                event.start = startOffset;
+                event.end = startOffset + text.length;
+                event.text = text = buffer !is null ? TCHARsToStr(buffer) : "";
+                commitCount = text.length ;
+                sendEvent (DWT.ImeComposition, event);
+                String chars = text;
+                text = "";
+                startOffset = -1;
+                commitCount = 0;
+                if (event.doit) {
+                    Display display = this.display;
+                    display.lastKey = 0;
+                    display.lastVirtual = display.lastNull = display.lastDead = false;
+                    length_ = chars.length;
+                    for (int i = 0; i < length_; i++) {
+                        char c = chars.charAt (i);
+                        display.lastAscii = c;
+                        event = new Event ();
+                        event.character = c;
+                        parent.sendEvent (DWT.KeyDown, event);
+                    }
+                }
+            }
+            if ((lParam & OS.GCS_COMPSTR) is 0) return LRESULT.ONE;
+        }
+        buffer = null;
+        if ((lParam & OS.GCS_COMPSTR) !is 0) {
+            int length_ = OS.ImmGetCompositionString (hIMC, OS.GCS_COMPSTR, null, 0);
+            if (length_ > 0) {
+                buffer = NewTCHARs (codePage, length_ / TCHAR.sizeof);
+                OS.ImmGetCompositionString (hIMC, OS.GCS_COMPSTR, buffer.ptr, length_);
+                if ((lParam & OS.GCS_CURSORPOS) !is 0) {
+                    caretOffset = OS.ImmGetCompositionString (hIMC, OS.GCS_CURSORPOS, null, 0);
+                }
+                int [] clauses = null;
+                if ((lParam & OS.GCS_COMPCLAUSE) !is 0) {
+                    length_ = OS.ImmGetCompositionStringW (hIMC, OS.GCS_COMPCLAUSE, /+cast(int [])+/null, 0);
+                    if (length_ > 0) {
+                        clauses = new int [length_ / 4];
+                        OS.ImmGetCompositionStringW (hIMC, OS.GCS_COMPCLAUSE, clauses.ptr, length_);
+                    }
+                }
+                if ((lParam & OS.GCS_COMPATTR) !is 0 && clauses !is null) {
+                    length_ = OS.ImmGetCompositionStringA (hIMC, OS.GCS_COMPATTR, /+cast(byte [])+/null, 0);
+                    if (length_ > 0) {
+                        byte [] attrs = new byte [length_];
+                        OS.ImmGetCompositionStringA (hIMC, OS.GCS_COMPATTR, attrs.ptr, length_);
+                        length_ = clauses.length - 1;
+                        ranges = new int [length_ * 2];
+                        styles = new TextStyle [length_];
+                        auto layout = OS.GetKeyboardLayout (0);
+                        short langID = cast(short)OS.LOWORD ( cast(int) layout);
+                        TF_DISPLAYATTRIBUTE* attr = null;
+                        TextStyle style = null;
+                        for (int i = 0; i < length_; i++) {
+                            ranges [i * 2] = clauses [i];
+                            ranges [i * 2 + 1] = clauses [i + 1] - 1;
+                            styles [i] = style = new TextStyle ();
+                            attr = getDisplayAttribute (langID, attrs [clauses [i]]);
+                            if (attr !is null) {
+                                switch (attr.crText.type) {
+                                    case OS.TF_CT_COLORREF:
+                                        style.foreground = Color.win32_new (display, attr.crText.cr);
+                                        break;
+                                    case OS.TF_CT_SYSCOLOR:
+                                        int colorRef = OS.GetSysColor (attr.crText.cr);
+                                        style.foreground = Color.win32_new (display, colorRef);
+                                        break;
+                                }
+                                switch (attr.crBk.type) {
+                                    case OS.TF_CT_COLORREF:
+                                        style.background = Color.win32_new (display, attr.crBk.cr);
+                                        break;
+                                    case OS.TF_CT_SYSCOLOR:
+                                        int colorRef = OS.GetSysColor (attr.crBk.cr);
+                                        style.background = Color.win32_new (display, colorRef);
+                                        break;
+                                }
+                                switch (attr.crLine.type) {
+                                    case OS.TF_CT_COLORREF:
+                                        style.underlineColor = Color.win32_new (display, attr.crLine.cr);
+                                        break;
+                                    case OS.TF_CT_SYSCOLOR:
+                                        int colorRef = OS.GetSysColor (attr.crLine.cr);
+                                        style.underlineColor = Color.win32_new (display, colorRef);
+                                        break;
+                                }
+                                style.underline = attr.lsStyle !is OS.TF_LS_NONE;
+                                switch (attr.lsStyle) {
+                                    case OS.TF_LS_SQUIGGLE:
+                                        style.underlineStyle = DWT.UNDERLINE_SQUIGGLE;
+                                        break;
+                                    case OS.TF_LS_DASH:
+                                        style.underlineStyle = UNDERLINE_IME_DASH;
+                                        break;
+                                    case OS.TF_LS_DOT:
+                                        style.underlineStyle = UNDERLINE_IME_DOT;
+                                        break;
+                                    case OS.TF_LS_SOLID:
+                                        style.underlineStyle = attr.fBoldLine ? UNDERLINE_IME_THICK : DWT.UNDERLINE_SINGLE;
+                                        break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            OS.ImmReleaseContext (hwnd, hIMC);
+        }
+        int end = startOffset + text.length;
+        if (startOffset is -1) {
+            Event event = new Event ();
+            event.detail = DWT.COMPOSITION_SELECTION;
+            sendEvent (DWT.ImeComposition, event);
+            startOffset = event.start;
+            end = event.end;
+        }
+        Event event = new Event ();
+        event.detail = DWT.COMPOSITION_CHANGED;
+        event.start = startOffset;
+        event.end = end;
+        event.text = text = buffer !is null ? TCHARsToStr(buffer) : "";
+        sendEvent (DWT.ImeComposition, event);
+        if (text.length is 0) {
+            startOffset = -1;
+            ranges = null;
+            styles = null;
+        }
+    }
+    return LRESULT.ONE;
+}
+
+LRESULT WM_IME_COMPOSITION_START (int /*long*/ wParam, int /*long*/ lParam) {
+    return isInlineEnabled () ? LRESULT.ONE : null;
+}
+
+LRESULT WM_IME_ENDCOMPOSITION (int /*long*/ wParam, int /*long*/ lParam) {
+    return isInlineEnabled () ? LRESULT.ONE : null;
+}
+
+LRESULT WM_KILLFOCUS (int /*long*/ wParam, int /*long*/ lParam) {
+    if (!isInlineEnabled ()) return null;
+    auto hwnd = parent.handle;
+    auto hIMC = OS.ImmGetContext (hwnd);
+    if (hIMC !is null) {
+        if (OS.ImmGetOpenStatus (hIMC)) {
+            OS.ImmNotifyIME (hIMC, OS.NI_COMPOSITIONSTR, OS.CPS_COMPLETE, 0);
+        }
+        OS.ImmReleaseContext (hwnd, hIMC);
+    }
+    return null;
+}
+
+LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
+    if (!isInlineEnabled ()) return null;
+    auto hwnd = parent.handle;
+    auto hIMC = OS.ImmGetContext (hwnd);
+    if (hIMC !is null) {
+        if (OS.ImmGetOpenStatus (hIMC)) {
+            if (OS.ImmGetCompositionString (hIMC, OS.GCS_COMPSTR, null, 0) > 0) {
+                Event event = new Event ();
+                event.detail = DWT.COMPOSITION_OFFSET;
+                event.x = OS.GET_X_LPARAM (lParam);
+                event.y = OS.GET_Y_LPARAM (lParam);
+                sendEvent (DWT.ImeComposition, event);
+                int offset = event.index;
+                int length_ = text.length;
+                if (offset !is -1 && startOffset !is -1 && startOffset <= offset && offset < startOffset + length_) {
+                    auto imeWnd = OS.ImmGetDefaultIMEWnd (hwnd);
+                    offset = event.index + event.count - startOffset;
+                    int trailing = event.count > 0 ? 1 : 2;
+                    int /*long*/ param = OS.MAKEWPARAM (OS.MAKEWORD (OS.IMEMOUSE_LDOWN, trailing), offset);
+                    OS.SendMessage (imeWnd, WM_MSIME_MOUSE, param, hIMC);
+                } else {
+                    OS.ImmNotifyIME (hIMC, OS.NI_COMPOSITIONSTR, OS.CPS_COMPLETE, 0);
+                }
+            }
+        }
+        OS.ImmReleaseContext (hwnd, hIMC);
+    }
+    return null;
+}
+
+}