1919
2020import org .eclipse .jface .fieldassist .ControlDecoration ;
2121import org .eclipse .jface .fieldassist .FieldDecorationRegistry ;
22+ import org .eclipse .swt .graphics .GC ;
2223import org .eclipse .swt .graphics .Image ;
2324
2425/**
@@ -41,11 +42,10 @@ private SearchDecoration() {
4142 * the validation.
4243 */
4344 public static boolean validateRegex (String regex , ControlDecoration targetDecoration ) {
44- String errorMessage = getValidationError (regex );
45+ String errorMessage = getValidationError (regex , targetDecoration . getControl () );
4546 if (errorMessage .isEmpty ()) {
4647 targetDecoration .hide ();
4748 return true ;
48-
4949 }
5050
5151 Image decorationImage = FieldDecorationRegistry .getDefault ()
@@ -62,21 +62,56 @@ public static boolean validateRegex(String regex, ControlDecoration targetDecora
6262 * @return The appropriate error message if the regex is invalid or an empty
6363 * string if the regex is valid.
6464 */
65- private static String getValidationError (String regex ) {
65+ private static String getValidationError (String regex , org .eclipse .swt .widgets .Control targetControl ) {
66+ // GC gc = new GC(targetControl);
67+
6668 try {
6769 Pattern .compile (regex );
6870 return "" ; //$NON-NLS-1$
71+
6972 } catch (PatternSyntaxException e ) {
70- String message = e .getLocalizedMessage ();
73+ return buildValidationErrorString (e , targetControl );
74+ }
75+ }
76+
77+ private static String buildValidationErrorString (PatternSyntaxException e , org .eclipse .swt .widgets .Control targetControl ) {
78+ GC gc = new GC (targetControl );
79+
80+ String description = e .getDescription ();
81+ int errorIndex = e .getIndex ();
82+ String pattern = e .getPattern ();
83+
84+ if (errorIndex == -1 ) {
85+ return description ;
86+ }
87+ StringBuilder sBuilder = new StringBuilder ();
88+
89+ sBuilder .append (description );
90+ sBuilder .append (" at index " ).append (errorIndex ).append (System .lineSeparator ()); //$NON-NLS-1$
91+ sBuilder .append (pattern ).append (System .lineSeparator ());
92+
93+ String stringToIndexString = pattern .substring (0 , errorIndex + 1 );
94+ String buildString = "" ; //$NON-NLS-1$
95+ String hairSpace = "\u200A " ; //$NON-NLS-1$
96+
97+ int stringToIndex = gc .stringExtent (stringToIndexString ).x ;
98+ String lastCharacter = stringToIndexString .substring (stringToIndexString .length () - 1 );
7199
72- // Only preserve the first line of the original error message.
73- int i = 0 ;
74- while (i < message .length () && "\n \r " .indexOf (message .charAt (i )) == -1 ) { //$NON-NLS-1$
75- i ++;
76- }
100+ int widthLastChar = gc .stringExtent (lastCharacter ).x ;
101+ int upWidth = gc .stringExtent ("^" ).x ; //$NON-NLS-1$
77102
78- return message .substring (0 , i );
103+ double howFar = stringToIndex - widthLastChar / 2 - upWidth / 2 ;
104+
105+ while (gc .stringExtent (buildString ).x < howFar ) {
106+ buildString += hairSpace ; // $NON-NLS-1$
79107 }
108+ sBuilder .append (buildString );
109+
110+ sBuilder .append ("^" ); //$NON-NLS-1$
111+ gc .dispose ();
112+
113+ return sBuilder .toString ();
80114 }
81115
116+
82117}
0 commit comments