All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jface.util.BidiUtils Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2012, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 ******************************************************************************/

package org.eclipse.jface.util;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory;
import org.eclipse.jface.internal.InternalPolicy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SegmentListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;

/**
 * This class provides API to handle Base Text Direction (BTD) and
 * Structured Text support for SWT Text widgets.
 *
 * @since 3.9
 */
public final class BidiUtils {

	/**
	 * Left-To-Right Base Text Direction.
	 * @see #getTextDirection()
	 */
	public static final String LEFT_TO_RIGHT = "ltr"; //$NON-NLS-1$

	/**
	 * Right-To-Left Base Text Direction.
	 * @see #getTextDirection()
	 */
	public static final String RIGHT_TO_LEFT = "rtl";//$NON-NLS-1$

	/**
	 * Auto (contextual) Base Text Direction.
	 * @see #getTextDirection()
	 */
	public static final String AUTO = "auto";//$NON-NLS-1$

	/**
	 * Base Text Direction defined in {@link BidiUtils#getTextDirection()}
	 * @see #getSegmentListener(String)
	 * @see #applyBidiProcessing(Text, String)
	 */
	public static final String BTD_DEFAULT = "default";//$NON-NLS-1$

	/**
	 * Visual Left-To-Right Text Direction.
	 * 

* Note: This handling type is deprecated and should only be used * when interfacing with legacy systems that store data in visual order. * * @see http://www.w3.org/International/questions/qa-visual-vs-logical * @see #getSegmentListener(String) * @see #applyBidiProcessing(Text, String) * * @since 3.11 */ public static final String VISUAL_LEFT_TO_RIGHT = "visualltr"; //$NON-NLS-1$ /** * Visual Right-To-Left Text Direction *

* Note: This handling type is deprecated and should only be used * when interfacing with legacy systems that store data in visual order. * * @see http://www.w3.org/International/questions/qa-visual-vs-logical * @see #getSegmentListener(String) * @see #applyBidiProcessing(Text, String) * * @since 3.11 */ public static final String VISUAL_RIGHT_TO_LEFT = "visualrtl";//$NON-NLS-1$ /** * Segment listener for LTR Base Text Direction */ private static final SegmentListener BASE_TEXT_DIRECTION_LTR = new BaseTextDirectionSegmentListener(LEFT_TO_RIGHT); /** * Segment listener for RTL Base Text Direction */ private static final SegmentListener BASE_TEXT_DIRECTION_RTL = new BaseTextDirectionSegmentListener(RIGHT_TO_LEFT); /** * Segment listener for Auto (Contextual) Base Text Direction */ private static final SegmentListener BASE_TEXT_DIRECTION_AUTO = new BaseTextDirectionSegmentListener(AUTO); /** * Segment listener for LTR Visual Text Direction */ private static final SegmentListener VISUAL_TEXT_DIRECTION_LTR = new VisualTextDirectionSegmentListener( VISUAL_LEFT_TO_RIGHT); /** * Segment listener for RTL Visual Text Direction */ private static final SegmentListener VISUAL_TEXT_DIRECTION_RTL = new VisualTextDirectionSegmentListener( VISUAL_RIGHT_TO_LEFT); /** * Listener cache. Map from structured text type id ({@link String}) to * structured text segment listener ({@link SegmentListener}). */ private static final Map structuredTextSegmentListeners = new HashMap<>(); /** * The LRE char */ static final char LRE = 0x202A; /** * The LRM char */ static final char LRM = 0x200E; /** * The PDF char */ static final char PDF = 0x202C; /** * The RLE char */ static final char RLE = 0x202B; /** * The LRO char */ static final char LRO = 0x202D; /** * The RLO char */ static final char RLO = 0x202E; private static boolean bidiSupport = false; private static String textDirection = "";//$NON-NLS-1$ private BidiUtils() { // no instances } /** * Returns the Base Text Direction. Possible values are: *

