diff options
author | Kai Maetzel | 2003-12-04 12:07:39 +0000 |
---|---|---|
committer | Kai Maetzel | 2003-12-04 12:07:39 +0000 |
commit | 929dd905c17860e5240bbadfd22845594888de8d (patch) | |
tree | 55c073c95251786096ebb00fc91f6f0fed358611 | |
parent | a0ad51e9ea24ec6ee3f13491ad2b6433a6ab7294 (diff) | |
download | eclipse.platform.text-AnnotationsRework.tar.gz eclipse.platform.text-AnnotationsRework.tar.xz eclipse.platform.text-AnnotationsRework.zip |
*** empty log message ***AnnotationsRework
32 files changed, 670 insertions, 133 deletions
diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java index 38baad1f56c..da77f18157a 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/filebuffers/ITextFileBuffer.java @@ -12,7 +12,6 @@ package org.eclipse.core.filebuffers; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.source.IAnnotationModel; /** * A text file buffer is a file buffer for text files. The contents of a text file buffe is diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ContainerGenerator.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ContainerGenerator.java index 9661c7c2a47..c1b0c7066f2 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ContainerGenerator.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/ContainerGenerator.java @@ -104,8 +104,15 @@ public class ContainerGenerator { } } }; + + // Get scheduling rule + IWorkspaceRoot root= fWorkspace.getRoot(); + IPath existingParentPath= fContainerFullPath; + while (!root.exists(existingParentPath)) + existingParentPath= existingParentPath.removeLastSegments(1); - fWorkspace.run(runnable, monitor); + IResource schedulingRule= root.findMember(existingParentPath); + fWorkspace.run(runnable, schedulingRule, IWorkspace.AVOID_UPDATE, monitor); return fContainer; } } diff --git a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/JavaTextFileBuffer.java b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/JavaTextFileBuffer.java index 8e0e8bfcf71..75611bb4b0e 100644 --- a/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/JavaTextFileBuffer.java +++ b/org.eclipse.core.filebuffers/src/org/eclipse/core/internal/filebuffers/JavaTextFileBuffer.java @@ -33,7 +33,6 @@ import org.eclipse.core.filebuffers.ITextFileBuffer; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; -import org.eclipse.jface.text.source.IAnnotationModel; /** * @since 3.0 diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextPresentationListener.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextPresentationListener.java index 50547bad4d7..893ddf9ddf8 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextPresentationListener.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextPresentationListener.java @@ -31,7 +31,6 @@ public interface ITextPresentationListener { * ignored. * * @param textPresentation the current text presentation - * @param the region which is about to be drawn */ - public void applyTextPresentation(TextPresentation textPresentation, IRegion region); + public void applyTextPresentation(TextPresentation textPresentation); } diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/PaintManager.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/PaintManager.java index 0bc7e4155a8..6f05b7ef1ca 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/PaintManager.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/PaintManager.java @@ -273,7 +273,7 @@ public final class PaintManager implements KeyListener, MouseListener, ISelectio * @param reason the reason * @see IPainter */ - void paint(int reason) { + private void paint(int reason) { for (Iterator e = fPainters.iterator(); e.hasNext();) ((IPainter) e.next()).paint(reason); } diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextPresentation.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextPresentation.java index c460a5fccd0..c64fbe26efb 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextPresentation.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextPresentation.java @@ -144,6 +144,11 @@ public class TextPresentation { private ArrayList fRanges; /** A clipping region against which the presentation can be clipped when asked for results */ private IRegion fResultWindow; + /** + * The optional extent for this presentation. + * @since 3.0 + */ + private IRegion fExtent; /** @@ -163,6 +168,19 @@ public class TextPresentation { Assert.isTrue(sizeHint > 0); fRanges= new ArrayList(sizeHint); } + + /** + * Creates a new empty text presentation with the given extent. + * <code>sizeHint</code> tells the expected size of this presentation. + * + * @param sizeHint the expected size of this presentation + * @since 3.0 + */ + public TextPresentation(IRegion extent, int sizeHint) { + this(sizeHint); + Assert.isNotNull(extent); + fExtent= extent; + } /** * Sets the result window for this presentation. When dealing with @@ -326,7 +344,7 @@ public class TextPresentation { defaultRange.start= start; defaultRange.length= end - start; defaultRange.background= range.background; - fRanges.add(last, defaultRange); + fRanges.add(last + insertOffset, defaultRange); } } } @@ -365,7 +383,7 @@ public class TextPresentation { int defaultEnd= fDefaultRange.start + fDefaultRange.length; int end= range.start + range.length; if (end > defaultEnd) - range.length -= (defaultEnd - end); + range.length -= (end - defaultEnd); } } @@ -423,9 +441,12 @@ public class TextPresentation { * @return the window relative range based on the absolute range */ private StyleRange createWindowRelativeRange(IRegion window, StyleRange range) { - if (window == null || range == null) - return range; - + if (range == null) + return null; + + if (window == null) + return (StyleRange)range.clone(); + int start= range.start - window.getOffset(); if (start < 0) start= 0; @@ -440,7 +461,30 @@ public class TextPresentation { newRange.length= end - start; return newRange; } + + /** + * Returns the region which is relative to the specified window and + * appropriately clipped if necessary. + * + * @param region the absolute coverage + * @return the window relative region based on the absolute coverage + * @since 3.0 + */ + private IRegion createWindowRelativeRegion(IRegion coverage) { + if (fResultWindow == null || coverage == null) + return coverage; + + int start= coverage.getOffset() - fResultWindow.getOffset(); + if (start < 0) + start= 0; + + int rangeEnd= coverage.getOffset() + coverage.getLength(); + int windowEnd= fResultWindow.getOffset() + fResultWindow.getLength(); + int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd); + end -= fResultWindow.getOffset(); + return new Region(start, end - start); + } /** * Returns an iterator which enumerates all style ranged which define a style @@ -543,6 +587,20 @@ public class TextPresentation { } /** + * Returns the extent of this presentation clipped by the + * presentation's result window. + * + * @return the clipped extent + * @since 3.0 + */ + public IRegion getExtent() { + if (fExtent != null) + return createWindowRelativeRegion(fExtent); + else + return getCoverage(); + } + + /** * Clears this presentation by resetting all applied changes. * @since 2.0 */ @@ -551,4 +609,6 @@ public class TextPresentation { fResultWindow= null; fRanges.clear(); } + + } diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java index 287d94578a4..cfb6421c7f2 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java @@ -1825,7 +1825,7 @@ public class TextViewer extends Viewer implements IWidgetTokenKeeperExtension extension= (IWidgetTokenKeeperExtension) fWidgetTokenKeeper; accepted= extension.requestWidgetToken(this, priority); } else { - fWidgetTokenKeeper.requestWidgetToken(this); + accepted= fWidgetTokenKeeper.requestWidgetToken(this); } if (accepted) { @@ -3031,8 +3031,6 @@ public class TextViewer extends Viewer implements } catch (BadLocationException x) { throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_2")); //$NON-NLS-1$ } - - getPaintManager().paint(IPainter.INTERNAL); } /* @@ -3048,7 +3046,6 @@ public class TextViewer extends Viewer implements manager.freeSlaveDocument(slave); } } - getPaintManager().paint(IPainter.INTERNAL); } @@ -4004,25 +4001,28 @@ public class TextViewer extends Viewer implements if (presentation == null || !redraws()) return; - if (presentation.isEmpty() || fTextWidget == null) + if (fTextWidget == null) return; - - if (controlRedraw) - fTextWidget.setRedraw(false); + /* * Call registered text presentation listeners * and let them apply their presentation. */ if (fTextPresentationListeners != null) { - IRegion region= presentation.getCoverage(); ArrayList listeners= new ArrayList(fTextPresentationListeners); for (int i= 0, size= listeners.size(); i < size; i++) { ITextPresentationListener listener= (ITextPresentationListener)listeners.get(i); - listener.applyTextPresentation(presentation, region); + listener.applyTextPresentation(presentation); } } + if (presentation.isEmpty()) + return; + + if (controlRedraw) + fTextWidget.setRedraw(false); + if (fReplaceTextPresentation) applyTextPresentation(presentation); else diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectAdapter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectAdapter.java index ae4c1820d1e..16afcdf0251 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectAdapter.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectAdapter.java @@ -238,7 +238,7 @@ final class ContentAssistSubjectAdapter implements IContentAssistSubject { if (fContentAssistSubject != null) fContentAssistSubject.setSelectedRange(i, j); else - fViewer.getTextWidget().setSelectionRange(i, j); + fViewer.setSelectedRange(i, j); } /* diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistSubject.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistSubject.java index d3b62969abc..37a2dd977ca 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistSubject.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistSubject.java @@ -53,9 +53,11 @@ public interface IContentAssistSubject { int getLineHeight(); /** - * Returns the caret position relative to the start of the text. + * Returns the caret position relative to the start of the text in widget + * coordinates. * - * @return the caret position relative to the start of the text + * @return the caret position relative to the start of the text in widget + * coordinates * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been @@ -71,7 +73,7 @@ public interface IContentAssistSubject { * bounding box at the specified offset in the text. The point is relative * to the upper left corner of the widget client area. * - * @param offset offset relative to the start of the content 0 + * @param offset widget offset relative to the start of the content 0 * <= offset <= getCharCount() * @return x, y location of the upper left corner of the character bounding * box at the specified offset in the text diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/formatter/ContentFormatter2.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/formatter/ContentFormatter2.java index 4bf79c23ac4..9f9f67220f2 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/formatter/ContentFormatter2.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/formatter/ContentFormatter2.java @@ -781,7 +781,7 @@ public class ContentFormatter2 implements IContentFormatter, IContentFormatterEx /** * Formats the given region in the document using the indicated strategy. * The type of the region does not have to be the same as the type for - * which the strategy was originally registred. + * which the strategy was originally registered. * <p> * The formatting process will happen in the mode set up by the formatting * context or changes to the partition aware/unaware property. @@ -954,6 +954,8 @@ public class ContentFormatter2 implements IContentFormatter, IContentFormatterEx determinePositionsToUpdate(offset, length); + // since sort is stable, no reference pairs to the same zero-length position + // will get swapped. Collections.sort(fOverlappingPositionReferences); int[] positions= new int[fOverlappingPositionReferences.size()]; @@ -1005,10 +1007,25 @@ public class ContentFormatter2 implements IContentFormatter, IContentFormatterEx PositionReference r= (PositionReference) fOverlappingPositionReferences.get(i); - if (r.refersToOffset()) - r.setOffset(offset + positions[i]); - else - r.setLength((offset + positions[i]) - r.getOffset()); + if (r.refersToOffset()) { + int posOffset= offset + positions[i]; + if (posOffset >= 0) + r.setOffset(posOffset); +// else +// Protest + } else { + // positions are ordered by offset. For every position that has references + // to both offset and length, the offset comes first. + // Therefore, the end of the position (offset + positions[i]) is supposedly + // greater than r.getOffset() + // if this is not the case, perhaps the position returned from the formatter was negative? + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=46617 + int length= offset + positions[i] - r.getOffset(); + if (length >= 0) + r.setLength(length); +// else +// Protest + } Position p= r.getPosition(); String category= r.getCategory(); diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java index fd8c6edfef9..98360671816 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java @@ -63,10 +63,10 @@ public class InformationPresenter extends AbstractInformationControlManager impl /** * Priority of the info controls managed by this information presenter. - * Default value: <code>0</code>; + * Default value: <code>5</code> in order to beat the hovers of <code>TextViewerHoverManager</code> * @since 3.0 */ - public static final int WIDGET_PRIORITY= 0; + public static final int WIDGET_PRIORITY= 5; /** @@ -428,16 +428,16 @@ public class InformationPresenter extends AbstractInformationControlManager impl * @see AbstractInformationControlManager#showInformationControl(Rectangle) */ protected void showInformationControl(Rectangle subjectArea) { - if (fTextViewer instanceof IWidgetTokenOwner) { + if (fTextViewer instanceof IWidgetTokenOwnerExtension) { + IWidgetTokenOwnerExtension extension= (IWidgetTokenOwnerExtension) fTextViewer; + if (extension.requestWidgetToken(this, WIDGET_PRIORITY)) + super.showInformationControl(subjectArea); + } else if (fTextViewer instanceof IWidgetTokenOwner) { IWidgetTokenOwner owner= (IWidgetTokenOwner) fTextViewer; if (owner.requestWidgetToken(this)) super.showInformationControl(subjectArea); - } else if (fTextViewer instanceof IWidgetTokenOwnerExtension) { - IWidgetTokenOwnerExtension extension= (IWidgetTokenOwnerExtension) fTextViewer; - if (extension.requestWidgetToken(this, WIDGET_PRIORITY)) - super.showInformationControl(subjectArea); - } + } } /* diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java index c2254963455..c7854f3e122 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java @@ -15,6 +15,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import org.eclipse.swt.custom.StyleRange; + import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadPositionCategoryException; @@ -417,8 +419,13 @@ public class PresentationReconciler implements IPresentationReconciler, IPresent */ private TextPresentation createPresentation(IRegion damage, IDocument document) { try { + if (fRepairers == null || fRepairers.isEmpty()) { + TextPresentation presentation= new TextPresentation(damage, 1); + presentation.setDefaultStyleRange(new StyleRange(damage.getOffset(), damage.getLength(), null, null)); + return presentation; + } - TextPresentation presentation= new TextPresentation(1000); + TextPresentation presentation= new TextPresentation(damage, 1000); ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, getDocumentPartitioning(), damage.getOffset(), damage.getLength()); for (int i= 0; i < partitioning.length; i++) { @@ -448,6 +455,13 @@ public class PresentationReconciler implements IPresentationReconciler, IPresent */ private IRegion getDamage(DocumentEvent e, boolean optimize) { + if (fDamagers == null || fDamagers.isEmpty()) { + int length= e.getText() == null ? 0 : e.getText().length(); + length= Math.max(e.getLength(), length); + length= Math.min(e.getDocument().getLength() - e.getOffset(), length); + return new Region(e.getOffset(), length); + } + IRegion damage= null; try { @@ -527,7 +541,7 @@ public class PresentationReconciler implements IPresentationReconciler, IPresent private void processDamage(IRegion damage, IDocument document) { if (damage != null && damage.getLength() > 0) { TextPresentation p= createPresentation(damage, document); - if (p != null && !p.isEmpty()) + if (p != null) applyTextRegionCollection(p); } } diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java index edbd92d70ab..669a5a51fce 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/rules/DefaultDamagerRepairer.java @@ -75,6 +75,7 @@ public class DefaultDamagerRepairer implements IPresentationDamager, IPresentati Assert.isNotNull(scanner); fScanner= scanner; + fDefaultTextAttribute= new TextAttribute(null); } /* @@ -164,8 +165,8 @@ public class DefaultDamagerRepairer implements IPresentationDamager, IPresentati IToken token= fScanner.nextToken(); if (token.isEOF()) break; - - TextAttribute attribute= getTokenTextAttribute(token); + + TextAttribute attribute= getTokenTextAttribute(token); if (lastAttribute != null && lastAttribute.equals(attribute)) { length += fScanner.getTokenLength(); } else { diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationPainter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationPainter.java index fba729adaf5..cfc9347b2db 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationPainter.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationPainter.java @@ -34,6 +34,7 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IPaintPositionManager; import org.eclipse.jface.text.IPainter; import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextInputListener; import org.eclipse.jface.text.ITextPresentationListener; import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.ITextViewerExtension3; @@ -102,7 +103,17 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo * The range in which all highlight annotations can be found. * @since 3.0 */ - private Position fHighlightAnnotationRange= new Position(0); + private Position fHighlightAnnotationRange= new Position(Integer.MAX_VALUE); + /** + * The text input listener. + * @since 3.0 + */ + private ITextInputListener fTextInputListener; + /** + * Flag which tells that a new document input is currently being set. + * @since 3.0 + */ + private boolean fInputDocumentAboutToBeChanged; /** @@ -167,11 +178,13 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo fModel.removeAnnotationModelListener(this); fModel= model; if (fModel != null) { - try { - fIsSettingModel= true; - fModel.addAnnotationModelListener(this); - } finally { - fIsSettingModel= false; + synchronized(this) { + try { + fIsSettingModel= true; + fModel.addAnnotationModelListener(this); + } finally { + fIsSettingModel= false; + } } } } @@ -230,9 +243,12 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo } } } - if (!fHighlightedDecorations.isEmpty()) { - fHighlightAnnotationRange.offset= highlightAnnotationRangeStart; - fHighlightAnnotationRange.length= highlightAnnotationRangeEnd - highlightAnnotationRangeStart; + if (highlightAnnotationRangeStart != Integer.MAX_VALUE) { + int end= Math.max(fHighlightAnnotationRange.offset + fHighlightAnnotationRange.length, highlightAnnotationRangeEnd); + end= Math.min(end, fSourceViewer.getDocument().getLength()); + fHighlightAnnotationRange.offset= Math.min(fHighlightAnnotationRange.offset, highlightAnnotationRangeStart); + fHighlightAnnotationRange.offset= Math.min(fHighlightAnnotationRange.offset, fSourceViewer.getDocument().getLength()); + fHighlightAnnotationRange.length= end - fHighlightAnnotationRange.offset; } } } @@ -246,42 +262,57 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo catchupWithModel(); - invalidateTextPresentation(); + if (!fInputDocumentAboutToBeChanged) + invalidateTextPresentation(); enablePainting(); } private void invalidateTextPresentation() { if (fSourceViewer instanceof ITextViewerExtension2) { - IRegion r= getWidgetRange(fHighlightAnnotationRange); - if (r != null) - ((ITextViewerExtension2)fSourceViewer).invalidateTextPresentation(r.getOffset(), r.getLength()); + IRegion r; + if (fHighlightAnnotationRange != null && fHighlightAnnotationRange.getOffset() != Integer.MAX_VALUE) + r= new Region(fHighlightAnnotationRange.getOffset(), fHighlightAnnotationRange.getLength()); + else + r= fSourceViewer.getVisibleRegion(); + + ((ITextViewerExtension2)fSourceViewer).invalidateTextPresentation(r.getOffset(), r.getLength()); + } else { fSourceViewer.invalidateTextPresentation(); } } /* - * @see ITextPresentationListener#applyTextPresentation(TextPresentation, IRegion) + * @see ITextPresentationListener#applyTextPresentation(TextPresentation) * @since 3.0 */ - public synchronized void applyTextPresentation(TextPresentation tp, IRegion region) { - for (Iterator iter= fHighlightedDecorations.iterator(); iter.hasNext();) { + public synchronized void applyTextPresentation(TextPresentation tp) { + IRegion region= tp.getExtent(); - Decoration pp = (Decoration)iter.next(); - Position p= pp.fPosition; - if (!fSourceViewer.overlapsWithVisibleRegion(p.offset, p.length)) - continue; - - if (p.getOffset() + p.getLength() >= region.getOffset() && region.getOffset() + region.getLength() > p.getOffset()) - tp.mergeStyleRange(new StyleRange(p.getOffset(), p.getLength(), null, pp.fColor)); + for (int layer= 0, maxLayer= 1; layer < maxLayer; layer++) { + + for (Iterator iter= fHighlightedDecorations.iterator(); iter.hasNext();) { + + Decoration pp = (Decoration)iter.next(); + maxLayer= Math.max(maxLayer, pp.fLayer + 1); // dynamically update layer maximum + if (pp.fLayer != layer) // wrong layer: skip annotation + continue; + + Position p= pp.fPosition; + if (!fSourceViewer.overlapsWithVisibleRegion(p.offset, p.length)) + continue; + + if (p.getOffset() + p.getLength() >= region.getOffset() && region.getOffset() + region.getLength() > p.getOffset()) + tp.mergeStyleRange(new StyleRange(p.getOffset(), p.getLength(), null, pp.fColor)); + } } } /* * @see IAnnotationModelListener#modelChanged(IAnnotationModel) */ - public void modelChanged(final IAnnotationModel model) { + public synchronized void modelChanged(final IAnnotationModel model) { if (fTextWidget != null && !fTextWidget.isDisposed()) { if (fIsSettingModel) { // inside the ui thread -> no need for posting @@ -334,7 +365,23 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo */ public void addHighlightAnnotationType(Object annotationType) { fHighlightAnnotationTypes.add(annotationType); - + if (fTextInputListener == null) { + fTextInputListener= new ITextInputListener() { + /* + * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + fInputDocumentAboutToBeChanged= true; + } + /* + * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + fInputDocumentAboutToBeChanged= false; + } + }; + fSourceViewer.addTextInputListener(fTextInputListener); + } } /** @@ -358,6 +405,11 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo */ public void removeHighlightAnnotationType(Object annotationType) { fHighlightAnnotationTypes.remove(annotationType); + if (fHighlightAnnotationTypes.isEmpty() && fTextInputListener != null) { + fSourceViewer.removeTextInputListener(fTextInputListener); + fTextInputListener= null; + fInputDocumentAboutToBeChanged= false; + } } /** @@ -367,6 +419,10 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo public void removeAllAnnotationTypes() { fAnnotationTypes.clear(); fHighlightAnnotationTypes.clear(); + if (fTextInputListener != null) { + fSourceViewer.removeTextInputListener(fTextInputListener); + fTextInputListener= null; + } } /** @@ -498,7 +554,7 @@ public class AnnotationPainter implements IPainter, PaintListener, IAnnotationMo * @return the corresponding widget region */ private IRegion getWidgetRange(Position p) { - if (p == null) + if (p == null || p.offset == Integer.MAX_VALUE) return null; if (fSourceViewer instanceof ITextViewerExtension3) { diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/IAnnotationAccessExtension.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/IAnnotationAccessExtension.java index fbf44004acd..c3fef5cc22a 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/IAnnotationAccessExtension.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/IAnnotationAccessExtension.java @@ -63,7 +63,7 @@ public interface IAnnotationAccessExtension { void paint(Annotation annotation, GC gc, Canvas canvas, Rectangle bounds); /** - * Returns the text associated with the given annoattion. + * Returns the text associated with the given annotation. * * @return the text associated with the given annotation or <code>null</code> if none */ diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java index 9da70812c1a..e5ff781a61c 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewerConfiguration.java @@ -30,6 +30,7 @@ import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.formatter.IContentFormatter; import org.eclipse.jface.text.information.IInformationPresenter; import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.jface.text.presentation.PresentationReconciler; import org.eclipse.jface.text.reconciler.IReconciler; @@ -98,7 +99,10 @@ public class SourceViewerConfiguration { * @return the presentation reconciler or <code>null</code> if presentation reconciling should not be supported */ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { - return null; + PresentationReconciler reconciler= new PresentationReconciler(); + reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); + + return reconciler; } /** diff --git a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java index 551e64f6997..6dc10869da1 100644 --- a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java +++ b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java @@ -72,7 +72,7 @@ public final class ChildDocument extends AbstractDocument { } catch (BadLocationException x) { } - return null; + return ""; } /* diff --git a/org.eclipse.text/src/org/eclipse/jface/text/FindReplaceDocumentAdapter.java b/org.eclipse.text/src/org/eclipse/jface/text/FindReplaceDocumentAdapter.java index 40e66f75af9..cf9c96d0c1d 100644 --- a/org.eclipse.text/src/org/eclipse/jface/text/FindReplaceDocumentAdapter.java +++ b/org.eclipse.text/src/org/eclipse/jface/text/FindReplaceDocumentAdapter.java @@ -146,7 +146,7 @@ public class FindReplaceDocumentAdapter implements CharSequence { findString= "\\b" + findString + "\\b"; //$NON-NLS-1$ //$NON-NLS-2$ if (!regExSearch && !wholeWord) - findString= "\\Q" + findString + "\\E"; //$NON-NLS-1$ //$NON-NLS-2$ + findString= asRegPattern(findString); fFindReplaceMatchOffset= startOffset; if (fFindReplaceMatcher != null && fFindReplaceMatcher.pattern().pattern().equals(findString) && fFindReplaceMatcher.pattern().flags() == patternFlags) { @@ -222,6 +222,40 @@ public class FindReplaceDocumentAdapter implements CharSequence { } /** + * Converts a non-regex string to a pattern + * that can be used with the regex search engine. + * + * @param string the non-regex pattern + * @return the string converted to a regex pattern + */ + private String asRegPattern(String string) { + StringBuffer out= new StringBuffer(string.length()); + boolean quoting= false; + + int i= 0; + while (i < string.length()) { + char ch= string.charAt(i++); + if (ch == '\\') { + if (quoting) { + out.append("\\E"); //$NON-NLS-1$ + quoting= false; + } + out.append("\\\\"); //$NON-NLS-1$ + continue; + } + if (!quoting) { + out.append("\\Q"); //$NON-NLS-1$ + quoting= true; + } + out.append(ch); + } + if (quoting) + out.append("\\E"); //$NON-NLS-1$ + + return out.toString(); + } + + /** * Subsitutes the previous match with the given text. * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>. * diff --git a/org.eclipse.text/src/org/eclipse/jface/text/source/Annotation.java b/org.eclipse.text/src/org/eclipse/jface/text/source/Annotation.java index 2e7894c0d3f..906cc82c8bc 100644 --- a/org.eclipse.text/src/org/eclipse/jface/text/source/Annotation.java +++ b/org.eclipse.text/src/org/eclipse/jface/text/source/Annotation.java @@ -36,14 +36,9 @@ public class Annotation { */ public Annotation(String annotationType, boolean isPersistent) { fType= annotationType; + fIsPersistent= isPersistent; } - -// /** -// * Creates a new annotation. -// */ -// public Annotation() { -// } - + /** * Returns the annotation type of this annotation. * diff --git a/org.eclipse.text/src/org/eclipse/jface/text/source/AnnotationModel.java b/org.eclipse.text/src/org/eclipse/jface/text/source/AnnotationModel.java index 24182c1001b..3ca33402401 100644 --- a/org.eclipse.text/src/org/eclipse/jface/text/source/AnnotationModel.java +++ b/org.eclipse.text/src/org/eclipse/jface/text/source/AnnotationModel.java @@ -521,9 +521,6 @@ public class AnnotationModel implements IAnnotationModel, IAnnotationModelExtens fireModelChanged(); } - // TODO check whether this is OK - annotation.fireAnnotationChanged(); - } else { try { addAnnotation(annotation, position, fireModelChanged); diff --git a/org.eclipse.ui.editors/buildnotes_text.html b/org.eclipse.ui.editors/buildnotes_text.html index 8e7025bb513..f4ffb25b552 100644 --- a/org.eclipse.ui.editors/buildnotes_text.html +++ b/org.eclipse.ui.editors/buildnotes_text.html @@ -19,6 +19,18 @@ To see which bugs have been addressed in one of the builds simply open the <a hr <br> <br> <br> +========== Eclipse Build Input November 11th 2003 ==========<br> +<pre> +- Finished annotation background painter +- Added new concept of ITextPresentationListener which should be used by clients + to apply a presentation style (e.g. color, bold) to the text. Clients using + the StyledText.*styleRange* API methods should convert to this new API. A + ITextPresentationListener can be added and removed from a text viewer (see + ITextViewerExtension4) +</pre> +<br> +<br> + ========== Eclipse Build Input October 28th 2003 ==========<br> <pre> - Vertical ruler annotations can be disabled via editor's Annotation preference diff --git a/org.eclipse.ui.editors/scripts/exportplugin.xml b/org.eclipse.ui.editors/scripts/exportplugin.xml index bebf4aade2b..6abb4e451d2 100644 --- a/org.eclipse.ui.editors/scripts/exportplugin.xml +++ b/org.eclipse.ui.editors/scripts/exportplugin.xml @@ -23,7 +23,6 @@ <copy file="plugin.properties" todir="${dest}"/> <zip zipfile="${dest}/editorssrc.zip"> <fileset dir="src" /> - <fileset dir="extensions" /> </zip> </target> </project> diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java index 046d904d434..1304e419c7a 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java @@ -742,13 +742,15 @@ public class FileDocumentProvider extends StorageDocumentProvider { * @since 3.0 */ public boolean isSynchronized(Object element) { - Object elementInfo= getElementInfo(element); - if (elementInfo instanceof FileInfo) { - FileEditorInput input= (FileEditorInput) element; - IResource resource= input.getFile(); - return resource.isSynchronized(IResource.DEPTH_ZERO); + if (element instanceof IFileEditorInput) { + if (getElementInfo(element) != null) { + IFileEditorInput input= (IFileEditorInput) element; + IResource resource= input.getFile(); + return resource.isSynchronized(IResource.DEPTH_ZERO); + } + return false; } - return false; + return super.isSynchronized(element); } // --------------- Encoding support --------------- diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextFileDocumentProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextFileDocumentProvider.java index 3f82957a024..b6a837da3c1 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextFileDocumentProvider.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextFileDocumentProvider.java @@ -25,6 +25,7 @@ import java.util.NoSuchElementException; import org.eclipse.core.internal.filebuffers.ContainerGenerator; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; @@ -37,6 +38,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.IFileBuffer; @@ -75,7 +77,7 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr /** * Opertion created by the document provider and to be executed by the providers runnable context. */ - protected static abstract class DocumentProviderOperation implements IRunnableWithProgress { + protected static abstract class DocumentProviderOperation implements IRunnableWithProgress, ISchedulingRuleProvider { /** * The actual functionality of this operation. @@ -94,6 +96,13 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr throw new InvocationTargetException(x); } } + + /* + * @see org.eclipse.ui.texteditor.ISchedulingRuleProvider#getSchedulingRule() + */ + public ISchedulingRule getSchedulingRule() { + return ResourcesPlugin.getWorkspace().getRoot(); + } } static protected class NullProvider implements IDocumentProvider, IDocumentProviderExtension, IDocumentProviderExtension2, IDocumentProviderExtension3, IStorageDocumentProvider { @@ -559,6 +568,15 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr protected void execute(IProgressMonitor monitor) throws CoreException { info.fTextFileBuffer.revert(monitor); } + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule() + */ + public ISchedulingRule getSchedulingRule() { + if (info.fElement instanceof IFileEditorInput) + return ((IFileEditorInput)info.fElement).getFile(); + else + return null; + } }; executeOperation(operation, getProgressMonitor()); } else { @@ -594,6 +612,15 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr public void execute(IProgressMonitor monitor) throws CoreException { commitFileBuffer(monitor, info, overwrite); } + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule() + */ + public ISchedulingRule getSchedulingRule() { + if (info.fElement instanceof IFileEditorInput) + return ((IFileEditorInput)info.fElement).getFile().getParent(); + else + return null; + } }; } else if (element instanceof IFileEditorInput) { @@ -603,6 +630,15 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr public void execute(IProgressMonitor monitor) throws CoreException { createFileFromDocument(monitor, file, document); } + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule() + */ + public ISchedulingRule getSchedulingRule() { + IResource existingParent= file.getParent(); + while (!existingParent.exists()) + existingParent= existingParent.getParent(); + return existingParent; + } }; } @@ -762,6 +798,17 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr protected void execute(IProgressMonitor monitor) throws CoreException { info.fTextFileBuffer.validateState(monitor, computationContext); } + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule() + */ + public ISchedulingRule getSchedulingRule() { + // XXX: waiting for clients (e.g. Team providers) to support scheduling rules (see bug 46753) + return ResourcesPlugin.getWorkspace().getRoot(); +// if (info.fElement instanceof IFileEditorInput) +// return ((IFileEditorInput)info.fElement).getFile().getParent(); +// else +// return null; + } }; executeOperation(operation, getProgressMonitor()); } else @@ -823,6 +870,15 @@ public class TextFileDocumentProvider implements IDocumentProvider, IDocumentPr protected void execute(IProgressMonitor monitor) throws CoreException { info.fTextFileBuffer.revert(monitor); } + /* + * @see org.eclipse.ui.editors.text.TextFileDocumentProvider.DocumentProviderOperation#getSchedulingRule() + */ + public ISchedulingRule getSchedulingRule() { + if (info.fElement instanceof IFileEditorInput) + return ((IFileEditorInput)info.fElement).getFile().getParent(); + else + return null; + } }; executeOperation(operation, getProgressMonitor()); } else { diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/WorkspaceOperationRunner.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/WorkspaceOperationRunner.java index f575d577851..f10622124f7 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/WorkspaceOperationRunner.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/WorkspaceOperationRunner.java @@ -13,8 +13,10 @@ package org.eclipse.ui.editors.text; import java.lang.reflect.InvocationTargetException; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; @@ -56,7 +58,17 @@ public class WorkspaceOperationRunner implements IRunnableContext { * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean, org.eclipse.jface.operation.IRunnableWithProgress) */ public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException { - WorkspaceModifyDelegatingOperation operation= new WorkspaceModifyDelegatingOperation(runnable); + if (runnable instanceof ISchedulingRuleProvider) + run(fork, cancelable, runnable, ((ISchedulingRuleProvider)runnable).getSchedulingRule()); + else + run(fork, cancelable, runnable, ResourcesPlugin.getWorkspace().getRoot()); + } + + /* + * @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean, org.eclipse.jface.operation.IRunnableWithProgress) + */ + public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable, ISchedulingRule schedulingRule) throws InvocationTargetException, InterruptedException { + WorkspaceModifyDelegatingOperation operation= new WorkspaceModifyDelegatingOperation(runnable, schedulingRule); operation.run(getProgressMonitor()); } } diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractMarkerAnnotationModel.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractMarkerAnnotationModel.java index aa5aa17cebc..f82f40ad854 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractMarkerAnnotationModel.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractMarkerAnnotationModel.java @@ -13,8 +13,10 @@ package org.eclipse.ui.texteditor; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResourceStatus; @@ -59,6 +61,44 @@ import org.eclipse.ui.internal.editors.text.EditorsPlugin; * </p> */ public abstract class AbstractMarkerAnnotationModel extends AnnotationModel { + + + /** + * Temporary class. Will change when this information is read out + * from an extension point. + * + * TODO read from extension point + */ + static class AnnotationTypeMapping { + + private String fMarkerType; + private String[] fAnnotationTypes; + + public AnnotationTypeMapping(String markerType, String[] annotationTypes) { + fMarkerType= markerType; + fAnnotationTypes= annotationTypes; + } + + public AnnotationTypeMapping(String markerType, String annotationType) { + this(markerType, new String[] { annotationType }); + } + + public String getMarkerType() { + return fMarkerType; + } + + public String getAnnotationType(IMarker marker) { + try { + if (fMarkerType.equalsIgnoreCase(marker.getType())) + return fAnnotationTypes[MarkerUtilities.getSeverity(marker)]; + } catch (CoreException x) { + } catch (ArrayIndexOutOfBoundsException x) { + } + return null; + } + } + + /** List of annotations whose text range became invalid because of document changes */ private List fDeletedAnnotations= new ArrayList(2); @@ -66,6 +106,10 @@ public abstract class AbstractMarkerAnnotationModel extends AnnotationModel { private List fInstantiatedMarkerUpdaters= null; /** List of registered but not yet instantiated marker updaters */ private List fMarkerUpdaterSpecifications= null; + /** + * Map of <code>AnnotationTypeMappings</code>. + */ + private Map fAnnotationTypeMappings; /** @@ -148,7 +192,73 @@ public abstract class AbstractMarkerAnnotationModel extends AnnotationModel { */ protected MarkerAnnotation createMarkerAnnotation(IMarker marker) { String annotationType= computeAnnotationType(marker); - return new MarkerAnnotation(annotationType, marker); + if (annotationType != null) + return new MarkerAnnotation(annotationType, marker); + return null; + } + + /** + * Determines the annotation type for the given marker. + * + * @param marker the marker for which to determine the annotation type + * @return the annotation type for an annotation for the given marker + */ + protected String computeAnnotationType(IMarker marker) { + + String markerType= null; + try { + markerType= marker.getType(); + } catch (CoreException x) { + handleCoreException(x, "could not compute annotation type"); + return null; + } + + String annotationType= getAnnotationType(marker, markerType); + if (annotationType != null) + return annotationType; + + String[] superTypes= MarkerUtilities.getSuperTypes(markerType); + for (int i= 0; i < superTypes.length; i++) { + annotationType= getAnnotationType(marker, superTypes[i]); + if (annotationType != null) + return annotationType; + } + + return null; + } + + protected String getAnnotationType(IMarker marker, String markerType) { + Map map= getAnnotationTypeMappings(); + AnnotationTypeMapping mapping= (AnnotationTypeMapping) map.get(markerType); + if (mapping != null) + return mapping.getAnnotationType(marker); + return null; + } + + protected Map getAnnotationTypeMappings() { + if (fAnnotationTypeMappings == null) { + fAnnotationTypeMappings= new HashMap(); + initializeAnnotationTypeMappings(); + } + return fAnnotationTypeMappings; + } + + /** + * Initializes the annotation type mappings. + * TODO will be replaced with extension point based mapping + */ + private void initializeAnnotationTypeMappings() { + String[] types= new String[] { + "org.eclipse.ui.workbench.texteditor.info", + "org.eclipse.ui.workbench.texteditor.warning", + "org.eclipse.ui.workbench.texteditor.error" + }; + AnnotationTypeMapping m= new AnnotationTypeMapping("org.eclipse.core.resources.problemmarker", types); + fAnnotationTypeMappings.put(m.getMarkerType(), m); + m= new AnnotationTypeMapping("org.eclipse.core.resources.taskmarker", "org.eclipse.ui.workbench.texteditor.task"); + fAnnotationTypeMappings.put(m.getMarkerType(), m); + m= new AnnotationTypeMapping("org.eclipse.core.resources.bookmark", "org.eclipse.ui.workbench.texteditor.bookmark"); + fAnnotationTypeMappings.put(m.getMarkerType(), m); } /** @@ -219,7 +329,9 @@ public abstract class AbstractMarkerAnnotationModel extends AnnotationModel { Position p= createPositionFromMarker(marker); if (p != null) try { - addAnnotation(createMarkerAnnotation(marker), p, false); + MarkerAnnotation annotation= createMarkerAnnotation(marker); + if (annotation != null) + addAnnotation(annotation, p, false); } catch (BadLocationException e) { // ignore invalid position } @@ -312,8 +424,12 @@ public abstract class AbstractMarkerAnnotationModel extends AnnotationModel { MarkerAnnotation a= getMarkerAnnotation(marker); if (a != null) { Position p= createPositionFromMarker(marker); - if (p != null) + if (p != null) { + String annotationType= computeAnnotationType(marker); + if (!a.getAnnotationType().equals(annotationType)) + a.setAnnotationType(annotationType); modifyAnnotation(a, p); + } } } diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ExtendedTextEditor.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ExtendedTextEditor.java index dd4d3b0fbff..34927421c36 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ExtendedTextEditor.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ExtendedTextEditor.java @@ -495,7 +495,7 @@ public abstract class ExtendedTextEditor extends StatusTextEditor { */ protected boolean isPrefQuickDiffAlwaysOn() { IPreferenceStore store= getPreferenceStore(); - return store == null ? store.getBoolean(ExtendedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON) : false; + return store != null ? store.getBoolean(ExtendedTextEditorPreferenceConstants.QUICK_DIFF_ALWAYS_ON) : false; } /** @@ -676,7 +676,7 @@ public abstract class ExtendedTextEditor extends StatusTextEditor { AnnotationPreference preference= (AnnotationPreference)iter2.next(); String key= preference.getVerticalRulerPreferenceKey(); boolean showAnnotation= true; - if (key != null) + if (key != null && store.contains(key)) showAnnotation= store.getBoolean(key); if (showAnnotation) fAnnotationRulerColumn.addAnnotationType(preference.getAnnotationType()); diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerRulerAction.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerRulerAction.java index a7013a3edf8..da1d8e5f6f4 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerRulerAction.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerRulerAction.java @@ -19,11 +19,10 @@ import java.util.List; import java.util.Map; import java.util.ResourceBundle; -import org.eclipse.swt.widgets.Shell; - import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ILog; @@ -32,9 +31,13 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.swt.widgets.Shell; + import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.window.Window; + import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; @@ -42,7 +45,6 @@ import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.IVerticalRulerInfo; -import org.eclipse.jface.window.Window; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.PlatformUI; @@ -345,7 +347,7 @@ public class MarkerRulerAction extends ResourceAction implements IUpdate { marker.delete(); } } - }, null); + }, null, IWorkspace.AVOID_UPDATE, null); } catch (CoreException x) { handleCoreException(x, TextEditorMessages.getString("MarkerRulerAction.removeMarkers")); //$NON-NLS-1$ } diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerUtilities.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerUtilities.java index f7f3774ad7f..837757afc95 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerUtilities.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/MarkerUtilities.java @@ -12,12 +12,20 @@ package org.eclipse.ui.texteditor; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; @@ -36,6 +44,116 @@ import org.eclipse.ui.PlatformUI; */ public final class MarkerUtilities { + + private static class MarkerType { + private String fType; + private String[] fSuperTypes; + private String fLabel; + + public MarkerType(String type, String[] superTypes, String label) { + fType= type; + fSuperTypes= superTypes; + fLabel= label; + } + + public String getType() { + return fType; + } + + public String[] getSuperTypes() { + return fSuperTypes; + } + + public String getLabel() { + return fLabel; + } + } + + /** + * Internal marker super type hierarchy cache. + * TODO this cache is currently unbound, i.e. only limited by the number of marker types + */ + private static class MarkerTypeHierarchy { + + private Map fTypeMap; + private Map fSuperTypesCache= new HashMap(); + + public String[] getSuperTypes(String typeName) { + String[] cachedTypes= (String[]) fSuperTypesCache.get(typeName); + if (cachedTypes == null) { + cachedTypes= computeSuperTypes(typeName); + fSuperTypesCache.put(typeName, cachedTypes); + } + return cachedTypes; + } + + private String[] computeSuperTypes(String typeName) { + ArrayList types= new ArrayList(); + appendAll(types, getDirectSuperTypes(typeName)); + int index= 0; + while (index < types.size()) { + String type= (String) types.get(index); + appendAll(types, getDirectSuperTypes(type)); + } + + String[] superTypes= new String[types.size()]; + types.toArray(superTypes); + return superTypes; + } + + private String[] getDirectSuperTypes(String typeName) { + MarkerType type= (MarkerType) getTypeMap().get(typeName); + return type == null ? null : type.getSuperTypes(); + } + + private void appendAll(List list, Object[] objects) { + for (int i= 0; i < objects.length; i++) { + Object o= objects[i]; + if (!list.contains(o)) + list.add(o); + } + } + + private Map getTypeMap() { + if (fTypeMap == null) + fTypeMap= readTypes(); + return fTypeMap; + } + + private Map readTypes() { + HashMap allTypes= new HashMap(); + IExtensionPoint point= Platform.getPluginRegistry().getExtensionPoint(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_MARKERS); + if (point != null) { + IExtension[] extensions = point.getExtensions(); + for (int i= 0; i < extensions.length; i++) { + IExtension extension= extensions[i]; + + ArrayList types= new ArrayList(); + IConfigurationElement[] configElements= extension.getConfigurationElements(); + for (int j= 0; j < configElements.length; ++j) { + IConfigurationElement element= configElements[j]; + if (element.getName().equalsIgnoreCase("super")) {//$NON-NLS-1$ + String type = element.getAttribute("type");//$NON-NLS-1$ + if (type != null) { + types.add(type); + } + } + } + String[] superTypes= new String[types.size()]; + types.toArray(superTypes); + String id= extension.getUniqueIdentifier(); + + allTypes.put(id, new MarkerType(id, superTypes, extension.getLabel())); + } + } + return allTypes; + } + } + + private static MarkerTypeHierarchy fgMarkerTypeHierarchy; + + + /** * Don't allow instantiation. */ @@ -100,6 +218,19 @@ public final class MarkerUtilities { public static int getPriority(IMarker marker) { return getIntAttribute(marker, IMarker.PRIORITY, IMarker.PRIORITY_NORMAL); } + + /** + * Returns the severity of the given marker. + * + * @param marker the marker + * @return the priority, or <code>IMarker.SEVERITY_INFO</code> if not set + * @see IMarker#SEVERITY + * @see IMarker#SEVERITY_INFO + * @see IMarker#getAttribute(java.lang.String,int) + */ + public static int getSeverity(IMarker marker) { + return getIntAttribute(marker, IMarker.SEVERITY, IMarker.SEVERITY_INFO); + } /** * Handles a core exception which occurs when accessing marker attributes. @@ -251,6 +382,19 @@ public final class MarkerUtilities { } }; - resource.getWorkspace().run(r, null); + resource.getWorkspace().run(r, null,IWorkspace.AVOID_UPDATE, null); + } + + /** + * Returns the list of super types for the given marker. + * The list is a depth first list and maintains the sequence in which + * the super types are listed in the marker specification. + * + * @return a depth-first list of all super types of the given marker type + */ + public static String[] getSuperTypes(String markerType) { + if (fgMarkerTypeHierarchy == null) + fgMarkerTypeHierarchy= new MarkerTypeHierarchy(); + return fgMarkerTypeHierarchy.getSuperTypes(markerType); } } diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ResourceMarkerAnnotationModel.java b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ResourceMarkerAnnotationModel.java index e77c088a69d..20797422c98 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ResourceMarkerAnnotationModel.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/ResourceMarkerAnnotationModel.java @@ -130,7 +130,7 @@ public class ResourceMarkerAnnotationModel extends AbstractMarkerAnnotationModel markers[i].delete(); } } - }, null); + }, null, IWorkspace.AVOID_UPDATE, null); } /* diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/quickdiff/DocumentLineDiffer.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/quickdiff/DocumentLineDiffer.java index b858a694663..9509237d066 100644 --- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/quickdiff/DocumentLineDiffer.java +++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/quickdiff/DocumentLineDiffer.java @@ -19,6 +19,7 @@ import java.util.ListIterator; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; @@ -516,6 +517,8 @@ public class DocumentLineDiffer implements ILineDiffer, IDocumentListener, IAnno return e.getStatus(); } } + } catch (OperationCanceledException e) { + return Status.CANCEL_STATUS; } // Getting our own copies of the documents for offline diffing. diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java index b0c1490af8f..9efc6d046d2 100644 --- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java +++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/SourceViewerDecorationSupport.java @@ -54,7 +54,7 @@ public class SourceViewerDecorationSupport { * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { - if (fSymbolicFontName != null && fSymbolicFontName.equals(event.getProperty())) + if (fMarginPainter != null && fSymbolicFontName != null && fSymbolicFontName.equals(event.getProperty())) fMarginPainter.initialize(); } } @@ -171,14 +171,15 @@ public class SourceViewerDecorationSupport { while (e.hasNext()) { Object type= e.next(); if (areAnnotationsShown(type)) - showAnnotations(type, false); + showAnnotations(type, false, false); else - hideAnnotations(type, false); + hideAnnotations(type, false, false); if (areAnnotationsHighlighted(type)) - showAnnotations(type, true); + showAnnotations(type, true, false); else - hideAnnotations(type, true); + hideAnnotations(type, true, false); } + updateAnnotationPainter(); } /** @@ -338,7 +339,7 @@ public class SourceViewerDecorationSupport { return; } - if (fCursorLinePainterEnableKey.equals(p)) { + if (fCursorLinePainterEnableKey != null && fCursorLinePainterEnableKey.equals(p)) { if (isCursorLineShown()) showCursorLine(); else @@ -346,7 +347,7 @@ public class SourceViewerDecorationSupport { return; } - if (fCursorLinePainterColorKey.equals(p)) { + if (fCursorLinePainterColorKey != null && fCursorLinePainterColorKey.equals(p)) { if (fCursorLinePainter != null) { hideCursorLine(); showCursorLine(); @@ -354,7 +355,7 @@ public class SourceViewerDecorationSupport { return; } - if (fMarginPainterEnableKey.equals(p)) { + if (fMarginPainterEnableKey != null && fMarginPainterEnableKey.equals(p)) { if (isMarginShown()) showMargin(); else @@ -362,7 +363,7 @@ public class SourceViewerDecorationSupport { return; } - if (fMarginPainterColorKey.equals(p)) { + if (fMarginPainterColorKey != null && fMarginPainterColorKey.equals(p)) { if (fMarginPainter != null) { fMarginPainter.setMarginRulerColor(getColor(fMarginPainterColorKey)); fMarginPainter.paint(IPainter.CONFIGURATION); @@ -370,7 +371,7 @@ public class SourceViewerDecorationSupport { return; } - if (fMarginPainterColumnKey.equals(p)) { + if (fMarginPainterColumnKey != null && fMarginPainterColumnKey.equals(p)) { if (fMarginPainter != null && fPreferenceStore != null) { fMarginPainter.setMarginRulerColumn(fPreferenceStore.getInt(fMarginPainterColumnKey)); fMarginPainter.paint(IPainter.CONFIGURATION); @@ -393,17 +394,17 @@ public class SourceViewerDecorationSupport { if (info.getTextPreferenceKey().equals(p)) { if (areAnnotationsShown(info.getAnnotationType())) - showAnnotations(info.getAnnotationType(), false); + showAnnotations(info.getAnnotationType(), false, true); else - hideAnnotations(info.getAnnotationType(), false); + hideAnnotations(info.getAnnotationType(), false, true); return; } if (info.getHighlightPreferenceKey() != null && info.getHighlightPreferenceKey().equals(p)) { if (areAnnotationsHighlighted(info.getAnnotationType())) - showAnnotations(info.getAnnotationType(), true); + showAnnotations(info.getAnnotationType(), true, true); else - hideAnnotations(info.getAnnotationType(), true); + hideAnnotations(info.getAnnotationType(), true, true); return; } @@ -545,7 +546,7 @@ public class SourceViewerDecorationSupport { * @return <code>true</code> f the cursor line is shown */ private boolean isCursorLineShown() { - if (fPreferenceStore != null) + if (fPreferenceStore != null && fCursorLinePainterEnableKey != null) return fPreferenceStore.getBoolean(fCursorLinePainterEnableKey); return false; } @@ -593,7 +594,7 @@ public class SourceViewerDecorationSupport { * @return <code>true</code> if the margin is shown */ private boolean isMarginShown() { - if (fPreferenceStore != null) + if (fPreferenceStore != null && fMarginPainterEnableKey != null) return fPreferenceStore.getBoolean(fMarginPainterEnableKey); return false; } @@ -603,8 +604,9 @@ public class SourceViewerDecorationSupport { * * @param annotationType the annotation type * @param highlighting <code>true</code> if highlighting <code>false</code> if painting squiggles + * @param updatePainter if <code>true</code> update the annotation painter */ - private void showAnnotations(Object annotationType, boolean highlighting) { + private void showAnnotations(Object annotationType, boolean highlighting, boolean updatePainter) { if (fSourceViewer instanceof ITextViewerExtension2) { if (fAnnotationPainter == null) { fAnnotationPainter= new AnnotationPainter(fSourceViewer, fAnnotationAccess); @@ -618,14 +620,20 @@ public class SourceViewerDecorationSupport { fAnnotationPainter.addHighlightAnnotationType(annotationType); else fAnnotationPainter.addAnnotationType(annotationType); - fAnnotationPainter.paint(IPainter.CONFIGURATION); + + if (updatePainter) + updateAnnotationPainter(); } } /** - * Shuts down the annotation painter. + * Updates the annotation painter. */ - private void shutdownAnnotationPainter() { + private void updateAnnotationPainter() { + if (fAnnotationPainter == null) + return; + + fAnnotationPainter.paint(IPainter.CONFIGURATION); if (!fAnnotationPainter.isPaintingAnnotations()) { if (fSourceViewer instanceof ITextViewerExtension2) { ITextViewerExtension2 extension= (ITextViewerExtension2) fSourceViewer; @@ -637,8 +645,6 @@ public class SourceViewerDecorationSupport { fAnnotationPainter.deactivate(true); fAnnotationPainter.dispose(); fAnnotationPainter= null; - } else { - fAnnotationPainter.paint(IPainter.CONFIGURATION); } } @@ -647,16 +653,19 @@ public class SourceViewerDecorationSupport { * * @param annotationType the annotation type * @param highlighting <code>true</code> if highlighting <code>false</code> if painting squiggles + * @param updatePainter if <code>true</code> update the annotation painter * @since 3.0 */ - private void hideAnnotations(Object annotationType, boolean highlighting) { + private void hideAnnotations(Object annotationType, boolean highlighting, boolean updatePainter) { if (fAnnotationPainter != null) { if (highlighting) fAnnotationPainter.removeHighlightAnnotationType(annotationType); else fAnnotationPainter.removeAnnotationType(annotationType); - fAnnotationPainter.paint(IPainter.CONFIGURATION); - shutdownAnnotationPainter(); + + if (updatePainter) { + updateAnnotationPainter(); + } } } @@ -698,12 +707,10 @@ public class SourceViewerDecorationSupport { * @return <code>true</code> if the annotation overview is shown */ private boolean isAnnotationOverviewShown(Object annotationType) { - if (fPreferenceStore != null) { - if (fOverviewRuler != null) { - AnnotationPreference info= (AnnotationPreference) fAnnotationTypeKeyMap.get(annotationType); - if (info != null) - return fPreferenceStore.getBoolean(info.getOverviewRulerPreferenceKey()); - } + if (fPreferenceStore != null && fOverviewRuler != null) { + AnnotationPreference info= (AnnotationPreference) fAnnotationTypeKeyMap.get(annotationType); + if (info != null) + return fPreferenceStore.getBoolean(info.getOverviewRulerPreferenceKey()); } return false; } |