Lines 12-21
Link Here
|
12 |
package org.eclipse.jface.util; |
12 |
package org.eclipse.jface.util; |
13 |
|
13 |
|
14 |
import java.util.HashMap; |
14 |
import java.util.HashMap; |
|
|
15 |
import java.util.Locale; |
15 |
import java.util.Map; |
16 |
import java.util.Map; |
16 |
|
17 |
|
|
|
18 |
import org.eclipse.equinox.bidi.StructuredTextProcessor; |
17 |
import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory; |
19 |
import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory; |
18 |
import org.eclipse.jface.internal.InternalPolicy; |
20 |
import org.eclipse.jface.internal.InternalPolicy; |
|
|
21 |
import org.eclipse.jface.window.Window; |
19 |
import org.eclipse.swt.SWT; |
22 |
import org.eclipse.swt.SWT; |
20 |
import org.eclipse.swt.custom.BidiSegmentEvent; |
23 |
import org.eclipse.swt.custom.BidiSegmentEvent; |
21 |
import org.eclipse.swt.custom.BidiSegmentListener; |
24 |
import org.eclipse.swt.custom.BidiSegmentListener; |
Lines 90-95
Link Here
|
90 |
public static final String VISUAL_RIGHT_TO_LEFT = "visualrtl";//$NON-NLS-1$ |
93 |
public static final String VISUAL_RIGHT_TO_LEFT = "visualrtl";//$NON-NLS-1$ |
91 |
|
94 |
|
92 |
/** |
95 |
/** |
|
|
96 |
* For applying bidi processing for formatting messages. |
97 |
* |
98 |
* @see #applyBidiProcessing(PROCESSING_TYPE, Object...) |
99 |
*/ |
100 |
public enum PROCESSING_TYPE { |
101 |
/** |
102 |
* For applying bidi processing on message placeholders. |
103 |
* |
104 |
* @see #applyBidiProcessing(PROCESSING_TYPE, Object...) |
105 |
*/ |
106 |
MESSAGEWITHPLACEHOLDERS, /** |
107 |
* For applying bidi processing on |
108 |
* concatenation of strings. |
109 |
* |
110 |
* @see #applyBidiProcessing(PROCESSING_TYPE, |
111 |
* Object...) |
112 |
*/ |
113 |
CONCATENATION |
114 |
} |
115 |
|
116 |
/** |
93 |
* Segment listener for LTR Base Text Direction |
117 |
* Segment listener for LTR Base Text Direction |
94 |
*/ |
118 |
*/ |
95 |
private static final SegmentListener BASE_TEXT_DIRECTION_LTR = new BaseTextDirectionSegmentListener(LEFT_TO_RIGHT); |
119 |
private static final SegmentListener BASE_TEXT_DIRECTION_LTR = new BaseTextDirectionSegmentListener(LEFT_TO_RIGHT); |
Lines 142-147
Link Here
|
142 |
* The RLE char |
166 |
* The RLE char |
143 |
*/ |
167 |
*/ |
144 |
static final char RLE = 0x202B; |
168 |
static final char RLE = 0x202B; |
|
|
169 |
|
170 |
/** |
171 |
* The RLM char |
172 |
*/ |
173 |
static final char RLM = 0x200F; |
145 |
|
174 |
|
146 |
/** |
175 |
/** |
147 |
* The LRO char |
176 |
* The LRO char |
Lines 538-541
Link Here
|
538 |
control.setTextDirection(textDir); |
567 |
control.setTextDirection(textDir); |
539 |
} |
568 |
} |
540 |
} |
569 |
} |
541 |
} |
570 |
|
|
|
571 |
/** |
572 |
* Applies bidi processing to the given string. |
573 |
* |
574 |
* <p> |
575 |
* Possible values for <code>handlingType</code> are: |
576 |
* <ul> |
577 |
* <li>{@link BidiUtils#LEFT_TO_RIGHT}</li> |
578 |
* <li>{@link BidiUtils#RIGHT_TO_LEFT}</li> |
579 |
* <li>{@link BidiUtils#AUTO}</li> |
580 |
* <li>{@link BidiUtils#BTD_DEFAULT}</li> |
581 |
* <li>{@link BidiUtils#VISUAL_LEFT_TO_RIGHT}</li> |
582 |
* <li>{@link BidiUtils#VISUAL_RIGHT_TO_LEFT}</li> |
583 |
* <li>the <code>String</code> constants in |
584 |
* {@link StructuredTextTypeHandlerFactory}</li> |
585 |
* <li>if OSGi is running, the types that have been contributed to the |
586 |
* <code>org.eclipse.equinox.bidi.bidiTypes</code> extension point.</li> |
587 |
* </ul> |
588 |
* <p> |
589 |
* The 3 values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, and |
590 |
* {@link #AUTO} are usable whether {@link #getBidiSupport() bidi support} |
591 |
* is enabled or disabled. |
592 |
* <p> |
593 |
* The remaining values only have an effect if bidi support is enabled. |
594 |
* <p> |
595 |
* The 4 first values {@link #LEFT_TO_RIGHT}, {@link #RIGHT_TO_LEFT}, |
596 |
* {@link #AUTO}, and {@link #BTD_DEFAULT} are for Base Text Direction (BTD) |
597 |
* handling. The remaining values are for Structured Text handling. |
598 |
* <p> |
599 |
* <strong>Note:</strong> The Structured Text handling only works if the |
600 |
* <code>org.eclipse.equinox.bidi</code> bundle is on the classpath! |
601 |
* <p> |
602 |
* <strong>Note:</strong> To deprocess the string you must use |
603 |
* {@link BidiUtils#deprocessBidi(String)} for the 6 first values or |
604 |
* {@link StructuredTextProcessor#deprocessTyped(String, String)} for the |
605 |
* remaining values. |
606 |
* </p> |
607 |
* |
608 |
* @param string |
609 |
* the string |
610 |
* @param handlingType |
611 |
* the type of handling |
612 |
* @return the bidi processed string |
613 |
* @throws IllegalArgumentException |
614 |
* if <code>handlingType</code> is not a known type identifier |
615 |
*/ |
616 |
public static String applyBidiProcessing(String string, String handlingType) { |
617 |
if (LEFT_TO_RIGHT.equals(handlingType)) { |
618 |
return addUCC(string, false, handlingType); |
619 |
} else if (RIGHT_TO_LEFT.equals(handlingType)) { |
620 |
return addUCC(string, true, handlingType); |
621 |
} else if (AUTO.equals(handlingType)) { |
622 |
return addUCC(string, isRTLValue(string), handlingType); |
623 |
|
624 |
} else if (getBidiSupport()) { |
625 |
if (BTD_DEFAULT.equals(handlingType)) { |
626 |
if (LEFT_TO_RIGHT.equals(getTextDirection())) { |
627 |
return addUCC(string, false, handlingType); |
628 |
} else if (RIGHT_TO_LEFT.equals(getTextDirection())) { |
629 |
return addUCC(string, true, handlingType); |
630 |
} else if (AUTO.equals(getTextDirection())) { |
631 |
return addUCC(string, isRTLValue(string), handlingType); |
632 |
} |
633 |
} else if (VISUAL_LEFT_TO_RIGHT.equals(handlingType)) { |
634 |
return (InternalPolicy.DEBUG_BIDI_UTILS ? handlingType : "") + LRO + string + PDF; //$NON-NLS-1$ |
635 |
} else if (VISUAL_RIGHT_TO_LEFT.equals(handlingType)) { |
636 |
return (InternalPolicy.DEBUG_BIDI_UTILS ? handlingType : "") + RLO + string + PDF; //$NON-NLS-1$ |
637 |
} else { |
638 |
return StructuredTextProcessor.processTyped(string, handlingType); |
639 |
} |
640 |
} |
641 |
return string; |
642 |
} |
643 |
|
644 |
/** |
645 |
* Strips off Unicode control characters from the given string. |
646 |
* |
647 |
* |
648 |
* @param string |
649 |
* the string |
650 |
* @return the bidi deprocessed string |
651 |
*/ |
652 |
public static String deprocessBidi(String string) { |
653 |
String header1 = "" + LRM + LRE, header2 = "" + RLM + RLE; //$NON-NLS-1$ //$NON-NLS-2$ |
654 |
String tailer1 = "" + LRM + PDF, tailer2 = "" + RLM + PDF; //$NON-NLS-1$ //$NON-NLS-2$ |
655 |
|
656 |
if (InternalPolicy.DEBUG_BIDI_UTILS) { |
657 |
string = string.replaceFirst(LEFT_TO_RIGHT, "").replaceFirst(RIGHT_TO_LEFT, "").replaceFirst(AUTO, "") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
658 |
.replaceFirst(BTD_DEFAULT, "").replaceFirst(VISUAL_LEFT_TO_RIGHT, "") //$NON-NLS-1$ //$NON-NLS-2$ |
659 |
.replaceFirst(VISUAL_RIGHT_TO_LEFT, ""); //$NON-NLS-1$ |
660 |
} |
661 |
if ((string.startsWith(header1) && string.endsWith(tailer1)) |
662 |
|| (string.startsWith(header2) && string.endsWith(tailer2))) { |
663 |
return string.substring(2, string.length() - 2); |
664 |
} else if ((string.charAt(0) == LRO || string.charAt(0) == RLO) && string.charAt(string.length() - 1) == PDF) { |
665 |
return string.substring(1, string.length() - 1); |
666 |
} |
667 |
return string; |
668 |
} |
669 |
|
670 |
/** |
671 |
* Applies bidi processing for formatting messages. <strong>Note:</strong> |
672 |
* The number of arguments in <code>params</code> should always be even and |
673 |
* greater than 0. Each pair is composed of the string to bidi process and |
674 |
* the type of handling as specified in |
675 |
* {@link #applyBidiProcessing(Text, String)}. If the number of arguments is |
676 |
* odd no bidi processing will occur. |
677 |
* </p> |
678 |
* |
679 |
* @param typeOfContext |
680 |
* message with placeholders or concatenation ? |
681 |
* @param params |
682 |
* unlimited number of arguments associated with either |
683 |
* placeholders or concatenated strings. It is always even number |
684 |
* since for each placeholder / piece of text, we need to specify |
685 |
* which type of handling is required (i.e. text direction |
686 |
* enforcement, structured text, no handling). |
687 |
* @return the bidi processed placeholders or the concatenated string. |
688 |
*/ |
689 |
public static Object[] applyBidiProcessing(PROCESSING_TYPE typeOfContext, Object... params) { |
690 |
if (typeOfContext == PROCESSING_TYPE.MESSAGEWITHPLACEHOLDERS) { |
691 |
char prefix = isBidiLocale() ? RLM : LRM; |
692 |
return applyBidiProcessing(prefix, params); |
693 |
} else if (typeOfContext == PROCESSING_TYPE.CONCATENATION) { |
694 |
char prefix = Window.getDefaultOrientation() == SWT.RIGHT_TO_LEFT ? RLM : LRM; |
695 |
Object[] results = applyBidiProcessing(prefix, params); |
696 |
StringBuffer sb = new StringBuffer(); |
697 |
for (int i = 0; i < results.length; i++) { |
698 |
sb.append(results[i]); |
699 |
} |
700 |
String[] result = new String[1]; |
701 |
result[0] = sb.toString(); |
702 |
return result; |
703 |
} |
704 |
return params; |
705 |
} |
706 |
|
707 |
private static Object[] applyBidiProcessing(char prefix, Object... params) { |
708 |
|
709 |
if (params.length == 0 || params.length % 2 == 1) { |
710 |
return params; |
711 |
} |
712 |
int numPlaceHolders = params.length / 2; |
713 |
Object[] results = new Object[numPlaceHolders]; |
714 |
for (int i = 0; i < numPlaceHolders; i++) { |
715 |
results[i] = prefix + applyBidiProcessing(params[2 * i].toString(), params[2 * i + 1].toString()); |
716 |
} |
717 |
return results; |
718 |
} |
719 |
|
720 |
private static String addUCC(String string, boolean isRTL, String handlingType) { |
721 |
StringBuffer sb = new StringBuffer(); |
722 |
if (InternalPolicy.DEBUG_BIDI_UTILS) { |
723 |
sb.append(handlingType); |
724 |
} |
725 |
if (isRTL) { |
726 |
sb.append(RLM).append(RLE); |
727 |
} else { |
728 |
sb.append(LRM).append(LRE); |
729 |
} |
730 |
sb.append(string); |
731 |
if (isRTL) { |
732 |
sb.append(RLM); |
733 |
} else { |
734 |
sb.append(LRM); |
735 |
} |
736 |
sb.append(PDF); |
737 |
return sb.toString(); |
738 |
} |
739 |
|
740 |
private static boolean isRTLValue(String stringValue) { |
741 |
for (int i = 0; i < stringValue.length(); i++) { |
742 |
if (Character.getDirectionality(stringValue.charAt(i)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT |
743 |
|| Character |
744 |
.getDirectionality(stringValue.charAt(i)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC |
745 |
|| Character.getDirectionality(stringValue.charAt(i)) == Character.DIRECTIONALITY_ARABIC_NUMBER) |
746 |
return true; |
747 |
else if (Character.getDirectionality(stringValue.charAt(i)) == Character.DIRECTIONALITY_LEFT_TO_RIGHT) { |
748 |
return false; |
749 |
} |
750 |
} |
751 |
return false; |
752 |
} |
753 |
|
754 |
private static boolean isBidiLocale() { |
755 |
Locale defaultLocale = Locale.getDefault(); |
756 |
String language = defaultLocale.getLanguage(); |
757 |
boolean isBidi = "iw".equals(language) || //$NON-NLS-1$ |
758 |
"he".equals(language) || //$NON-NLS-1$ |
759 |
"ar".equals(language) || //$NON-NLS-1$ |
760 |
"fa".equals(language) || //$NON-NLS-1$ |
761 |
"ur".equals(language); //$NON-NLS-1$ |
762 |
return isBidi; |
763 |
} |
764 |
|
765 |
} |