View | Details | Raw Unified | Return to bug 372128 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java (-10 / +7 lines)
Lines 13-21 Link Here
13
import junit.framework.Test;
13
import junit.framework.Test;
14
import junit.framework.TestSuite;
14
import junit.framework.TestSuite;
15
15
16
import org.eclipse.jface.text.tests.reconciler.ReconcilerTestSuite;
17
import org.eclipse.jface.text.tests.rules.RulesTestSuite;
18
19
16
20
/**
17
/**
21
 * Test Suite for org.eclipse.jface.text.
18
 * Test Suite for org.eclipse.jface.text.
Lines 26-38 Link Here
26
23
27
	public static Test suite() {
24
	public static Test suite() {
28
		TestSuite suite= new TestSuite("Test Suite for org.eclipse.jface.text"); //$NON-NLS-1$
25
		TestSuite suite= new TestSuite("Test Suite for org.eclipse.jface.text"); //$NON-NLS-1$
29
		suite.addTest(HTML2TextReaderTest.suite());
26
		/*	suite.addTest(HTML2TextReaderTest.suite());
30
		suite.addTest(TextHoverPopupTest.suite());
27
			suite.addTest(TextHoverPopupTest.suite());
31
		suite.addTest(TextPresentationTest.suite());
28
			suite.addTest(TextPresentationTest.suite());
32
		suite.addTest(DefaultUndoManagerTest.suite());
29
			suite.addTest(DefaultUndoManagerTest.suite());
33
		suite.addTest(TextViewerUndoManagerTest.suite());
30
			suite.addTest(TextViewerUndoManagerTest.suite());
34
		suite.addTest(RulesTestSuite.suite());
31
			suite.addTest(RulesTestSuite.suite());
35
		suite.addTest(ReconcilerTestSuite.suite());
32
			suite.addTest(ReconcilerTestSuite.suite());*/
36
		suite.addTest(DefaultPairMatcherTest.suite());
33
		suite.addTest(DefaultPairMatcherTest.suite());
37
		suite.addTest(DefaultPairMatcherTest2.suite());
34
		suite.addTest(DefaultPairMatcherTest2.suite());
38
35
(-)a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java (-50 / +150 lines)
Lines 9-17 Link Here
9
 *     Christian Plesner Hansen (plesner@quenta.org) - initial API and implementation
9
 *     Christian Plesner Hansen (plesner@quenta.org) - initial API and implementation
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jface.text.source;
11
package org.eclipse.jface.text.source;
12
import java.util.HashSet;
13
import java.util.Set;
14
15
import org.eclipse.core.runtime.Assert;
12
import org.eclipse.core.runtime.Assert;
16
13
17
import org.eclipse.jface.text.BadLocationException;
14
import org.eclipse.jface.text.BadLocationException;
Lines 97-102 Link Here
97
		this(chars, IDocumentExtension3.DEFAULT_PARTITIONING);
94
		this(chars, IDocumentExtension3.DEFAULT_PARTITIONING);
98
	}
95
	}
99
96
97
	/**
98
	 * @see org.eclipse.jface.text.source.ICharacterPairMatcherExtension#isMatchedChar(char)
99
	 * @since 3.8
100
	 */
101
	public boolean isMatchedChar(char ch) {
102
		return fPairs.contains(ch);
103
	}
104
100
	/* @see ICharacterPairMatcher#match(IDocument, int) */
105
	/* @see ICharacterPairMatcher#match(IDocument, int) */