    *
  • {@link BidiUtils#LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#RIGHT_TO_LEFT}
  • *
  • {@link BidiUtils#AUTO}
  • *
  • null (no direction set)
  • *
* * @return the base text direction */ public static String getTextDirection() { return textDirection; } /** * Sets the Base Text Direction. Possible values are: *
    *
  • {@link BidiUtils#LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#RIGHT_TO_LEFT}
  • *
  • {@link BidiUtils#AUTO}
  • *
  • null (no default direction)
  • *
* * @param direction the text direction to set * @throws IllegalArgumentException if direction is not legal */ public static void setTextDirection(String direction) { if (direction == null || LEFT_TO_RIGHT.equals(direction) || RIGHT_TO_LEFT.equals(direction) || AUTO.equals(direction)) { textDirection = direction; } else { throw new IllegalArgumentException(direction); } } /** * Returns whether bidi support is enabled. * * @return true iff bidi support is enabled */ public static boolean getBidiSupport() { return bidiSupport; } /** * Enables or disables bidi support. * * @param bidi true to enable bidi support, false to disable */ public static void setBidiSupport(boolean bidi) { bidiSupport = bidi; } /** * Applies bidi processing to the given text field. * *

* Possible values for handlingType are: *

    *
  • {@link BidiUtils#LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#RIGHT_TO_LEFT}
  • *
  • {@link BidiUtils#AUTO}
  • *
  • {@link BidiUtils#BTD_DEFAULT}
  • *
  • {@link BidiUtils#VISUAL_LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#VISUAL_RIGHT_TO_LEFT}
  • *
  • the String constants in * {@link StructuredTextTypeHandlerFactory}
  • *
  • if OSGi is running, the types that have been contributed to the * org.eclipse.equinox.bidi.bidiTypes extension point.
  • *
*

* The 3 values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, and * {@link #AUTO} are usable whether {@link #getBidiSupport() bidi support} * is enabled or disabled. *

* The remaining values only have an effect if bidi support is enabled. *

* The 4 first values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, * {@link #AUTO}, and {@link #BTD_DEFAULT} are for Base Text Direction (BTD) * handling. The remaining values are for Structured Text handling. *

* Note: If this method is called on a text control, then * {@link #applyTextDirection(Control, String)} must not be called on the * same control. *

* Note: The Structured Text handling only works if the * org.eclipse.equinox.bidi bundle is on the classpath! *

* *

* Note: * {@link org.eclipse.swt.widgets.Text#addSegmentListener(SegmentListener)} * is currently only implemented on Windows and GTK, so this method won't * have an effect on Cocoa. * * @param field * the text field * @param handlingType * the type of handling * @throws IllegalArgumentException * if handlingType is not a known type identifier */ public static void applyBidiProcessing(Text field, String handlingType) { SegmentListener listener = getSegmentListener(handlingType); if (listener != null) { field.addSegmentListener(listener); if (InternalPolicy.DEBUG_BIDI_UTILS) { int color = 0; if (LEFT_TO_RIGHT.equals(handlingType)) { color = SWT.COLOR_RED; } else if (RIGHT_TO_LEFT.equals(handlingType)) { color = SWT.COLOR_GREEN; } else if (BTD_DEFAULT.equals(handlingType)) { color = SWT.COLOR_YELLOW; } else if (AUTO.equals(handlingType)) { color = SWT.COLOR_MAGENTA; } else { color = SWT.COLOR_CYAN; } field.setBackground(field.getDisplay().getSystemColor(color)); if (field.getMessage().isEmpty()) { field.setMessage('<' + handlingType + '>'); } if (field.getToolTipText() == null) { field.setToolTipText('<' + handlingType + '>'); } } } } /** * Applies bidi processing to the given styled text field. * *

* Possible values for handlingType are: *

    *
  • {@link BidiUtils#LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#RIGHT_TO_LEFT}
  • *
  • {@link BidiUtils#AUTO}
  • *
  • {@link BidiUtils#BTD_DEFAULT}
  • *
  • {@link BidiUtils#VISUAL_LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#VISUAL_RIGHT_TO_LEFT}
  • *
  • the String constants in * {@link StructuredTextTypeHandlerFactory}
  • *
  • if OSGi is running, the types that have been contributed to the * org.eclipse.equinox.bidi.bidiTypes extension point.
  • *
*

* The 3 values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, and * {@link #AUTO} are usable whether {@link #getBidiSupport() bidi support} * is enabled or disabled. *

* The remaining values only have an effect if bidi support is enabled. *

* The 4 first values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, * {@link #AUTO}, and {@link #BTD_DEFAULT} are for Base Text Direction (BTD) * handling. The remaining values are for Structured Text handling. *

* Note: If this method is called on a text control, then * {@link #applyTextDirection(Control, String)} must not be called on the * same control. *

* Note: The Structured Text handling only works if the * org.eclipse.equinox.bidi bundle is on the classpath! *

* * @param field * the styled text field * @param handlingType * the type of handling * @throws IllegalArgumentException * if handlingType is not a known type identifier */ public static void applyBidiProcessing(StyledText field, String handlingType) { final SegmentListener listener = getSegmentListener(handlingType); if (listener != null) { field.addBidiSegmentListener(listener::getSegments); } } /** * Applies bidi processing to the given combo. * *

* Possible values for handlingType are: *

    *
  • {@link BidiUtils#LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#RIGHT_TO_LEFT}
  • *
  • {@link BidiUtils#AUTO}
  • *
  • {@link BidiUtils#BTD_DEFAULT}
  • *
  • {@link BidiUtils#VISUAL_LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#VISUAL_RIGHT_TO_LEFT}
  • *
  • the String constants in * {@link StructuredTextTypeHandlerFactory}
  • *
  • if OSGi is running, the types that have been contributed to the * org.eclipse.equinox.bidi.bidiTypes extension point.
  • *
*

* The 3 values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, and * {@link #AUTO} are usable whether {@link #getBidiSupport() bidi support} * is enabled or disabled. *

* The remaining values only have an effect if bidi support is enabled. *

* The 4 first values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, * {@link #AUTO}, and {@link #BTD_DEFAULT} are for Base Text Direction (BTD) * handling. The remaining values are for Structured Text handling. *

* Note: If this method is called on a combo control, then * {@link #applyTextDirection(Control, String)} must not be called on the * same control. *

* Note: The Structured Text handling only works if the * org.eclipse.equinox.bidi bundle is on the classpath! *

* *

* Note: * {@link org.eclipse.swt.widgets.Combo#addSegmentListener(SegmentListener)} * is currently only implemented on Windows so this method won't have an * effect on Cocoa and GTK. * * @param combo * the combo field * @param handlingType * the type of handling * @throws IllegalArgumentException * if handlingType is not a known type identifier * @since 3.10 */ public static void applyBidiProcessing(Combo combo, String handlingType) { SegmentListener listener = getSegmentListener(handlingType); if (listener != null) { combo.addSegmentListener(listener); if (InternalPolicy.DEBUG_BIDI_UTILS) { int color = 0; if (LEFT_TO_RIGHT.equals(handlingType)) { color = SWT.COLOR_RED; } else if (RIGHT_TO_LEFT.equals(handlingType)) { color = SWT.COLOR_GREEN; } else if (BTD_DEFAULT.equals(handlingType)) { color = SWT.COLOR_YELLOW; } else if (AUTO.equals(handlingType)) { color = SWT.COLOR_MAGENTA; } else { color = SWT.COLOR_CYAN; } combo.setBackground(combo.getDisplay().getSystemColor(color)); if (combo.getToolTipText() == null) { combo.setToolTipText('<' + handlingType + '>'); } } } } /** * Returns a segment listener for the given handlingType that * can e.g. be passed to {@link Text#addSegmentListener(SegmentListener)}. * *

* Note: The Structured Text handling only works if the * org.eclipse.equinox.bidi bundle is on the classpath! *

* * @param handlingType * the handling type as specified in * {@link #applyBidiProcessing(Text, String)} * @return the segment listener, or null if no handling is * required * @throws IllegalArgumentException * if handlingType is not a known type identifier * @see #applyBidiProcessing(Text, String) */ public static SegmentListener getSegmentListener(String handlingType) { SegmentListener listener = null; if (LEFT_TO_RIGHT.equals(handlingType)) { listener = BASE_TEXT_DIRECTION_LTR; } else if (RIGHT_TO_LEFT.equals(handlingType)) { listener = BASE_TEXT_DIRECTION_RTL; } else if (AUTO.equals(handlingType)) { listener = BASE_TEXT_DIRECTION_AUTO; } else if (getBidiSupport()) { if (BTD_DEFAULT.equals(handlingType)) { if (LEFT_TO_RIGHT.equals(getTextDirection())) { listener = BASE_TEXT_DIRECTION_LTR; } else if (RIGHT_TO_LEFT.equals(getTextDirection())) { listener = BASE_TEXT_DIRECTION_RTL; } else if (AUTO.equals(getTextDirection())) { listener = BASE_TEXT_DIRECTION_AUTO; } } else if (VISUAL_LEFT_TO_RIGHT.equals(handlingType)) { listener = VISUAL_TEXT_DIRECTION_LTR; } else if (VISUAL_RIGHT_TO_LEFT.equals(handlingType)) { listener = VISUAL_TEXT_DIRECTION_RTL; } else { Object handler = structuredTextSegmentListeners.get(handlingType); if (handler != null) { listener = (SegmentListener) handler; } else { listener = new StructuredTextSegmentListener(handlingType); structuredTextSegmentListeners.put(handlingType, listener); } } } return listener; } /** * Applies a Base Text Direction to the given control (and its descendants, if * it's a {@link Composite}). * *

* Possible values for textDirection are: *

*
    *
  • {@link BidiUtils#LEFT_TO_RIGHT}
  • *
  • {@link BidiUtils#RIGHT_TO_LEFT}
  • *
  • {@link BidiUtils#AUTO}
  • *
  • {@link BidiUtils#BTD_DEFAULT}
  • *
*

* The 3 values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, and * {@link BidiUtils#AUTO} are usable whether {@link #getBidiSupport() bidi * support} is enabled or disabled. *

*

* The remaining value {@link BidiUtils#BTD_DEFAULT} only has an effect if bidi * support is enabled. *

* *

* Note: If this method is called on a control, then no * applyBidiProcessing method must be called on the same control. *

*

* Note: * {@link org.eclipse.swt.widgets.Control#setTextDirection(int)} is currently * only implemented on Windows, so the direction won't be inherited by * descendants on GTK and Cocoa. *

* * @param control the control * @param textDirection the text direction */ public static void applyTextDirection(Control control, String textDirection) { int textDir = 0; if (LEFT_TO_RIGHT.equals(textDirection)) { textDir = SWT.LEFT_TO_RIGHT; } else if (RIGHT_TO_LEFT.equals(textDirection)) { textDir = SWT.RIGHT_TO_LEFT; } else if (AUTO.equals(textDirection)) { textDir = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; } else if (getBidiSupport() && BTD_DEFAULT.equals(textDirection)) { if (LEFT_TO_RIGHT.equals(getTextDirection())) { textDir = SWT.LEFT_TO_RIGHT; } else if (RIGHT_TO_LEFT.equals(getTextDirection())) { textDir = SWT.RIGHT_TO_LEFT; } else if (AUTO.equals(getTextDirection())) { textDir = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; } } if (control instanceof Text && textDir != 0) { applyBidiProcessing((Text) control, textDirection); } else if (control instanceof StyledText && textDir != 0) { applyBidiProcessing((StyledText) control, textDirection); } else if (control instanceof Combo && textDir != 0) { applyBidiProcessing((Combo) control, textDirection); } else if (textDir != 0) { control.setTextDirection(textDir); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy