summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKnut Radloff <kradloff>2003-07-15 15:21:56 +0000
committerKnut Radloff <kradloff>2003-07-15 15:21:56 +0000
commit6e328f67bc48bae3babf2d21c4d4332857a0675c (patch)
treebcfc9f7be8e755967e50f479c0123bd654a85f46
parent85e3e91f7c5ab2935864a23260c5b4863a9eb03c (diff)
downloadeclipse.platform.swt-6e328f67bc48bae3babf2d21c4d4332857a0675c.tar.gz
eclipse.platform.swt-6e328f67bc48bae3babf2d21c4d4332857a0675c.tar.xz
eclipse.platform.swt-6e328f67bc48bae3babf2d21c4d4332857a0675c.zip
Fixes bug 37608
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java86
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java33
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java16
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java117
4 files changed, 222 insertions, 30 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index fc1fe9b3c9..8aa978f4f5 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -140,6 +140,7 @@ public class StyledText extends Canvas {
int lastTextChangeReplaceLineCount; // text changed handler
int lastTextChangeReplaceCharCount;
boolean isBidi;
+ boolean isMirrored;
boolean bidiColoring = false; // apply the BIDI algorithm on text segments of the same color
Image leftCaretBitmap = null;
Image rightCaretBitmap = null;
@@ -1600,8 +1601,8 @@ public StyledText(Composite parent, int style) {
super.setForeground(getForeground());
super.setBackground(getBackground());
Display display = getDisplay();
- boolean isRightOriented = (getStyle() & SWT.MIRRORED) != 0;
- isBidi = StyledTextBidi.isBidiPlatform() || isRightOriented;
+ isMirrored = (getStyle() & SWT.MIRRORED) != 0;
+ isBidi = StyledTextBidi.isBidiPlatform() || isMirrored;
if ((style & SWT.READ_ONLY) != 0) {
setEditable(false);
}
@@ -1623,7 +1624,7 @@ public StyledText(Composite parent, int style) {
}
else {
createCaretBitmaps();
- if (isRightOriented) {
+ if (isMirrored) {
BidiUtil.setKeyboardLanguage(BidiUtil.KEYBOARD_BIDI);
}
new Caret(this, SWT.NULL);
@@ -1642,6 +1643,18 @@ public StyledText(Composite parent, int style) {
String platform= SWT.getPlatform();
isCarbon = "carbon".equals(platform);
+ StyledTextBidi.addOrientationListener(this,
+ new Runnable() {
+ public void run() {
+ setOrientation(SWT.LEFT_TO_RIGHT);
+ }
+ },
+ new Runnable() {
+ public void run() {
+ setOrientation(SWT.RIGHT_TO_LEFT);
+ }
+ }
+ );
// set the caret width, the height of the caret will default to the line height
calculateScrollBars();
createKeyBindings();
@@ -2243,7 +2256,7 @@ void createKeyBindings() {
setKeyBinding(SWT.END | SWT.MOD1, ST.TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1, ST.WINDOW_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1, ST.WINDOW_END);
- if ((getStyle() & SWT.MIRRORED) == 0) {
+ if (isMirrored() == false) {
setKeyBinding(SWT.ARROW_LEFT, ST.COLUMN_PREVIOUS);
setKeyBinding(SWT.ARROW_RIGHT, ST.COLUMN_NEXT);
setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1, ST.WORD_PREVIOUS);
@@ -2267,7 +2280,7 @@ void createKeyBindings() {
setKeyBinding(SWT.END | SWT.MOD1 | SWT.MOD2, ST.SELECT_TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1 | SWT.MOD2, ST.SELECT_WINDOW_END);
- if ((getStyle() & SWT.MIRRORED) == 0) {
+ if (isMirrored() == false) {
setKeyBinding(SWT.ARROW_LEFT | SWT.MOD2, ST.SELECT_COLUMN_PREVIOUS);
setKeyBinding(SWT.ARROW_RIGHT | SWT.MOD2, ST.SELECT_COLUMN_NEXT);
setKeyBinding(SWT.ARROW_LEFT | SWT.MOD1 | SWT.MOD2, ST.SELECT_WORD_PREVIOUS);
@@ -2306,7 +2319,7 @@ void createKeyBindings() {
*/
void createCaretBitmaps() {
int caretWidth = BIDI_CARET_WIDTH;
- int gcStyle = getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+ int gcStyle = isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
Display display = getDisplay();
if (caretPalette == null) {
@@ -3252,7 +3265,7 @@ void doVisualPrevious() {
// check if caret location is at the visual beginning of the line
if (columnX <= XINSET && horizontalScrollOffset == 0) {
return;
- }
+ }
String lineText = content.getLine(line);
int lineLength = lineText.length();
GC gc = getGC();
@@ -3274,7 +3287,7 @@ void doVisualPrevious() {
}
else
if (visualOffset == 0) {
- boolean isRightOriented = (getStyle() & SWT.MIRRORED) != 0;
+ boolean isRightOriented = isMirrored();
//move to visual line end (i.e., behind L2R character/in front of R2L character at visual 0)
if ((isRightOriented && bidi.isRightToLeft(offsetInLine) == false) ||
@@ -3358,7 +3371,7 @@ void doVisualNext() {
visualOffset++;
offsetInLine = bidi.getLogicalOffset(visualOffset);
if (offsetInLine > 0 && offsetInLine < lineLength) {
- boolean isRightOriented = (getStyle() & SWT.MIRRORED) != 0;
+ boolean isRightOriented = isMirrored();
if (isRightOriented) {
boolean leftToRightStart = bidi.isRightToLeft(offsetInLine) == false && bidi.isRightToLeft(offsetInLine - 1);
if (leftToRightStart) {
@@ -5118,6 +5131,7 @@ void handleDispose() {
if (isBidi()) {
StyledTextBidi.removeLanguageListener(this);
}
+ StyledTextBidi.removeOrientationListener(this);
}
/**
* Scrolls the widget horizontally.
@@ -5646,6 +5660,16 @@ boolean isLineDelimiter(int offset) {
return offsetInLine > content.getLine(line).length();
}
/**
+ * Returns whether the widget is mirrored (right oriented/right to left
+ * writing order).
+ *
+ * @return isMirrored true=the widget is right oriented, false=the widget
+ * is left oriented
+ */
+boolean isMirrored() {
+ return isMirrored;
+}
+/**
* Returns whether or not the given lines are visible.
* <p>
*
@@ -5882,7 +5906,7 @@ void performPaint(GC gc,int startLine,int startY, int renderHeight) {
Color foreground = getForeground();
int lineCount = content.getLineCount();
int paintY = 0;
- int gcStyle = getStyle() & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
+ int gcStyle = isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
if (isSingleLine()) {
lineCount = 1;
@@ -6897,7 +6921,7 @@ void setBidiCaretLocation(StyledTextBidi bidi, int caretLine) {
int lineStartOffset = content.getOffsetAtLine(caretLine);
int offsetInLine = caretOffset - lineStartOffset;
GC gc = null;
- boolean isRightOriented = (getStyle() & SWT.MIRRORED) != 0;
+ boolean isRightOriented = isMirrored();
if (bidi == null) {
gc = getGC();
@@ -7405,6 +7429,44 @@ void setMouseWordSelectionAnchor() {
}
}
/**
+ * Sets the widget orientation (writing order). Text will be right aligned
+ * for right to left writing order.
+ * <p>
+ *
+ * @param newOrientation one of SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
+ */
+void setOrientation(int orientation) {
+ if ((orientation & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT)) == 0) {
+ return;
+ }
+ if ((orientation & SWT.RIGHT_TO_LEFT) != 0 && (orientation & SWT.LEFT_TO_RIGHT) != 0) {
+ return;
+ }
+ if ((orientation & SWT.RIGHT_TO_LEFT) != 0) {
+ if (isMirrored()) {
+ return;
+ }
+ isMirrored = true;
+ } else {
+ if (isMirrored() == false) {
+ return;
+ }
+ isMirrored = false;
+ }
+ StyledTextBidi.setOrientation(this, orientation);
+ isBidi = StyledTextBidi.isBidiPlatform() || isMirrored();
+ initializeRenderer();
+ if (isBidi()) {
+ caretDirection = SWT.NULL;
+ createCaretBitmaps();
+ setBidiCaretDirection();
+ }
+ setCaretLocation();
+ keyActionMap.clear();
+ createKeyBindings();
+ super.redraw();
+}
+/**
* Adjusts the maximum and the page size of the scroll bars to
* reflect content width/length changes.
*/
@@ -8269,4 +8331,4 @@ void wordWrapResize(int oldClientAreaWidth) {
// word wrap may have changed on one of the visible lines
super.redraw();
}
-} \ No newline at end of file
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
index e76ba3a1d0..04d9f83d80 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledTextBidi.java
@@ -183,6 +183,20 @@ static void addLanguageListener(Control control, Runnable runnable) {
BidiUtil.addLanguageListener(control.handle, runnable);
}
/**
+ * Adds a listener that is called when the widget orientation (writing order)
+ * is changed by the user.
+ * <p>
+ *
+ * @param control Control to add the keyboard language listener for.
+ * @param LTRRunnable the listener that is called when writing order is
+ * switched to "left to right" (left oriented text).
+ * @param RTLRunnable the listener that is called when writing order is
+ * switched to "right to left" (right oriented text).
+ */
+static void addOrientationListener(Control control, Runnable LTRRunnable, Runnable RTLRunnable) {
+ BidiUtil.addOrientationListener(control.handle, LTRRunnable, RTLRunnable);
+}
+/**
* Answers the direction of the active keyboard language - either
* L2R or R2L. The active keyboard language determines the direction
* of the caret and can be changed by the user (e.g., via Alt-Shift on
@@ -249,6 +263,15 @@ static void removeLanguageListener(Control control) {
BidiUtil.removeLanguageListener(control.handle);
}
/**
+ * Removes the orientation listener for the specified window.
+ * <p>
+ *
+ * @param control window to remove the listener from.
+ */
+static void removeOrientationListener(Control control) {
+ BidiUtil.removeOrientationListener(control.handle);
+}
+/**
* Calculates render positions using the glyph distance values in the dx array.
*/
private void calculateRenderPositions() {
@@ -1049,6 +1072,16 @@ void setKeyboardLanguage(int logicalIndex) {
BidiUtil.setKeyboardLanguage(language);
}
/**
+ * Sets the orientation (writing order) of the specified control. Text will
+ * be right aligned for right to left writing order.
+ * <p>
+ *
+ * @param orientation one of SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
+ */
+static void setOrientation(Control control, int orientation) {
+ BidiUtil.setOrientation(control.handle, orientation);
+}
+/**
* Returns a string representation of the receiver.
* <p>
*
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java
index 44e937c82f..fa1e01366f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/emulated/bidi/org/eclipse/swt/internal/BidiUtil.java
@@ -45,6 +45,11 @@ public static void addLanguageListener(int hwnd, Runnable runnable) {
}
/*
* Not implemented.
+ */
+public static void addOrientationListener(int hwnd, Runnable LTRRunnable, Runnable RTLRunnable) {
+}
+/*
+ * Not implemented.
*
*/
public static void drawGlyphs(GC gc, char[] renderBuffer, int[] renderDx, int x, int y) {
@@ -95,7 +100,16 @@ public static void removeLanguageListener(int hwnd) {
/*
* Not implemented.
*/
+public static void removeOrientationListener(int hwnd) {
+}
+/*
+ * Not implemented.
+ */
public static void setKeyboardLanguage(int language) {
}
-
+/*
+ * Not implemented.
+ */
+public static void setOrientation(int hwnd, int orientation) {
+}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java
index 8082fe6f1a..38385df8eb 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/BidiUtil.java
@@ -37,7 +37,8 @@ public class BidiUtil {
// variables used for providing a listener mechanism for keyboard language
// switching
- static Hashtable map = new Hashtable ();
+ static Hashtable languageMap = new Hashtable ();
+ static Hashtable keyMap = new Hashtable ();
static Hashtable oldProcMap = new Hashtable ();
/*
* This code is intentionally commented. In order
@@ -98,16 +99,30 @@ public class BidiUtil {
* monitored.
* <p>
*
- * @param int the handle of the Control that is listening for keyboard language
+ * @param hwnd the handle of the Control that is listening for keyboard language
* changes
* @param runnable the code that should be executed when a keyboard language change
* occurs
*/
-public static void addLanguageListener (int hwnd, Runnable runnable) {
- map.put (new Integer (hwnd), runnable);
- int oldProc = OS.GetWindowLong (hwnd, OS.GWL_WNDPROC);
- oldProcMap.put (new Integer(hwnd), new Integer(oldProc));
- OS.SetWindowLong (hwnd, OS.GWL_WNDPROC, callback.getAddress ());
+public static void addLanguageListener(int hwnd, Runnable runnable) {
+ languageMap.put(new Integer(hwnd), runnable);
+ subclass(hwnd);
+}
+/**
+ * Adds a widget orientation (writing order) listener. The listener will get notified
+ * when the user switches the writing order using Ctrl-Shift.
+ * <p>
+ *
+ * @param hwnd the handle of the Control that is listening for widget orientation
+ * changes
+ * @param LTRRunnable the listener that is called when writing order is
+ * switched to "left to right" (left oriented text).
+ * @param RTLRunnable the listener that is called when writing order is
+ * switched to "right to left" (right oriented text).
+ */
+public static void addOrientationListener(int hwnd, Runnable LTRRunnable, Runnable RTLRunnable) {
+ keyMap.put(new Integer(hwnd), new Runnable[] {LTRRunnable, RTLRunnable});
+ subclass(hwnd);
}
/**
* Proc used for OS.EnumSystemLanguageGroups call during isBidiPlatform test.
@@ -405,7 +420,7 @@ public static int getKeyboardLanguage() {
*
* @return integer array with an entry for each installed language
*/
-public static int[] getKeyboardLanguageList() {
+static int[] getKeyboardLanguageList() {
int maxSize = 10;
int[] tempList = new int[maxSize];
int size = OS.GetKeyboardLayoutList(maxSize, tempList);
@@ -479,13 +494,23 @@ public static boolean isKeyboardBidi() {
*
* @param hwnd the handle of the Control that is listening for keyboard language changes
*/
-public static void removeLanguageListener (int hwnd) {
- map.remove (new Integer (hwnd));
- Integer proc = (Integer)oldProcMap.remove (new Integer (hwnd));
- if (proc == null) return;
- OS.SetWindowLong (hwnd, OS.GWL_WNDPROC, proc.intValue());
+public static void removeLanguageListener(int hwnd) {
+ languageMap.remove(new Integer(hwnd));
+ unsubclass(hwnd);
}
/**
+ * Removes the widget orientation (writing order) listener for the specified
+ * control.
+ * <p>
+ *
+ * @param hwnd the handle of the Control that is listening for widget
+ * orientation changes
+ */
+public static void removeOrientationListener(int hwnd) {
+ keyMap.remove(new Integer(hwnd));
+ unsubclass(hwnd);
+}
+/**
* Switch the keyboard language to the specified language type. We do
* not distinguish between mulitple bidi or multiple non-bidi languages, so
* set the keyboard to the first language of the given type.
@@ -524,6 +549,36 @@ public static void setKeyboardLanguage(int language) {
}
}
/**
+ * Sets the orientation (writing order) of the specified control. Text will
+ * be right aligned for right to left writing order.
+ * <p>
+ *
+ * @param hwnd the handle of the Control to change the orientation of
+ * @param orientation one of SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
+ */
+public static void setOrientation (int hwnd, int orientation) {
+ int bits = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE);
+ if ((orientation & SWT.RIGHT_TO_LEFT) != 0) {
+ bits |= OS.WS_EX_LAYOUTRTL;
+ } else {
+ bits &= ~OS.WS_EX_LAYOUTRTL;
+ }
+ OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits);
+}
+/**
+ * Override the window proc.
+ *
+ * @param hwnd control to override the window proc of
+ */
+static void subclass(int hwnd) {
+ Integer key = new Integer(hwnd);
+ if (oldProcMap.get(key) == null) {
+ int oldProc = OS.GetWindowLong(hwnd, OS.GWL_WNDPROC);
+ oldProcMap.put(key, new Integer(oldProc));
+ OS.SetWindowLong(hwnd, OS.GWL_WNDPROC, callback.getAddress());
+ }
+}
+/**
* Reverse the character array. Used for right orientation.
*
* @param charArray character array to reverse
@@ -571,7 +626,21 @@ static void translateOrder(int[] orderArray, int glyphCount, boolean isRightOrie
}
}
/**
- * Window proc to intercept keyboard language switch event (WS_INPUTLANGCHANGE).
+ * Remove the overridden the window proc.
+ *
+ * @param hwnd control to remove the window proc override for
+ */
+static void unsubclass(int hwnd) {
+ Integer key = new Integer(hwnd);
+ if (languageMap.get(key) == null && keyMap.get(key) == null) {
+ Integer proc = (Integer) oldProcMap.remove(key);
+ if (proc == null) return;
+ OS.SetWindowLong(hwnd, OS.GWL_WNDPROC, proc.intValue());
+ }
+}
+/**
+ * Window proc to intercept keyboard language switch event (WS_INPUTLANGCHANGE)
+ * and widget orientation changes.
* Run the Control's registered runnable when the keyboard language is switched.
*
* @param hwnd handle of the control that is listening for the keyboard language
@@ -579,13 +648,27 @@ static void translateOrder(int[] orderArray, int glyphCount, boolean isRightOrie
* @param msg window message
*/
static int windowProc (int hwnd, int msg, int wParam, int lParam) {
+ Integer key = new Integer (hwnd);
switch (msg) {
case 0x51 /*OS.WM_INPUTLANGCHANGE*/:
- Runnable runnable = (Runnable) map.get (new Integer (hwnd));
+ Runnable runnable = (Runnable) languageMap.get (key);
if (runnable != null) runnable.run ();
break;
- }
- Integer oldProc = (Integer)oldProcMap.get(new Integer(hwnd));
+ case OS.WM_KEYDOWN:
+ if (wParam == OS.VK_SHIFT) {
+ if (OS.GetKeyState (OS.VK_CONTROL) < 0) {
+ Runnable[] runnables = (Runnable[]) keyMap.get (key);
+ if (runnables == null) break;
+ if (OS.GetKeyState (0xA0 /* VK_LSHIFT */) < 0) {
+ if (runnables[0] != null) runnables[0].run ();
+ } else {
+ if (runnables[1] != null) runnables[1].run ();
+ }
+ }
+ }
+ break;
+ }
+ Integer oldProc = (Integer)oldProcMap.get(key);
return OS.CallWindowProc (oldProc.intValue(), hwnd, msg, wParam, lParam);
}