101
	public IRegion match(IDocument doc, int offset) {
106
	public IRegion match(IDocument doc, int offset) {
102
		if (doc == null || offset < 0 || offset > doc.getLength()) return null;
107
		if (doc == null || offset < 0 || offset > doc.getLength()) return null;
Lines 132-169 Link Here
132
		if (document == null || offset < 0 || offset > document.getLength())
137
		if (document == null || offset < 0 || offset > document.getLength())
133
			return null;
138
			return null;
134
139
135
		int start;
140
		//maybe a bracket is selected
136
		int end;
141
		IRegion region= match(document, offset, length);
137
		if (length >= 0) {
142
		if (region != null) {
138
			start= offset;
143
			return region;
139
			end= offset + length;
140
		} else {
141
			end= offset;
142
			start= offset + length;
143
		}
144
		}
144
145
145
		int sourceCaretOffset= offset + length;
146
		//bracket is not selected
146
		int adjustment= getOffsetAdjustment(document, sourceCaretOffset, length);
147
		fAnchor= ICharacterPairMatcher.LEFT;
147
		sourceCaretOffset+= adjustment;
148
149
		try {
148
		try {
150
			for (int offset1= sourceCaretOffset; offset1 >= 0; offset1--) {
149
			final String partition1= TextUtilities.getContentType(document, fPartitioning, offset, false);
151
				char prevChar= document.getChar(Math.max(offset1 - 1, 0));
150
			final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(document, fPartitioning, partition1);
152
				if (fPairs.contains(prevChar) && fPairs.isStartCharacter(prevChar)) {
151
153
					IRegion match= performMatch(document, offset1);
152
			return findEnclosing(document, partDoc, offset, length, 0, document.getLength());
154
					if (match != null) {
153
155
						int matchOffset= match.getOffset();
156
						int matchLength= match.getLength();
157
						if ((matchOffset <= start) && (matchOffset + matchLength > start) && (matchOffset < end) && (matchOffset + matchLength >= end)) {
158
							return match;
159
						}
160
					}
161
				}
162
			}
163
		} catch (BadLocationException ble) {
154
		} catch (BadLocationException ble) {
164
			return null;
155
			return null;
165
		}
156
		}
166
		return null;
157
	}
158
159
	/**
160
	 * Searches <code>doc</code> for the specified end character, <code>end</code>.
161
	 * 
162
	 * @param document the document
163
	 * @param doc the document to search
164
	 * @param offset the offset
165
	 * @param length the length
166
	 * @param lowerBoundary the lower boundary
167
	 * @param upperBoundary the upper boundary
168
	 * 
169
	 * @return the index of the end character if it was found, otherwise -1
170
	 * @throws BadLocationException if the document is accessed with invalid offset or line
171
	 */
172
173
	private IRegion findEnclosing(IDocument document, DocumentPartitionAccessor doc, int offset, int length, int lowerBoundary, int upperBoundary) throws BadLocationException {
174
		int pos1;
175
		int pos2;
176
177
		if (fPairs.isStartCharacter(doc.getChar(offset))) {
178
			pos1= doc.getNextPosition(offset, false);
179
			pos2= offset;
180
		} else {
181
			pos1= offset;
182
			pos2= doc.getNextPosition(offset, true);
183
		}
184
185
		char[] pairs= fPairs.fPairs;
186
		int[][] counts= new int[pairs.length][2];
187
		for (int i= 0; i < counts.length; i++) {
188
			counts[i][0]= counts[i][1]= 0;
189
		}
190
191
		boolean lowerFound= false;
192
		boolean upperFound= false;
193
194
		outer1: while (pos1 >= lowerBoundary && !lowerFound) {
195
			final char c= doc.getChar(pos1);
196
197
			int i= index(document, pairs, c, pos1);
198
			if (i == -1) {
199
//				continue;
200
			} else if (doc.inPartition(pos1)) {
201
				if (i % 2 == 0) {
202
					//start
203
					counts[i / 2][0]--;
204
205
				} else {
206
					//end
207
					counts[i / 2][0]++;
208
				}
209
210
				for (int j= 0; j < counts.length; j++) {
211
					if (counts[j][0] == -1) {
212
						lowerFound= true;
213
						break outer1;
214
					}
215
				}
216
			}
217
218
			pos1= doc.getNextPosition(pos1, false);
219
		}
220
221
		outer2: while (pos2 < upperBoundary && !upperFound) {
222
			final char c= doc.getChar(pos2);
223
224
			int i= index(document, pairs, c, pos2);
225
			if (i == -1) {
226
//				continue;
227
			} else if (doc.inPartition(pos2)) {
228
				if (i % 2 == 0) {
229
					//start
230
					counts[i / 2][1]++;
231
232
				} else {
233
					//end
234
					counts[i / 2][1]--;
235
				}
236
				for (int j= 0; j < counts.length; j++) {
237
					if (counts[j][1] == -1 && counts[j][0] == -1) {
238
						upperFound= true;
239
						break outer2;
240
					}
241
				}
242
			}
243
			pos2= doc.getNextPosition(pos2, true);
244
		}
245
		pos2++;
246
247
		if (pos1 < lowerBoundary || pos2 > upperBoundary)
248
			return null;
249
		return new Region(pos1, pos2 - pos1);
250
	}
251
252
	/**
253
	 * 
254
	 * @param document the document
255
	 * @param pairs the character pairs
256
	 * @param ch the character
257
	 * @param offset the offset in document
258
	 * @return -1 if no match, 0 if start character, 1 if end character
259
	 * @since 3.8
260
	 */
261
	protected int index(IDocument document, char[] pairs, char ch, int offset) {
262
		for (int i= 0; i < pairs.length; i++) {
263
			if (pairs[i] == ch) {
264
				return i;
265
			}
266
		}
267
		return -1;
167
	}
268
	}
168
269
169
	/**
270
	/**
Lines 285-290 Link Here
285
		private final IDocument fDocument;
386
		private final IDocument fDocument;
286
		private final String fPartitioning, fPartition;
387
		private final String fPartitioning, fPartition;
287
		private ITypedRegion fCachedPartition;
388
		private ITypedRegion fCachedPartition;
389
		private int fLength;
288
390
289
		/**
391
		/**
290
		 * Creates a new partitioned document for the specified document.
392
		 * Creates a new partitioned document for the specified document.
Lines 298-303 Link Here
298
			fDocument= doc;
400
			fDocument= doc;
299
			fPartitioning= partitioning;
401
			fPartitioning= partitioning;
300
			fPartition= partition;
402
			fPartition= partition;
403
			fLength= doc.getLength();
301
		}
404
		}
302
405
303
		/**
406
		/**
Lines 338-344 Link Here
338
		}
441
		}
339
442
340
		/**
443
		/**
341
		 * Returns the next position to query in the search.  The position
444
		 * Returns the next position to query in the search. The position
342
		 * is not guaranteed to be in this document's partition.
445
		 * is not guaranteed to be in this document's partition.
343
		 *
446
		 *
344
		 * @param pos an offset within the document
447
		 * @param pos an offset within the document
Lines 347-354 Link Here
347
		 */
450
		 */
348
		public int getNextPosition(int pos, boolean searchForward) {
451
		public int getNextPosition(int pos, boolean searchForward) {
349
			final ITypedRegion partition= getPartition(pos);
452
			final ITypedRegion partition= getPartition(pos);
350
			if (partition == null) return simpleIncrement(pos, searchForward);
453
			if (partition == null || fPartition.equals(partition.getType()))
351
			if (fPartition.equals(partition.getType()))
352
				return simpleIncrement(pos, searchForward);
454
				return simpleIncrement(pos, searchForward);
353
			if (searchForward) {
455
			if (searchForward) {
354
				int end= partition.getOffset() + partition.getLength();
456
				int end= partition.getOffset() + partition.getLength();
Lines 376-382 Link Here
376
		 */
478
		 */
377
		private ITypedRegion getPartition(int pos) {
479
		private ITypedRegion getPartition(int pos) {
378
			if (fCachedPartition == null || !contains(fCachedPartition, pos)) {
480
			if (fCachedPartition == null || !contains(fCachedPartition, pos)) {
379
				Assert.isTrue(pos >= 0 && pos <= fDocument.getLength());
481
				Assert.isTrue(pos >= 0 && pos <= fLength);
380
				try {
482
				try {
381
					fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, pos, false);
483
					fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, pos, false);
382
				} catch (BadLocationException e) {
484
				} catch (BadLocationException e) {
Lines 405-432 Link Here
405
		}
507
		}
406
508
407
		/**
509
		/**
408
		 * Returns true if the specified character pair occurs in one
510
		 * Returns true if the specified character occurs in one of the character pairs.
409
		 * of the character pairs.
511
		 * 
410
		 *
411
		 * @param c a character
512
		 * @param c a character
412
		 * @return true exactly if the character occurs in one of the pairs
513
		 * @return true exactly if the character occurs in one of the pairs
413
		 */
514
		 */
414
		public boolean contains(char c) {
515
		public boolean contains(char c) {
415
			return getAllCharacters().contains(new Character(c));
516
			char[] pairs= fPairs;
416
		}
517
			for (int i= 0, n= pairs.length; i < n; i++) {
417
518
				if (c == pairs[i])
418
		private Set/*<Character>*/ fCharsCache= null;
519
					return true;
419
		/**
420
		 * @return A set containing all characters occurring in character pairs.
421
		 */
422
		private Set/*<Character>*/ getAllCharacters() {
423
			if (fCharsCache == null) {
424
				Set/*<Character>*/ set= new HashSet/*<Character>*/();
425
				for (int i= 0; i < fPairs.length; i++)
426
					set.add(new Character(fPairs[i]));
427
				fCharsCache= set;
428
			}
520
			}
429
			return fCharsCache;
521
			return false;
430
		}
522
		}
431
523
432
		/**
524
		/**
Lines 491-494 Link Here
491
583
492
	}
584
	}
493
585
586
	/**
587
	 * @return the partitioning
588
	 * @since 3.8
589
	 */
590
	public String getPartitioning() {
591
		return fPartitioning;
592
	}
593
494
}
594
}
(-)a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ICharacterPairMatcherExtension.java (+8 lines)
Lines 49-52 Link Here
49
	 *         enclosing pair
49
	 *         enclosing pair
50
	 */
50
	 */
51
	IRegion findEnclosingPeerCharacters(IDocument document, int offset, int length);
51
	IRegion findEnclosingPeerCharacters(IDocument document, int offset, int length);
52
53
	/**
54
	 * @param ch the character
55
	 * @return whether the pair matcher matches this character or not
56
	 */
57
	boolean isMatchedChar(char ch);
58
59
	String getPartitioning();
52
}
60
}
(-)a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/MatchingCharacterPainter.java (-3 / +177 lines)
Lines 20-32 Link Here
20
import org.eclipse.swt.graphics.Rectangle;
20
import org.eclipse.swt.graphics.Rectangle;
21
21
22
import org.eclipse.jface.text.BadLocationException;
22
import org.eclipse.jface.text.BadLocationException;
23
import org.eclipse.jface.text.DocumentEvent;
23
import org.eclipse.jface.text.IDocument;
24
import org.eclipse.jface.text.IDocument;
24
import org.eclipse.jface.text.IPaintPositionManager;
25
import org.eclipse.jface.text.IPaintPositionManager;
25
import org.eclipse.jface.text.IPainter;
26
import org.eclipse.jface.text.IPainter;
26
import org.eclipse.jface.text.IRegion;
27
import org.eclipse.jface.text.IRegion;
28
import org.eclipse.jface.text.ITextInputListener;
29
import org.eclipse.jface.text.ITextListener;
27
import org.eclipse.jface.text.ITextViewerExtension5;
30
import org.eclipse.jface.text.ITextViewerExtension5;
28
import org.eclipse.jface.text.Position;
31
import org.eclipse.jface.text.Position;
29
import org.eclipse.jface.text.Region;
32
import org.eclipse.jface.text.Region;
33
import org.eclipse.jface.text.TextEvent;
34
import org.eclipse.jface.text.TextUtilities;
30
35
31
/**
36
/**
32
 * Highlights the peer character matching the character near the caret position.
37
 * Highlights the peer character matching the character near the caret position.
Lines 37-43 Link Here
37
 *
42
 *
38
 * @since 2.1
43
 * @since 2.1
39
 */
44
 */
40
public final class MatchingCharacterPainter implements IPainter, PaintListener {
45
public final class MatchingCharacterPainter implements IPainter, PaintListener, ITextListener, ITextInputListener {
41
46
42
	/** Indicates whether this painter is active */
47
	/** Indicates whether this painter is active */
43
	private boolean fIsActive= false;
48
	private boolean fIsActive= false;
Lines 62-67 Link Here
62
	/** Whether a character is present at caret location or not. */
67
	/** Whether a character is present at caret location or not. */
63
	private boolean fCharacterPresentAtCaretLocation;
68
	private boolean fCharacterPresentAtCaretLocation;
64
69
70
	private IRegion fPreviousSelection;
71
72
//	private int count= 0;
73
74
	private IDocument fDocument;
75
76
	private boolean fDocumentChanged;
65
77
66
	/**
78
	/**
67
	 * Creates a new MatchingCharacterPainter for the given source viewer using the given character
79
	 * Creates a new MatchingCharacterPainter for the given source viewer using the given character
Lines 75-80 Link Here
75
		fSourceViewer= sourceViewer;
87
		fSourceViewer= sourceViewer;
76
		fMatcher= matcher;
88
		fMatcher= matcher;
77
		fTextWidget= sourceViewer.getTextWidget();
89
		fTextWidget= sourceViewer.getTextWidget();
90
91
		fDocument= fSourceViewer.getDocument();
92
93
		if (fMatcher instanceof ICharacterPairMatcherExtension) {
94
			fSourceViewer.addTextInputListener(this);
95
			fSourceViewer.addTextListener(this);
96
		}
78
	}
97
	}
79
98
80
	/**
99
	/**
Lines 138-143 Link Here
138
	 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
157
	 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
139
	 */
158
	 */
140
	public void paintControl(PaintEvent event) {
159
	public void paintControl(PaintEvent event) {
160
//		System.out.println("paint event - " + "fPairPosition.offset: " + fPairPosition.offset + " | fPairPosition.length: " + fPairPosition.length);
141
		if (fTextWidget != null)
161
		if (fTextWidget != null)
142
			handleDrawRequest(event.gc);
162
			handleDrawRequest(event.gc);
143
	}
163
	}
Lines 148-154 Link Here
148
	 * @param gc the GC to draw into.
168
	 * @param gc the GC to draw into.
149
	 */
169
	 */
150
	private void handleDrawRequest(GC gc) {
170
	private void handleDrawRequest(GC gc) {
151
171
//		System.out.println("drawing");
152
		if (fPairPosition.isDeleted)
172
		if (fPairPosition.isDeleted)
153
			return;
173
			return;
154
174
Lines 262-268 Link Here
262
	 */
282
	 */
263
	public void paint(int reason) {
283
	public void paint(int reason) {
264
284
265
		IDocument document= fSourceViewer.getDocument();
285
//		printDebugStatements(reason, "entering the method");
286
		IDocument document= fDocument;
266
		if (document == null) {
287
		if (document == null) {
267
			deactivate(false);
288
			deactivate(false);
268
			return;
289
			return;
Lines 272-283 Link Here
272
		IRegion pair;
293
		IRegion pair;
273
		boolean characterPresentAtCaretLocation;
294
		boolean characterPresentAtCaretLocation;
274
295
296
		if (reason != IPainter.CONFIGURATION && !fDocumentChanged && selection.equals(fPreviousSelection)) {
297
//			if (reason == IPainter.INTERNAL)
298
//				System.out.println("same as previous selection");
299
			return;
300
		}
301
302
		if (reason == IPainter.TEXT_CHANGE) {
303
			fPreviousSelection= selection;
304
			fPairPosition.isDeleted= true;
305
			return;
306
		}
307
308
		fDocumentChanged= false;
309
275
		if (fMatcher instanceof ICharacterPairMatcherExtension) {
310
		if (fMatcher instanceof ICharacterPairMatcherExtension) {
276
			ICharacterPairMatcherExtension matcher= (ICharacterPairMatcherExtension)fMatcher;
311
			ICharacterPairMatcherExtension matcher= (ICharacterPairMatcherExtension)fMatcher;
312
313
			if (fHighlightEnclosingPeerCharcters && fPreviousSelection != null && reason != IPainter.INTERNAL && reason != IPainter.CONFIGURATION) {
314
				int previousCaretOffset= fPreviousSelection.getOffset() + fPreviousSelection.getLength();
315
				int currentCaretOffset= selection.getOffset() + selection.getLength();
316
317
				try {
318
					//check partitions as well
319
					String prevContentType= TextUtilities.getContentType(document, matcher.getPartitioning(), previousCaretOffset, false);
320
					String currContentType= TextUtilities.getContentType(document, matcher.getPartitioning(), currentCaretOffset, false);
321
322
					if (prevContentType.equals(currContentType)) {
323
						if (Math.abs(currentCaretOffset - previousCaretOffset) == 1) {
324
							char c= currentCaretOffset > previousCaretOffset ? document.getChar(previousCaretOffset) : document.getChar(currentCaretOffset);
325
							if (!matcher.isMatchedChar(c)) {
326
								fPreviousSelection= selection;
327
								return;
328
							}
329
						}
330
331
						int start;
332
						int end;
333
						if (currentCaretOffset > previousCaretOffset) {
334
							start= previousCaretOffset;
335
							end= currentCaretOffset;
336
						} else {
337
							start= currentCaretOffset;
338
							end= previousCaretOffset;
339
						}
340
						boolean found= false;
341
						for (int i= start; i < end; i++) {
342
							if (matcher.isMatchedChar(document.getChar(i))) {
343
								found= true;
344
								break;
345
							}
346
						}
347
						if (!found) {
348
							fPreviousSelection= selection;
349
							return;
350
						}
351
					}
352
				} catch (BadLocationException e) {
353
					//do nothing
354
				}
355
			}
356
357
//			printDebugStatements(reason, "about to compute");
358
//			count++;
359
277
			pair= matcher.match(document, selection.getOffset(), selection.getLength());
360
			pair= matcher.match(document, selection.getOffset(), selection.getLength());
278
			characterPresentAtCaretLocation= (pair != null);
361
			characterPresentAtCaretLocation= (pair != null);
279
			if (pair == null && fHighlightEnclosingPeerCharcters) {
362
			if (pair == null && fHighlightEnclosingPeerCharcters) {
363
//				long start= System.currentTimeMillis();
280
				pair= matcher.findEnclosingPeerCharacters(document, selection.getOffset(), selection.getLength());
364
				pair= matcher.findEnclosingPeerCharacters(document, selection.getOffset(), selection.getLength());
365
//				long end= System.currentTimeMillis();
366
//				System.out.println("MCP: " + (end - start));
281
			}
367
			}
282
		} else {
368
		} else {
283
			if (Math.abs(selection.getLength()) > 0) {
369
			if (Math.abs(selection.getLength()) > 0) {
Lines 288-293 Link Here
288
			characterPresentAtCaretLocation= (pair != null);
374
			characterPresentAtCaretLocation= (pair != null);
289
		}
375
		}
290
376
377
		fPreviousSelection= selection;
291
		if (pair == null) {
378
		if (pair == null) {
292
			deactivate(true);
379
			deactivate(true);
293
			return;
380
			return;
Lines 312-317 Link Here
312
				fPairPosition.isDeleted= false;
399
				fPairPosition.isDeleted= false;
313
				fPairPosition.offset= pair.getOffset();
400
				fPairPosition.offset= pair.getOffset();
314
				fPairPosition.length= pair.getLength();
401
				fPairPosition.length= pair.getLength();
402
//				System.out.println("fPairPosition.offset: " + fPairPosition.offset + " | fPairPosition.length: " + fPairPosition.length);
315
				fAnchor= fMatcher.getAnchor();
403
				fAnchor= fMatcher.getAnchor();
316
				fCharacterPresentAtCaretLocation= characterPresentAtCaretLocation;
404
				fCharacterPresentAtCaretLocation= characterPresentAtCaretLocation;
317
				// apply new highlighting
405
				// apply new highlighting
Lines 334-343 Link Here
334
		}
422
		}
335
	}
423
	}
336
424
425
//	private void printDebugStatements(int reason, String loc) {
426
////		count++;
427
//		String s;
428
//		switch (reason) {
429
//			case IPainter.SELECTION:
430
//				s= "SELECTION"; //$NON-NLS-1$
431
//				break;
432
//			case IPainter.TEXT_CHANGE:
433
//				s= "TEXT_CHANGE"; //$NON-NLS-1$
434
//				break;
435
//			case IPainter.KEY_STROKE:
436
//				s= "KEY_STROKE"; //$NON-NLS-1$
437
//				break;
438
//			case IPainter.MOUSE_BUTTON:
439
//				s= "MOUSE_BUTTON"; //$NON-NLS-1$
440
//				break;
441
//			case IPainter.INTERNAL:
442
//				s= "INTERNAL"; //$NON-NLS-1$
443
//				break;
444
//			case IPainter.CONFIGURATION:
445
//				s= "CONFIGURATION"; //$NON-NLS-1$
446
//				break;
447
//			default:
448
//				s= "You have got to be kidding me"; //$NON-NLS-1$
449
//				break;
450
//		}
451
//		System.out.println(loc + " Reason: " + s + "   count: " + count); //$NON-NLS-1$ //$NON-NLS-2$
452
//	}
453
337
	/*
454
	/*
338
	 * @see org.eclipse.jface.text.IPainter#setPositionManager(org.eclipse.jface.text.IPaintPositionManager)
455
	 * @see org.eclipse.jface.text.IPainter#setPositionManager(org.eclipse.jface.text.IPaintPositionManager)
339
	 */
456
	 */
340
	public void setPositionManager(IPaintPositionManager manager) {
457
	public void setPositionManager(IPaintPositionManager manager) {
341
		fPaintPositionManager= manager;
458
		fPaintPositionManager= manager;
342
	}
459
	}
460
461
	/**
462
	 * @param oldInput the old input
463
	 * @param newInput the new input
464
	 * @since 3.8
465
	 */
466
	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
467
		//do nothing
468
	}
469
470
	/**
471
	 * @param oldInput the old input
472
	 * @param newInput the new input
473
	 * @since 3.8
474
	 */
475
	public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
476
		fDocument= newInput;
477
		fDocumentChanged= true;
478
//		System.out.println("doc changed");
479
	}
480
481
	/**
482
	 * @param event the text event
483
	 * @since 3.8
484
	 */
485
	public void textChanged(TextEvent event) {
486
		if (!(fMatcher instanceof ICharacterPairMatcherExtension))
487
			return;
488
			
489
		String text= event.getText();
490
		String replacedText= event.getReplacedText();
491
//		System.out.println("TextEvent: " + "|" + text + "|" + replacedText);
492
493
		boolean viewerRedrawState= event.getViewerRedrawState();
494
		DocumentEvent documentEvent= event.getDocumentEvent();
495
		if (documentEvent == null && !viewerRedrawState)
496
			return;
497
498
		ICharacterPairMatcherExtension matcher= (ICharacterPairMatcherExtension)fMatcher;
499
		boolean found= searchForCharacter(text, matcher) || searchForCharacter(replacedText, matcher);
500
501
		if (found || (documentEvent == null && viewerRedrawState)) {
502
//			System.out.println("smart painting");
503
			paint(IPainter.INTERNAL);
504
		}
505
	}
506
507
	private boolean searchForCharacter(String text, ICharacterPairMatcherExtension matcher) {
508
		if (text == null)
509
			return false;
510
		for (int i= 0; i < text.length(); i++) {
511
			if (matcher.isMatchedChar(text.charAt(i))) {
512
				return true;
513
			}
514
		}
515
		return false;
516
	}
343
}
517
}
(-)a/org.eclipse.text.tests/src/org/eclipse/text/tests/CopyOnWriteTextStoreTest.java (-4 / +4 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2008 IBM Corporation and others.
2
 * Copyright (c) 2005, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 31-37 Link Here
31
			super(new GapTextStore());
31
			super(new GapTextStore());
32
		}
32
		}
33
		ITextStore getStore() {
33
		ITextStore getStore() {
34
			return fTextStore;
34
			return (ITextStore)new Accessor(this, CopyOnWriteTextStore.class).get("fTextStore");
35
		}
35
		}
36
		String get() {
36
		String get() {
37
			return get(0, getLength());
37
			return get(0, getLength());
Lines 68-74 Link Here
68
		// check that underlying text store is not modifiable
68
		// check that underlying text store is not modifiable
69
		boolean failed= false;
69
		boolean failed= false;
70
		try {
70
		try {
71
			fText.getStore().replace(0,0,null);
71
			fText.getStore().replace(0, 0, null);
72
		} catch (UnsupportedOperationException uoe) {
72
		} catch (UnsupportedOperationException uoe) {
73
			failed= true;
73
			failed= true;
74
		}
74
		}
Lines 91-97 Link Here
91
		// check that underlying text store is not modifiable
91
		// check that underlying text store is not modifiable
92
		boolean failed= false;
92
		boolean failed= false;
93
		try {
93
		try {
94
			fText.getStore().replace(0,0,null);
94
			fText.getStore().replace(0, 0, null);
95
		} catch (UnsupportedOperationException uoe) {
95
		} catch (UnsupportedOperationException uoe) {
96
			failed= true;
96
			failed= true;
97
		}
97
		}
(-)a/org.eclipse.text/src/org/eclipse/jface/text/AbstractDocument.java (-3 / +5 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
2
 * Copyright (c) 2000, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 802-810 Link Here
802
	 * @see org.eclipse.jface.text.IDocument#getChar(int)
802
	 * @see org.eclipse.jface.text.IDocument#getChar(int)
803
	 */
803
	 */
804
	public char getChar(int pos) throws BadLocationException {
804
	public char getChar(int pos) throws BadLocationException {
805
		if ((0 > pos) || (pos >= getLength()))
805
		try {
806
			return fStore.get(pos); //TODO: call getStore() ?
807
		} catch (IndexOutOfBoundsException e) {
806
			throw new BadLocationException();
808
			throw new BadLocationException();
807
		return getStore().get(pos);
809
		}
808
	}
810
	}
809
811
810
	/*
812
	/*
(-)a/org.eclipse.text/src/org/eclipse/jface/text/CopyOnWriteTextStore.java (-2 / +2 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2010 IBM Corporation and others.
2
 * Copyright (c) 2005, 2012 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 107-113 Link Here
107
	}
107
	}
108
108
109
	/** The underlying "real" text store */
109
	/** The underlying "real" text store */
110
	protected ITextStore fTextStore= new StringTextStore();
110
	private ITextStore fTextStore;
111
111
112
	/** A modifiable <code>ITextStore</code> instance */
112
	/** A modifiable <code>ITextStore</code> instance */
113
	private final ITextStore fModifiableTextStore;
113
	private final ITextStore fModifiableTextStore;

Return to bug 372128