From e187f68cbca9e47b6c881e2891e72ca2d4499904 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Tue, 11 May 2004 05:52:51 +0000 Subject: [PATCH] 2004-05-11 Alain Magloire Preliminary work to get Parser IProblem in the CEditor. --- core/org.eclipse.cdt.core/ChangeLog | 4 + .../cdt/core/model/IProblemRequestor.java | 53 ++ .../cdt/core/model/ITranslationUnit.java | 45 + .../model/CreateWorkingCopyOperation.java | 77 ++ .../model/ReconcileWorkingCopyOperation.java | 13 +- .../internal/core/model/TranslationUnit.java | 21 +- .../model/TranslationUnitProblemFinder.java | 96 +++ .../cdt/internal/core/model/WorkingCopy.java | 23 +- core/org.eclipse.cdt.ui/ChangeLog | 4 + .../icons/full/obj16/quickfix_error_obj.gif | Bin 0 -> 232 bytes .../icons/full/obj16/quickfix_warning_obj.gif | Bin 0 -> 233 bytes core/org.eclipse.cdt.ui/plugin.xml | 25 + .../cdt/internal/ui/CPluginImages.java | 6 + .../internal/ui/editor/CDocumentProvider.java | 803 +++++++++++++++++- .../internal/ui/editor/CMarkerAnnotation.java | 92 +- .../cdt/internal/ui/editor/ICAnnotation.java | 108 +++ .../TranslationUnitAnnotationModelEvent.java | 107 +++ .../WorkInProgressPreferencePage.java | 22 + .../internal/ui/text/CAnnotationHover.java | 2 +- .../ui/text/IProblemRequestorExtension.java | 51 ++ .../ui/util/ProblemMarkerManager.java | 58 +- .../eclipse/cdt/ui/PreferenceConstants.java | 25 +- 22 files changed, 1574 insertions(+), 61 deletions(-) create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IProblemRequestor.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java create mode 100644 core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_error_obj.gif create mode 100644 core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_warning_obj.gif create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index b3ae0a9a963..912957e19ef 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,7 @@ +2004-05-11 Alain Magloire + + Preliminary work to get Parser IProblem in the CEditor. + 2004-05-07 David Inglis Setup a default scanner provider which uses the c path entries. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IProblemRequestor.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IProblemRequestor.java new file mode 100644 index 00000000000..b18c660481e --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IProblemRequestor.java @@ -0,0 +1,53 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.core.model; + +import org.eclipse.cdt.core.parser.IProblem; + +/** + * A callback interface for receiving problem as they are discovered + * IProblemRequestor + */ + +public interface IProblemRequestor { + + /** + * Notification of a Java problem. + * + * @param problem IProblem - The discovered Java problem. + */ + void acceptProblem(IProblem problem); + + /** + * Notification sent before starting the problem detection process. + * Typically, this would tell a problem collector to clear previously recorded problems. + */ + void beginReporting(); + + /** + * Notification sent after having completed problem detection process. + * Typically, this would tell a problem collector that no more problems should be expected in this + * iteration. + */ + void endReporting(); + + /** + * Predicate allowing the problem requestor to signal whether or not it is currently + * interested by problem reports. When answering false, problem will + * not be discovered any more until the next iteration. + * + * This predicate will be invoked once prior to each problem detection iteration. + * + * @return boolean - indicates whether the requestor is currently interested by problems. + */ + boolean isActive(); +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java index 9ff9a892664..0642e0e65a2 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java @@ -185,6 +185,51 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource IBufferFactory factory) throws CModelException; + /** + * Returns a shared working copy on this element using the given factory to create + * the buffer, or this element if this element is already a working copy. + * This API can only answer an already existing working copy if it is based on the same + * original translation unit AND was using the same buffer factory (i.e. as + * defined by Object#equals). + *

+ * The life time of a shared working copy is as follows: + *

+ * So users of this method must destroy exactly once the working copy. + *

+ * Note that the buffer factory will be used for the life time of this working copy, i.e. if the + * working copy is closed then reopened, this factory will be used. + * The buffer will be automatically initialized with the original's compilation unit content + * upon creation. + *

+ * When the shared working copy instance is created, an ADDED ICElementDelta is reported on this + * working copy. + * + * @param monitor a progress monitor used to report progress while opening this compilation unit + * or null if no progress should be reported + * @param factory the factory that creates a buffer that is used to get the content of the working copy + * or null if the internal factory should be used + * @param problemRequestor a requestor which will get notified of problems detected during + * reconciling as they are discovered. The requestor can be set to null indicating + * that the client is not interested in problems. + * @exception CModelException if the contents of this element can not be + * determined. Reasons include: + *

+ * @return a shared working copy on this element using the given factory to create + * the buffer, or this element if this element is already a working copy + * @see IBufferFactory + * @see IProblemRequestor + * @since 2.0 + */ + IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor requestor) throws CModelException; + /** * Returns the first namespace declaration in this translation unit with the given package name * This is a handle-only method. The namespace declaration may or may not exist. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java new file mode 100644 index 00000000000..90599b34122 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java @@ -0,0 +1,77 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import java.util.Map; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IProblemRequestor; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IFile; + +/** + * CreateWorkingCopyOperation + */ +public class CreateWorkingCopyOperation extends CModelOperation { + + Map perFactoryWorkingCopies; + IBufferFactory factory; + IProblemRequestor problemRequestor; + + /* + * Creates a working copy from the given original tu and the given buffer factory. + * perFactoryWorkingCopies map is not null if the working copy is a shared working copy. + */ + public CreateWorkingCopyOperation(ITranslationUnit originalElement, Map perFactoryWorkingCopies, IBufferFactory factory, IProblemRequestor problemRequestor) { + super(new ICElement[] {originalElement}); + this.perFactoryWorkingCopies = perFactoryWorkingCopies; + this.factory = factory; + this.problemRequestor = problemRequestor; + } + protected void executeOperation() throws CModelException { + ITranslationUnit tu = getTranslationUnit(); + + WorkingCopy workingCopy = new WorkingCopy(tu.getParent(), (IFile)tu.getResource(), this.factory, this.problemRequestor); + // open the working copy now to ensure contents are that of the current state of this element + workingCopy.open(this.fMonitor); + + if (this.perFactoryWorkingCopies != null) { + this.perFactoryWorkingCopies.put(tu, workingCopy); + //if (TranslationUnit.SHARED_WC_VERBOSE) { + // System.out.println("Creating shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$ + //} + } + + // report added java delta + CElementDelta delta = new CElementDelta(this.getCModel()); + delta.added(workingCopy); + addDelta(delta); + + fResultElements = new ICElement[] {workingCopy}; + } + + /** + * Returns the translation unit this operation is working on. + */ + protected ITranslationUnit getTranslationUnit() { + return (ITranslationUnit)getElementToProcess(); + } + + /** + * @see JavaModelOperation#isReadOnly + */ + public boolean isReadOnly() { + return true; + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java index cf850a295fa..83c2adf700f 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java @@ -14,6 +14,7 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICModelStatus; import org.eclipse.cdt.core.model.ICModelStatusConstants; +import org.eclipse.cdt.core.model.IProblemRequestor; /** * Reconcile a working copy and signal the changes through a delta. @@ -57,12 +58,12 @@ public class ReconcileWorkingCopyOperation extends CModelOperation { if (forceProblemDetection && wasConsistent){ if (fMonitor != null && fMonitor.isCanceled()) return; - //IProblemRequestor problemRequestor = workingCopy.problemRequestor; - //if (problemRequestor != null && problemRequestor.isActive()){ - // problemRequestor.beginReporting(); - // CompilationUnitProblemFinder.process(workingCopy, problemRequestor, fMonitor); - // problemRequestor.endReporting(); - //} + IProblemRequestor problemRequestor = workingCopy.problemRequestor; + if (problemRequestor != null && problemRequestor.isActive()){ + problemRequestor.beginReporting(); + TranslationUnitProblemFinder.process(workingCopy, problemRequestor, fMonitor); + problemRequestor.endReporting(); + } } // register the deltas diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index 3eeecc679ac..4f9e37518f9 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IInclude; import org.eclipse.cdt.core.model.IParent; +import org.eclipse.cdt.core.model.IProblemRequestor; import org.eclipse.cdt.core.model.ISourceManipulation; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; @@ -366,6 +367,14 @@ public class TranslationUnit extends Openable implements ITranslationUnit { */ public IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor,IBufferFactory factory) throws CModelException { + return getSharedWorkingCopy(monitor, factory, null); + } + + /** + * @see org.eclipse.cdt.core.model.ITranslationUnit#getSharedWorkingCopy(IProgressMonitor, IBufferFactory) + */ + public IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor,IBufferFactory factory, IProblemRequestor requestor) + throws CModelException { // if factory is null, default factory must be used if (factory == null) factory = BufferManager.getDefaultBufferManager(); @@ -388,15 +397,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return workingCopy; } else { - workingCopy = (WorkingCopy)this.getWorkingCopy(monitor, factory); - perFactoryWorkingCopies.put(this, workingCopy); - - // report added java delta -// CElementDelta delta = new CElementDelta(this.getCModel()); -// delta.added(workingCopy); -// manager.fire(delta, CModelManager.DEFAULT_CHANGE_EVENT); - - return workingCopy; + CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, requestor); + runOperation(op, monitor); + return (IWorkingCopy)op.getResultElements()[0]; } } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java new file mode 100644 index 00000000000..2d440a31e49 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java @@ -0,0 +1,96 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import java.io.StringReader; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.IProblemRequestor; +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.core.parser.IProblem; +import org.eclipse.cdt.core.parser.IScanner; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.core.parser.NullSourceElementRequestor; +import org.eclipse.cdt.core.parser.ParserFactory; +import org.eclipse.cdt.core.parser.ParserFactoryError; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.ParserMode; +import org.eclipse.cdt.core.parser.ScannerInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * TranslationUnitProblemFinder + */ +public class TranslationUnitProblemFinder extends NullSourceElementRequestor { + + IProblemRequestor requestor; + /** + * + */ + public TranslationUnitProblemFinder(IProblemRequestor requestor) { + super(); + this.requestor = requestor; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptProblem(org.eclipse.cdt.core.parser.IProblem) + */ + public boolean acceptProblem(IProblem problem) { + requestor.acceptProblem(problem); + return true; + } + + /** + * @param copy + * @param requestor + * @param monitor + */ + public static void process(WorkingCopy copy, IProblemRequestor requestor, IProgressMonitor monitor) { + + TranslationUnitProblemFinder problemFinder = new TranslationUnitProblemFinder(requestor); + IProject project = copy.getCProject().getProject(); + String code = new String(); + try{ + code = copy.getBuffer().getContents(); + } catch (CModelException e) { + // + } + + // pick the language + ParserLanguage language = copy.isCXXLanguage()? ParserLanguage.CPP : ParserLanguage.C; + + IParser parser = null; + try { + IScannerInfo scanInfo = new ScannerInfo(); + IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project); + if (provider != null){ + IScannerInfo buildScanInfo = provider.getScannerInformation(project); + if (buildScanInfo != null){ + scanInfo = new ScannerInfo(buildScanInfo.getDefinedSymbols(), buildScanInfo.getIncludePaths()); + } + } + + boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode()); + ParserMode mode = quickParseMode ? ParserMode.QUICK_PARSE : ParserMode.STRUCTURAL_PARSE; + IScanner scanner = ParserFactory.createScanner(new StringReader(code), copy.getPath().toOSString(), + scanInfo, mode, language, problemFinder, null, null); + parser = ParserFactory.createParser(scanner, problemFinder, mode, language, null); + parser.parse(); + } catch(ParserFactoryError pfe) { + // + } + + } +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java index 8cfded82178..6067bed8df8 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICModelStatusConstants; +import org.eclipse.cdt.core.model.IProblemRequestor; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.core.resources.IFile; @@ -45,16 +46,26 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { * never true if this translation unit is not a working copy. */ protected int useCount = 1; - + + /** + * If set, this is the problem requestor which will be used to notify problems + * detected during reconciling. + */ + protected IProblemRequestor problemRequestor; + /** * Creates a working copy of this element */ public WorkingCopy(ICElement parent, IFile file, IBufferFactory bufferFactory) { + this(parent, file, bufferFactory, null); + } + public WorkingCopy(ICElement parent, IFile file, IBufferFactory bufferFactory, IProblemRequestor requestor) { super(parent, file); this.bufferFactory = bufferFactory == null ? getBufferManager() : bufferFactory; + this.problemRequestor = requestor; } public WorkingCopy(ICElement parent, IPath path, IBufferFactory bufferFactory) { @@ -206,11 +217,17 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { * something other than navigation or if this is a working copy being * opened after it has been destroyed. */ - public void open(IProgressMonitor pm) throws CModelException { + public void open(IProgressMonitor monitor) throws CModelException { if (this.useCount == 0) { // was destroyed throw newNotPresentException(); } else { - super.open(pm); + super.open(monitor); + if (monitor != null && monitor.isCanceled()) return; + if (this.problemRequestor != null && this.problemRequestor.isActive()){ + this.problemRequestor.beginReporting(); + TranslationUnitProblemFinder.process(this, this.problemRequestor, monitor); + this.problemRequestor.endReporting(); + } } } /** diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index 576164e7541..7cc1670f074 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,7 @@ +2004-05-11 Alain Magloire + + Preliminary work to get Parser IProblem in the CEditor. + 2004-05-10 Andrew Niefer - fixing bug 60493: - created CSearchUtil.getSearchForFromElement and CSearchUtil.getSearchForFromNode diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_error_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_error_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6427e85933dfafcce23127a20117f55e9290484 GIT binary patch literal 232 zcmZ?wbhEHb6krfwIKseiW5)pti-;dT7#bQFe*CbQF~j1=kBS*HDsJ4^@#DvbA2%$1 z+=%$G!(v7SkTK&21H%priwX;i9T5>fDk}c}|KHHi5D^i+Z^fkA>n z2P6fulYuo=L9H*vQ^_?-;aP`P+rl-vVFx&s#7h+exZMvO$o?tRBe9XaSuo9Xii4uS zg+3n$wB1OV=x~b`z*`^Ev Ng8c#srjr#JtO1LWQZE1i literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_warning_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_warning_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..b34d85f21829f272d882d4c39b1476afc747f6d9 GIT binary patch literal 233 zcmZ?wbhEHb6krfwIKseSZy*2vKSM(U!~g&G^XJ?D|6jj + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java index 5fcb9f6d7d8..d2701dc5215 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java @@ -93,6 +93,9 @@ public class CPluginImages { public static final String IMG_OBJS_BREAKPOINT_DISABLED = NAME_PREFIX + "breakpoint_disabled.gif"; //$NON-NLS-1$ public static final String IMG_OBJS_BREAKPOINT_ACTIVE = NAME_PREFIX + "breakpoint_active.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FIXABLE_PROBLEM= NAME_PREFIX + "quickfix_warning_obj.gif"; //$NON-NLS-1$ + public static final String IMG_OBJS_FIXABLE_ERROR= NAME_PREFIX + "quickfix_error_obj.gif"; //$NON-NLS-1$ + // build console public static final String IMG_VIEW_BUILD = NAME_PREFIX + "buildconsole.gif"; //$NON-NLS-1$ public static final ImageDescriptor DESC_BUILD_CONSOLE = createManaged(T_VIEW, IMG_VIEW_BUILD); @@ -141,6 +144,9 @@ public class CPluginImages { public static final ImageDescriptor DESC_OBJS_SOURCE_ATTACH_ATTRIB= createManaged(T_OBJ, IMG_OBJS_SOURCE_ATTACH_ATTRIB); public static final ImageDescriptor DESC_OVR_PATH_INHERIT= create(T_OVR, "path_inherit_co.gif"); //$NON-NLS-1$ + public static final ImageDescriptor DESC_OBJS_FIXABLE_PROBLEM= createManaged(T_OBJ, IMG_OBJS_FIXABLE_PROBLEM); + public static final ImageDescriptor DESC_OBJS_FIXABLE_ERROR= createManaged(T_OBJ, IMG_OBJS_FIXABLE_ERROR); + // Breakpoint image descriptors public static final ImageDescriptor DESC_OBJS_BREAKPOINT = createManaged( T_OBJ, IMG_OBJS_BREAKPOINT ); public static final ImageDescriptor DESC_OBJS_BREAKPOINT_DISABLED = createManaged( T_OBJ, IMG_OBJS_BREAKPOINT_DISABLED ); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java index 7cd6e490c7c..088f0ab0d86 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java @@ -10,27 +10,59 @@ ***********************************************************************/ package org.eclipse.cdt.internal.ui.editor; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; + import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.IProblemRequestor; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.internal.core.model.IBufferFactory; import org.eclipse.cdt.internal.ui.CFileElementWorkingCopy; +import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.text.IProblemRequestorExtension; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceRuleFactory; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DefaultLineTracker; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ILineTracker; import org.eclipse.jface.text.ISynchronizable; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModelEvent; +import org.eclipse.jface.text.source.IAnnotationAccessExtension; import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelListener; +import org.eclipse.jface.text.source.IAnnotationModelListenerExtension; +import org.eclipse.jface.text.source.IAnnotationPresentation; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.editors.text.TextFileDocumentProvider; +import org.eclipse.ui.texteditor.AnnotationPreference; +import org.eclipse.ui.texteditor.AnnotationPreferenceLookup; +import org.eclipse.ui.texteditor.MarkerAnnotation; +import org.eclipse.ui.texteditor.MarkerUtilities; +import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; /** * CDocumentProvider2 @@ -43,8 +75,671 @@ public class CDocumentProvider extends TextFileDocumentProvider { public IWorkingCopy fCopy; } + /** + * Annotation representating an IProblem. + */ + static protected class ProblemAnnotation extends Annotation implements ICAnnotation, IAnnotationPresentation { + + private static final String SPELLING_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.spelling"; //$NON-NLS-1$ + + //XXX: To be fully correct these constants should be non-static + /** + * The layer in which task problem annotations are located. + */ + private static final int TASK_LAYER; + /** + * The layer in which info problem annotations are located. + */ + private static final int INFO_LAYER; + /** + * The layer in which warning problem annotations representing are located. + */ + private static final int WARNING_LAYER; + /** + * The layer in which error problem annotations representing are located. + */ + private static final int ERROR_LAYER; + + static { + AnnotationPreferenceLookup lookup= EditorsUI.getAnnotationPreferenceLookup(); + TASK_LAYER= computeLayer("org.eclipse.ui.workbench.texteditor.task", lookup); //$NON-NLS-1$ + INFO_LAYER= computeLayer("org.eclipse.cdt.ui.info", lookup); //$NON-NLS-1$ + WARNING_LAYER= computeLayer("org.eclipse.cdt.ui.warning", lookup); //$NON-NLS-1$ + ERROR_LAYER= computeLayer("org.eclipse.cdt.ui.error", lookup); //$NON-NLS-1$ + } + + private static int computeLayer(String annotationType, AnnotationPreferenceLookup lookup) { + Annotation annotation= new Annotation(annotationType, false, null); + AnnotationPreference preference= lookup.getAnnotationPreference(annotation); + if (preference != null) + return preference.getPresentationLayer() + 1; + else + return IAnnotationAccessExtension.DEFAULT_LAYER + 1; + } + + private static Image fgQuickFixImage; + private static Image fgQuickFixErrorImage; + private static boolean fgQuickFixImagesInitialized= false; + + private ITranslationUnit fTranslationUnit; + private List fOverlaids; + private IProblem fProblem; + private Image fImage; + private boolean fQuickFixImagesInitialized= false; + private int fLayer= IAnnotationAccessExtension.DEFAULT_LAYER; + + + public ProblemAnnotation(IProblem problem, ITranslationUnit cu) { + + fProblem= problem; + fTranslationUnit= cu; + + //if (SpellProblem.Spelling == fProblem.getID()) { + // setType(SPELLING_ANNOTATION_TYPE); + // fLayer= WARNING_LAYER; + //if (IProblem.Task == fProblem.getID()) { + // setType(CMarkerAnnotation.TASK_ANNOTATION_TYPE); + // fLayer= TASK_LAYER; + if (fProblem.isWarning()) { + setType(CMarkerAnnotation.WARNING_ANNOTATION_TYPE); + fLayer= WARNING_LAYER; + } else if (fProblem.isError()) { + setType(CMarkerAnnotation.ERROR_ANNOTATION_TYPE); + fLayer= ERROR_LAYER; + } else { + setType(CMarkerAnnotation.INFO_ANNOTATION_TYPE); + fLayer= INFO_LAYER; + } + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer() + */ + public int getLayer() { + return fLayer; + } + + private void initializeImages() { + // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18936 + if (!fQuickFixImagesInitialized) { + if (isProblem() && indicateQuixFixableProblems() /*&& JavaCorrectionProcessor.hasCorrections(this)*/) { // no light bulb for tasks + if (!fgQuickFixImagesInitialized) { + fgQuickFixImage= CPluginImages.get(CPluginImages.IMG_OBJS_FIXABLE_PROBLEM); + fgQuickFixErrorImage= CPluginImages.get(CPluginImages.IMG_OBJS_FIXABLE_ERROR); + fgQuickFixImagesInitialized= true; + } + if (CMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(getType())) + fImage= fgQuickFixErrorImage; + else + fImage= fgQuickFixImage; + } + fQuickFixImagesInitialized= true; + } + } + + private boolean indicateQuixFixableProblems() { + return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION); + } + + /* + * @see Annotation#paint + */ + public void paint(GC gc, Canvas canvas, Rectangle r) { + initializeImages(); + if (fImage != null) { + drawImage(fImage, gc, canvas, r, SWT.CENTER, SWT.TOP); + } + } + + /* + * @see ICAnnotation#getImage(Display) + */ + public Image getImage(Display display) { + initializeImages(); + return fImage; + } + + /* + * @see ICAnnotation#getMessage() + */ + public String getText() { + return fProblem.getMessage(); + } + + /* + * @see ICAnnotation#getArguments() + */ + public String[] getArguments() { + return isProblem() ? new String[]{fProblem.getArguments()} : null; + } + + /* + * @see ICAnnotation#getId() + */ + public int getId() { + return fProblem.getID(); + } + + /* + * @see ICAnnotation#isProblem() + */ + public boolean isProblem() { + String type= getType(); + return CMarkerAnnotation.WARNING_ANNOTATION_TYPE.equals(type) || + CMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(type) || + SPELLING_ANNOTATION_TYPE.equals(type); + } + + /* + * @see ICAnnotation#hasOverlay() + */ + public boolean hasOverlay() { + return false; + } + + /* + * @see org.eclipse.cdt.internal.ui.javaeditor.IJavaAnnotation#getOverlay() + */ + public ICAnnotation getOverlay() { + return null; + } + + /* + * @see ICAnnotation#addOverlaid(ICAnnotation) + */ + public void addOverlaid(ICAnnotation annotation) { + if (fOverlaids == null) + fOverlaids= new ArrayList(1); + fOverlaids.add(annotation); + } + + /* + * @see ICAnnotation#removeOverlaid(ICAnnotation) + */ + public void removeOverlaid(ICAnnotation annotation) { + if (fOverlaids != null) { + fOverlaids.remove(annotation); + if (fOverlaids.size() == 0) + fOverlaids= null; + } + } + + /* + * @see ICAnnotation#getOverlaidIterator() + */ + public Iterator getOverlaidIterator() { + if (fOverlaids != null) + return fOverlaids.iterator(); + return null; + } + + /* + * @see org.eclipse.cdt.internal.ui.editor.ICAnnotation#getTranslationUnit() + */ + public ITranslationUnit getTranslationUnit() { + return fTranslationUnit; + } + } + + /** + * Internal structure for mapping positions to some value. + * The reason for this specific structure is that positions can + * change over time. Thus a lookup is based on value and not + * on hash value. + */ + protected static class ReverseMap { + + static class Entry { + Position fPosition; + Object fValue; + } + + private List fList= new ArrayList(2); + private int fAnchor= 0; + + public ReverseMap() { + } + + public Object get(Position position) { + + Entry entry; + + // behind anchor + int length= fList.size(); + for (int i= fAnchor; i < length; i++) { + entry= (Entry) fList.get(i); + if (entry.fPosition.equals(position)) { + fAnchor= i; + return entry.fValue; + } + } + + // before anchor + for (int i= 0; i < fAnchor; i++) { + entry= (Entry) fList.get(i); + if (entry.fPosition.equals(position)) { + fAnchor= i; + return entry.fValue; + } + } + + return null; + } + + private int getIndex(Position position) { + Entry entry; + int length= fList.size(); + for (int i= 0; i < length; i++) { + entry= (Entry) fList.get(i); + if (entry.fPosition.equals(position)) + return i; + } + return -1; + } + + public void put(Position position, Object value) { + int index= getIndex(position); + if (index == -1) { + Entry entry= new Entry(); + entry.fPosition= position; + entry.fValue= value; + fList.add(entry); + } else { + Entry entry= (Entry) fList.get(index); + entry.fValue= value; + } + } + + public void remove(Position position) { + int index= getIndex(position); + if (index > -1) + fList.remove(index); + } + + public void clear() { + fList.clear(); + } + } + + /** + * Annotation model dealing with c marker annotations and temporary problems. + * Also acts as problem requestor for its translation unit. Initialiy inactive. Must explicitly be + * activated. + */ + protected static class TranslationUnitAnnotationModel extends ResourceMarkerAnnotationModel implements IProblemRequestor, IProblemRequestorExtension { + + private static class ProblemRequestorState { + boolean fInsideReportingSequence= false; + List fReportedProblems; + } + + private ThreadLocal fProblemRequestorState= new ThreadLocal(); + private int fStateCount= 0; + + private ITranslationUnit fTranslationUnit; + private List fGeneratedAnnotations; + private IProgressMonitor fProgressMonitor; + private boolean fIsActive= false; + + private ReverseMap fReverseMap= new ReverseMap(); + private List fPreviouslyOverlaid= null; + private List fCurrentlyOverlaid= new ArrayList(); + + + public TranslationUnitAnnotationModel(IResource resource) { + super(resource); + } + + public void setCompilationUnit(ITranslationUnit unit) { + fTranslationUnit= unit; + } + + protected MarkerAnnotation createMarkerAnnotation(IMarker marker) { + String markerType= MarkerUtilities.getMarkerType(marker); + if (markerType != null && markerType.startsWith(CMarkerAnnotation.C_MARKER_TYPE_PREFIX)) { + // TODO: Fix this we need the document + return new CMarkerAnnotation(marker, null); + } + return super.createMarkerAnnotation(marker); + } + + /* + * @see org.eclipse.jface.text.source.AnnotationModel#createAnnotationModelEvent() + */ + protected AnnotationModelEvent createAnnotationModelEvent() { + return new TranslationUnitAnnotationModelEvent(this, getResource()); + } + + protected Position createPositionFromProblem(IProblem problem) { + int start= problem.getSourceStart(); + if (start < 0) + return null; + + int length= problem.getSourceEnd() - problem.getSourceStart() + 1; + if (length < 0) + return null; + return new Position(start, length); + } + + /* + * @see IProblemRequestor#beginReporting() + */ + public void beginReporting() { + ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get(); + if (state == null) + internalBeginReporting(false); + } + + /* + * @see org.eclipse.jdt.internal.ui.text.java.IProblemRequestorExtension#beginReportingSequence() + */ + public void beginReportingSequence() { + ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get(); + if (state == null) + internalBeginReporting(true); + } + + /** + * Sets up the infrastructure necessary for problem reporting. + * + * @param insideReportingSequence true if this method + * call is issued from inside a reporting sequence + */ + private void internalBeginReporting(boolean insideReportingSequence) { + if (fTranslationUnit != null && fTranslationUnit.getCProject().isOnSourceRoot(fTranslationUnit.getResource())) { + ProblemRequestorState state= new ProblemRequestorState(); + state.fInsideReportingSequence= insideReportingSequence; + state.fReportedProblems= new ArrayList(); + synchronized (getLockObject()) { + fProblemRequestorState.set(state); + ++fStateCount; + } + } + } + + /* + * @see IProblemRequestor#acceptProblem(IProblem) + */ + public void acceptProblem(IProblem problem) { + if (isActive()) { + ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get(); + if (state != null) + state.fReportedProblems.add(problem); + } + } + + /* + * @see IProblemRequestor#endReporting() + */ + public void endReporting() { + ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get(); + if (state != null && !state.fInsideReportingSequence) + internalEndReporting(state); + } + + /* + * @see org.eclipse.jdt.internal.ui.text.java.IProblemRequestorExtension#endReportingSequence() + */ + public void endReportingSequence() { + ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get(); + if (state != null && state.fInsideReportingSequence) + internalEndReporting(state); + } + + private void internalEndReporting(ProblemRequestorState state) { + int stateCount= 0; + synchronized(getLockObject()) { + -- fStateCount; + stateCount= fStateCount; + fProblemRequestorState.set(null); + } + + if (stateCount == 0 && isActive()) + reportProblems(state.fReportedProblems); + } + + /** + * Signals the end of problem reporting. + */ + private void reportProblems(List reportedProblems) { + if (fProgressMonitor != null && fProgressMonitor.isCanceled()) + return; + + boolean temporaryProblemsChanged= false; + + synchronized (getLockObject()) { + + boolean isCanceled= false; + + fPreviouslyOverlaid= fCurrentlyOverlaid; + fCurrentlyOverlaid= new ArrayList(); + + if (fGeneratedAnnotations.size() > 0) { + temporaryProblemsChanged= true; + removeAnnotations(fGeneratedAnnotations, false, true); + fGeneratedAnnotations.clear(); + } + + if (reportedProblems != null && reportedProblems.size() > 0) { + + Iterator e= reportedProblems.iterator(); + while (e.hasNext()) { + + if (fProgressMonitor != null && fProgressMonitor.isCanceled()) { + isCanceled= true; + break; + } + + IProblem problem= (IProblem) e.next(); + Position position= createPositionFromProblem(problem); + if (position != null) { + + try { + ProblemAnnotation annotation= new ProblemAnnotation(problem, fTranslationUnit); + overlayMarkers(position, annotation); + addAnnotation(annotation, position, false); + fGeneratedAnnotations.add(annotation); + + temporaryProblemsChanged= true; + } catch (BadLocationException x) { + // ignore invalid position + } + } + } + } + + removeMarkerOverlays(isCanceled); + fPreviouslyOverlaid= null; + } + + if (temporaryProblemsChanged) + fireModelChanged(); + } + + private void removeMarkerOverlays(boolean isCanceled) { + if (isCanceled) { + fCurrentlyOverlaid.addAll(fPreviouslyOverlaid); + } else if (fPreviouslyOverlaid != null) { + Iterator e= fPreviouslyOverlaid.iterator(); + while (e.hasNext()) { + CMarkerAnnotation annotation= (CMarkerAnnotation) e.next(); + annotation.setOverlay(null); + } + } + } + + /** + * Overlays value with problem annotation. + * @param problemAnnotation + */ + private void setOverlay(Object value, ProblemAnnotation problemAnnotation) { + if (value instanceof CMarkerAnnotation) { + CMarkerAnnotation annotation= (CMarkerAnnotation) value; + if (annotation.isProblem()) { + annotation.setOverlay(problemAnnotation); + fPreviouslyOverlaid.remove(annotation); + fCurrentlyOverlaid.add(annotation); + } + } else { + } + } + + private void overlayMarkers(Position position, ProblemAnnotation problemAnnotation) { + Object value= getAnnotations(position); + if (value instanceof List) { + List list= (List) value; + for (Iterator e = list.iterator(); e.hasNext();) + setOverlay(e.next(), problemAnnotation); + } else { + setOverlay(value, problemAnnotation); + } + } + + /** + * Tells this annotation model to collect temporary problems from now on. + */ + private void startCollectingProblems() { + fGeneratedAnnotations= new ArrayList(); + } + + /** + * Tells this annotation model to no longer collect temporary problems. + */ + private void stopCollectingProblems() { + if (fGeneratedAnnotations != null) + removeAnnotations(fGeneratedAnnotations, true, true); + fGeneratedAnnotations= null; + } + + /* + * @see IProblemRequestor#isActive() + */ + public boolean isActive() { + return fIsActive; + } + + /* + * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor) + */ + public void setProgressMonitor(IProgressMonitor monitor) { + fProgressMonitor= monitor; + } + + /* + * @see IProblemRequestorExtension#setIsActive(boolean) + */ + public void setIsActive(boolean isActive) { + if (fIsActive != isActive) { + fIsActive= isActive; + if (fIsActive) + startCollectingProblems(); + else + stopCollectingProblems(); + } + } + + private Object getAnnotations(Position position) { + return fReverseMap.get(position); + } + + /* + * @see AnnotationModel#addAnnotation(Annotation, Position, boolean) + */ + protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged) throws BadLocationException { + super.addAnnotation(annotation, position, fireModelChanged); + + Object cached= fReverseMap.get(position); + if (cached == null) + fReverseMap.put(position, annotation); + else if (cached instanceof List) { + List list= (List) cached; + list.add(annotation); + } else if (cached instanceof Annotation) { + List list= new ArrayList(2); + list.add(cached); + list.add(annotation); + fReverseMap.put(position, list); + } + } + + /* + * @see AnnotationModel#removeAllAnnotations(boolean) + */ + protected void removeAllAnnotations(boolean fireModelChanged) { + super.removeAllAnnotations(fireModelChanged); + fReverseMap.clear(); + } + + /* + * @see AnnotationModel#removeAnnotation(Annotation, boolean) + */ + protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) { + Position position= getPosition(annotation); + Object cached= fReverseMap.get(position); + if (cached instanceof List) { + List list= (List) cached; + list.remove(annotation); + if (list.size() == 1) { + fReverseMap.put(position, list.get(0)); + list.clear(); + } + } else if (cached instanceof Annotation) { + fReverseMap.remove(position); + } + super.removeAnnotation(annotation, fireModelChanged); + } + } + + protected static class GlobalAnnotationModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension { + + private ArrayList fListenerList; + + public GlobalAnnotationModelListener() { + fListenerList= new ArrayList(); + } + + /** + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + Object[] listeners= fListenerList.toArray(); + for (int i= 0; i < listeners.length; i++) { + ((IAnnotationModelListener) listeners[i]).modelChanged(model); + } + } + + /** + * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + Object[] listeners= fListenerList.toArray(); + for (int i= 0; i < listeners.length; i++) { + Object curr= listeners[i]; + if (curr instanceof IAnnotationModelListenerExtension) { + ((IAnnotationModelListenerExtension) curr).modelChanged(event); + } + } + } + + public void addListener(IAnnotationModelListener listener) { + fListenerList.add(listener); + } + + public void removeListener(IAnnotationModelListener listener) { + fListenerList.remove(listener); + } + } + + /** Preference key for temporary problems */ + private final static String HANDLE_TEMPORARY_PROBLEMS= PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS; + /** Indicates whether the save has been initialized by this provider */ private boolean fIsAboutToSave = false; + /** Internal property changed listener */ + private IPropertyChangeListener fPropertyListener; + /** Annotation model listener added to all created CU annotation models */ + private GlobalAnnotationModelListener fGlobalAnnotationModelListener; + /** The save policy used by this provider */ //private ISavePolicy fSavePolicy; @@ -54,7 +749,15 @@ public class CDocumentProvider extends TextFileDocumentProvider { */ public CDocumentProvider() { super(); - setParentDocumentProvider(new TextFileDocumentProvider(new CStorageDocumentProvider())); + setParentDocumentProvider(new TextFileDocumentProvider(new CStorageDocumentProvider())); + fGlobalAnnotationModelListener= new GlobalAnnotationModelListener(); + fPropertyListener= new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + if (HANDLE_TEMPORARY_PROBLEMS.equals(event.getProperty())) + enableHandlingTemporaryProblems(); + } + }; + CUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyListener); } /** @@ -82,7 +785,8 @@ public class CDocumentProvider extends TextFileDocumentProvider { * @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createAnnotationModel(org.eclipse.core.resources.IFile) */ protected IAnnotationModel createAnnotationModel(IFile file) { - return new CMarkerAnnotationModel(file); + //return new CMarkerAnnotationModel(file); + return new TranslationUnitAnnotationModel(file); } /* @@ -90,23 +794,15 @@ public class CDocumentProvider extends TextFileDocumentProvider { */ protected FileInfo createFileInfo(Object element) throws CoreException { ITranslationUnit original = null; - IWorkingCopy copy = null; if (element instanceof IFileEditorInput) { IFileEditorInput input = (IFileEditorInput)element; original = createTranslationUnit(input.getFile()); - if (original != null) { - IBufferFactory factory = CUIPlugin.getDefault().getBufferFactory(); - copy = original.getSharedWorkingCopy(getProgressMonitor(), factory); - } } else if (element instanceof ITranslationUnitEditorInput) { ITranslationUnitEditorInput input = (ITranslationUnitEditorInput)element; - ITranslationUnit u = input.getTranslationUnit(); - if (u != null) { - copy = new CFileElementWorkingCopy(u); - } + original = input.getTranslationUnit(); } - - if (copy == null) { + + if (original == null) { return null; } @@ -115,22 +811,27 @@ public class CDocumentProvider extends TextFileDocumentProvider { return null; TranslationUnitInfo tuInfo = (TranslationUnitInfo) info; setUpSynchronization(tuInfo); - - //IProblemRequestor requestor= tuInfo.fModel instanceof IProblemRequestor ? (IProblemRequestor) tuInfo.fModel : null; - //original.becomeWorkingCopy(requestor, getProgressMonitor()); + IProblemRequestor requestor= tuInfo.fModel instanceof IProblemRequestor ? (IProblemRequestor) tuInfo.fModel : null; + IWorkingCopy copy = null; + if (element instanceof IFileEditorInput) { + IBufferFactory factory = CUIPlugin.getDefault().getBufferFactory(); + copy = original.getSharedWorkingCopy(getProgressMonitor(), factory, requestor); + } else if (element instanceof ITranslationUnitEditorInput) { + copy = new CFileElementWorkingCopy(original); + } tuInfo.fCopy = copy; - //if (tuInfo.fModel instanceof CMarkerAnnotationModel) { - // CMarkerAnnotationModel model= (CMarkerAnnotationModel) tuInfo.fModel; - // model.setCompilationUnit(tuInfo.fCopy); - //} - //if (tuInfo.fModel != null) - // tuInfo.fModel.addAnnotationModelListener(fGlobalAnnotationModelListener); - //if (requestor instanceof IProblemRequestorExtension) { - // IProblemRequestorExtension extension= (IProblemRequestorExtension)requestor; - // extension.setIsActive(isHandlingTemporaryProblems()); - //} + if (tuInfo.fModel instanceof TranslationUnitAnnotationModel) { + TranslationUnitAnnotationModel model= (TranslationUnitAnnotationModel) tuInfo.fModel; + model.setCompilationUnit(tuInfo.fCopy); + } + if (tuInfo.fModel != null) + tuInfo.fModel.addAnnotationModelListener(fGlobalAnnotationModelListener); + if (requestor instanceof IProblemRequestorExtension) { + IProblemRequestorExtension extension= (IProblemRequestorExtension)requestor; + extension.setIsActive(isHandlingTemporaryProblems()); + } return tuInfo; } @@ -151,8 +852,8 @@ public class CDocumentProvider extends TextFileDocumentProvider { if (info instanceof TranslationUnitInfo) { TranslationUnitInfo tuInfo = (TranslationUnitInfo) info; tuInfo.fCopy.destroy(); - //if (cuInfo.fModel != null) - // cuInfo.fModel.removeAnnotationModelListener(fGlobalAnnotationModelListener); + if (tuInfo.fModel != null) + tuInfo.fModel.removeAnnotationModelListener(fGlobalAnnotationModelListener); } super.disposeFileInfo(element, info); } @@ -192,6 +893,15 @@ public class CDocumentProvider extends TextFileDocumentProvider { } finally { fIsAboutToSave = false; } + + // If here, the dirty state of the editor will change to "not dirty". + // Thus, the state changing flag will be reset. + // NOTE: this is done in commitFileBuffer() if we use info.fCopy.comit(...) reenable code + //if (info.fModel instanceof AbstractMarkerAnnotationModel) { + // AbstractMarkerAnnotationModel model= (AbstractMarkerAnnotationModel) info.fModel; + // model.updateMarkers(document); + //} + } /* @@ -226,6 +936,43 @@ public class CDocumentProvider extends TextFileDocumentProvider { return null; } + /** + * Returns the preference whether handling temporary problems is enabled. + */ + protected boolean isHandlingTemporaryProblems() { + IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore(); + return store.getBoolean(HANDLE_TEMPORARY_PROBLEMS); + } + + /** + * Switches the state of problem acceptance according to the value in the preference store. + */ + protected void enableHandlingTemporaryProblems() { + boolean enable= isHandlingTemporaryProblems(); + for (Iterator iter= getFileInfosIterator(); iter.hasNext();) { + FileInfo info= (FileInfo) iter.next(); + if (info.fModel instanceof IProblemRequestorExtension) { + IProblemRequestorExtension extension= (IProblemRequestorExtension) info.fModel; + extension.setIsActive(enable); + } + } + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.ITranlationUnitDocumentProvider#addGlobalAnnotationModelListener(org.eclipse.jface.text.source.IAnnotationModelListener) + */ + public void addGlobalAnnotationModelListener(IAnnotationModelListener listener) { + fGlobalAnnotationModelListener.addListener(listener); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.ITranslationUnitDocumentProvider#removeGlobalAnnotationModelListener(org.eclipse.jface.text.source.IAnnotationModelListener) + */ + public void removeGlobalAnnotationModelListener(IAnnotationModelListener listener) { + fGlobalAnnotationModelListener.removeListener(listener); + } + + /* * @see org.eclipse.jdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider#getWorkingCopy(java.lang.Object) */ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java index c80e810b359..25bfde409e3 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java @@ -5,26 +5,40 @@ package org.eclipse.cdt.internal.ui.editor; * All Rights Reserved. */ +import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.search.ui.SearchUI; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.MarkerUtilities; -public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnotation { - +public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnotation, ICAnnotation { + + public static final String C_MARKER_TYPE_PREFIX= "org.eclipse.cdt"; //$NON-NLS-1$ + public static final String ERROR_ANNOTATION_TYPE= "org.eclipse.cdt.ui.error"; //$NON-NLS-1$ + public static final String WARNING_ANNOTATION_TYPE= "org.eclipse.cdt.ui.warning"; //$NON-NLS-1$ + public static final String INFO_ANNOTATION_TYPE= "org.eclipse.cdt.ui.info"; //$NON-NLS-1$ + public static final String TASK_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.task"; //$NON-NLS-1$ + private boolean fIsProblemMarker; private IDocument fDocument; private int error_start = -1; private int error_length = 0; + private ICAnnotation fOverlay; + public CMarkerAnnotation(IMarker marker, IDocument document) { super(marker); fDocument = document; @@ -173,7 +187,7 @@ public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnot super.initialize(); } - + /** * @see IProblemAnnotation#getMessage() */ @@ -245,4 +259,76 @@ public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnot public int getErrorLength() { return error_length; } + + /** + * Overlays this annotation with the given cAnnotation. + * + * @param cAnnotation annotation that is overlaid by this annotation + */ + public void setOverlay(ICAnnotation cAnnotation) { + if (fOverlay != null) + fOverlay.removeOverlaid(this); + + fOverlay= cAnnotation; + if (!isMarkedDeleted()) + markDeleted(fOverlay != null); + + if (fOverlay != null) + fOverlay.addOverlaid(this); + } + + /* + * @see ICAnnotation#hasOverlay() + */ + public boolean hasOverlay() { + return fOverlay != null; + } + + /* + * @see org.eclipse.cdt.internal.ui.editor.ICAnnotation#getOverlay() + */ + public ICAnnotation getOverlay() { + return fOverlay; + } + + /* + * @see ICAnnotation#addOverlaid(ICAnnotation) + */ + public void addOverlaid(ICAnnotation annotation) { + // not supported + } + + /* + * @see ICAnnotation#removeOverlaid(ICAnnotation) + */ + public void removeOverlaid(ICAnnotation annotation) { + // not supported + } + + /* + * @see ICAnnotation#getOverlaidIterator() + */ + public Iterator getOverlaidIterator() { + // not supported + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.javaeditor.IJavaAnnotation#getCompilationUnit() + */ + public ITranslationUnit getTranslationUnit() { + ICElement element= CoreModel.getDefault().create(getMarker().getResource()); + if (element instanceof ITranslationUnit) { + return (ITranslationUnit)element; + } + return null; + } + + /* + * @see org.eclipse.cdt.internal.ui.editor.ICAnnotation#getImage(org.eclipse.swt.widgets.Display) + */ + public Image getImage(Display display) { + return super.getImage(display); + } + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java new file mode 100644 index 00000000000..3a66d573196 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java @@ -0,0 +1,108 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.internal.ui.editor; + +import java.util.Iterator; + +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +/** + * ICAnnotation + * + * Interface of annotations representing markers + * and problems. + * + * @see org.eclipse.core.resources.IMarker + * @see org.eclipse.jdt.core.compiler.IProblem + */ +public interface ICAnnotation { + + /** + * @see org.eclipse.jface.text.source.Annotation#getType() + */ + String getType(); + + /** + * @see org.eclipse.jface.text.source.Annotation#isPersistent() + */ + boolean isPersistent(); + + /** + * @see org.eclipse.jface.text.source.Annotation#isMarkedDeleted() + */ + boolean isMarkedDeleted(); + + /** + * @see org.eclipse.jface.text.source.Annotation#getText() + */ + String getText(); + + /** + * Returns whether this annotation is overlaid. + * + * @return true if overlaid + */ + boolean hasOverlay(); + + /** + * Returns the overlay of this annotation. + * + * @return the annotation's overlay + */ + ICAnnotation getOverlay(); + + /** + * Returns an iterator for iterating over the + * annotation which are overlaid by this annotation. + * + * @return an iterator over the overlaid annotaions + */ + Iterator getOverlaidIterator(); + + /** + * Adds the given annotation to the list of + * annotations which are overlaid by this annotations. + * + * @param annotation the problem annoation + */ + void addOverlaid(ICAnnotation annotation); + + /** + * Removes the given annotation from the list of + * annotations which are overlaid by this annotation. + * + * @param annotation the problem annoation + */ + void removeOverlaid(ICAnnotation annotation); + + /** + * Tells whether this annotation is a problem + * annotation. + * + * @return true if it is a problem annotation + */ + boolean isProblem(); + + /** + * Returns the compilation unit corresponding to the document on which the annotation is set + * or null if no corresponding co0mpilationunit exists. + */ + ITranslationUnit getTranslationUnit(); + + String[] getArguments(); + + int getId(); + + Image getImage(Display display); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java new file mode 100644 index 00000000000..6c99899bb9f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java @@ -0,0 +1,107 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.internal.ui.editor; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationModelEvent; +import org.eclipse.jface.text.source.IAnnotationModel; + +import org.eclipse.ui.texteditor.MarkerAnnotation; + + +/** + * + * TranslationUnitAnnotationModelEvent + * + * Event sent out by changes of the compilation unit annotation model. + */ +public class TranslationUnitAnnotationModelEvent extends AnnotationModelEvent { + + private boolean fIncludesProblemMarkerAnnotations; + private IResource fUnderlyingResource; + + /** + * Constructor for CompilationUnitAnnotationModelEvent. + * @param model + * @param underlyingResource The annotation model's underlying resource + */ + public TranslationUnitAnnotationModelEvent(IAnnotationModel model, IResource underlyingResource) { + super(model); + fUnderlyingResource= underlyingResource; + fIncludesProblemMarkerAnnotations= false; + } + + private void testIfProblemMarker(Annotation annotation) { + if (fIncludesProblemMarkerAnnotations) { + return; + } + if (annotation instanceof CMarkerAnnotation) { + fIncludesProblemMarkerAnnotations= ((CMarkerAnnotation) annotation).isProblem(); + } else if (annotation instanceof MarkerAnnotation) { + try { + IMarker marker= ((MarkerAnnotation) annotation).getMarker(); + if (!marker.exists() || marker.isSubtypeOf(IMarker.PROBLEM)) { + fIncludesProblemMarkerAnnotations= true; + } + } catch (CoreException e) { + CUIPlugin.getDefault().log(e); + } + } + } + + /* + * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationAdded(org.eclipse.jface.text.source.Annotation) + */ + public void annotationAdded(Annotation annotation) { + super.annotationAdded(annotation); + testIfProblemMarker(annotation); + } + + + /* + * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationRemoved(org.eclipse.jface.text.source.Annotation) + */ + public void annotationRemoved(Annotation annotation) { + super.annotationRemoved(annotation); + testIfProblemMarker(annotation); + } + + /* + * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationChanged(org.eclipse.jface.text.source.Annotation) + */ + public void annotationChanged(Annotation annotation) { + testIfProblemMarker(annotation); + super.annotationChanged(annotation); + } + + /** + * Returns whether the change included problem marker annotations. + * + * @return true if the change included marker annotations + */ + public boolean includesProblemMarkerAnnotationChanges() { + return fIncludesProblemMarkerAnnotations; + } + + /** + * Returns the annotation model's underlying resource + */ + public IResource getUnderlyingResource() { + return fUnderlyingResource; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java index d91a95ea731..ab126cbdd7a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java @@ -13,6 +13,7 @@ import org.eclipse.cdt.core.browser.AllTypesCache; import org.eclipse.cdt.internal.core.search.indexing.SourceIndexer; import org.eclipse.cdt.internal.ui.search.CSearchPage; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.utils.ui.controls.ControlFactory; import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.dialogs.IDialogConstants; @@ -47,6 +48,7 @@ public class WorkInProgressPreferencePage extends PreferencePage private Button fExternEnabled; private Button fIProblemMarkers; private Button fBackgroundTypeCacheEnabled; + private Button fEditorCorrection; protected OverlayPreferenceStore fOverlayStore; private Text fTextControl; @@ -62,6 +64,7 @@ public class WorkInProgressPreferencePage extends PreferencePage overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, CSearchPage.EXTERNALMATCH_VISIBLE)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, SourceIndexer.CDT_INDEXER_TIMEOUT)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS)); OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; overlayKeys.toArray(keys); @@ -140,6 +143,21 @@ public class WorkInProgressPreferencePage extends PreferencePage } }); + Group editorCorrectionGroup= new Group(result, SWT.NONE); + editorCorrectionGroup.setLayout(new GridLayout()); + editorCorrectionGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + editorCorrectionGroup.setText("Editor"); //$NON-NLS-1$ + + fEditorCorrection = createCheckButton(editorCorrectionGroup, "Enable editor problem marker"); //$NON-NLS-1$ + fEditorCorrection.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + } + public void widgetSelected(SelectionEvent e) { + Button button = (Button) e.widget; + fOverlayStore.setValue(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS, button.getSelection()); + } + }); + initialize(); return result; @@ -156,6 +174,8 @@ public class WorkInProgressPreferencePage extends PreferencePage fTextControl.setText(fOverlayStore.getString(SourceIndexer.CDT_INDEXER_TIMEOUT)); fBackgroundTypeCacheEnabled.setSelection(fOverlayStore.getBoolean(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE)); + + fEditorCorrection.setSelection(fOverlayStore.getBoolean(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS)); } /* (non-Javadoc) @@ -220,6 +240,8 @@ public class WorkInProgressPreferencePage extends PreferencePage prefs.setValue(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE, fOverlayStore.getString(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE)); + prefs.setValue(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS, fOverlayStore.getString(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS)); + CCorePlugin.getDefault().savePluginPreferences(); return true; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java index dd7b550d534..6e2b9d93822 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java @@ -88,7 +88,7 @@ public class CAnnotationHover implements IAnnotationHover { */ public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) { List markers= getMarkersForLine(sourceViewer, lineNumber); - if (markers != null) { + if (markers != null && markers.size() > 0) { if (markers.size() == 1) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java new file mode 100644 index 00000000000..d2e4553776c --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2002,2003,2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ + +package org.eclipse.cdt.internal.ui.text; + +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * Extension to IProblemRequestor. + * IProblemRequestorExtension + */ +public interface IProblemRequestorExtension { + + /** + * Sets the progress monitor to this problem requestor. + * + * @param monitor the progress monitor to be used + */ + void setProgressMonitor(IProgressMonitor monitor); + + /** + * Sets the active state of this problem requestor. + * + * @param isActive the state of this problem requestor + */ + void setIsActive(boolean isActive); + + /** + * Informs the problem requestor that a sequence of reportings is about to start. While + * a sequence is active, multiple peering calls of beginReporting and + * endReporting can appear. + * + * @since 3.0 + */ + void beginReportingSequence(); + + /** + * Informs the problem requestor that the sequence of reportings has been finished. + * + * @since 3.0 + */ + void endReportingSequence(); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java index 2f94b8a662c..0eda74bb4c9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java @@ -7,8 +7,10 @@ package org.eclipse.cdt.internal.ui.util; import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.internal.ui.editor.TranslationUnitAnnotationModelEvent; import org.eclipse.cdt.ui.CUIPlugin; +import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -23,7 +25,12 @@ import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.text.source.AnnotationModelEvent; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelListener; +import org.eclipse.jface.text.source.IAnnotationModelListenerExtension; import org.eclipse.jface.util.ListenerList; +import org.eclipse.swt.widgets.Display; /** @@ -31,7 +38,7 @@ import org.eclipse.jface.util.ListenerList; * Viewers showing error ticks should register as listener to * this type. */ -public class ProblemMarkerManager implements IResourceChangeListener { +public class ProblemMarkerManager implements IResourceChangeListener, IAnnotationModelListener, IAnnotationModelListenerExtension { /** * Visitors used to filter the element delta changes @@ -113,17 +120,42 @@ public class ProblemMarkerManager implements IResourceChangeListener { CUIPlugin.getDefault().log(e.getStatus()); } - if (changedElements.size() > 0) { + if (!changedElements.isEmpty()) { fireChanges(changedElements); } + } - + + /* (non-Javadoc) + * @see IAnnotationModelListener#modelChanged(IAnnotationModel) + */ + public void modelChanged(IAnnotationModel model) { + // no action + } + + /* (non-Javadoc) + * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent) + */ + public void modelChanged(AnnotationModelEvent event) { + if (event instanceof TranslationUnitAnnotationModelEvent) { + TranslationUnitAnnotationModelEvent cuEvent= (TranslationUnitAnnotationModelEvent) event; + if (cuEvent.includesProblemMarkerAnnotationChanges()) { + //IResource[] changes= new IResource[] {cuEvent.getUnderlyingResource()}; + IResource res = cuEvent.getUnderlyingResource(); + if (res != null) { + fireChanges(Collections.singleton(res.getFullPath())); + } + } + } + } + /** * Adds a listener for problem marker changes. */ public void addListener(IProblemChangedListener listener) { if (fListeners.isEmpty()) { CUIPlugin.getWorkspace().addResourceChangeListener(this); + CUIPlugin.getDefault().getDocumentProvider().addGlobalAnnotationModelListener(this); } fListeners.add(listener); } @@ -135,15 +167,23 @@ public class ProblemMarkerManager implements IResourceChangeListener { fListeners.remove(listener); if (fListeners.isEmpty()) { CUIPlugin.getWorkspace().removeResourceChangeListener(this); + CUIPlugin.getDefault().getDocumentProvider().removeGlobalAnnotationModelListener(this); } } - private void fireChanges(Set changes) { - Object[] listeners= fListeners.getListeners(); - for (int i= 0; i < listeners.length; i++) { - IProblemChangedListener curr= (IProblemChangedListener) listeners[i]; - curr.problemsChanged(changes); - } + private void fireChanges(final Set changes) { + Display display= SWTUtil.getStandardDisplay(); + if (display != null && !display.isDisposed()) { + display.asyncExec(new Runnable() { + public void run() { + Object[] listeners= fListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + IProblemChangedListener curr= (IProblemChangedListener) listeners[i]; + curr.problemsChanged(changes); + } + } + }); + } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index 56ef7215a92..d41492b4112 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -62,7 +62,7 @@ public class PreferenceConstants { *

*/ public static final String PREF_USE_STRUCTURAL_PARSE_MODE= "org.eclipse.cdt.ui.editor.UseStructuralMode"; //$NON-NLS-1$ - + /** * A named preference that controls if segmented view (show selected element only) is turned on or off. *

@@ -121,7 +121,24 @@ public class PreferenceConstants { * @since 2.1 */ public final static String EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER= "taskIndicationInOverviewRuler"; //$NON-NLS-1$ - + + /** + * A named preference that controls if correction indicators are shown in the UI. + *

+ * Value is of type Boolean. + *

+ */ + public final static String EDITOR_CORRECTION_INDICATION= "CEditor.ShowTemporaryProblem"; //$NON-NLS-1$ + + /** + * A named preference that controls if temporary problems are evaluated and shown in the UI. + *

+ * Value is of type Boolean. + *

+ */ + public final static String EDITOR_EVALUATE_TEMPORARY_PROBLEMS= "handleTemporaryProblems"; //$NON-NLS-1$ + + public static final String REFACTOR_ERROR_PAGE_SEVERITY_THRESHOLD= "Refactoring.ErrorPage.severityThreshold"; //$NON-NLS-1$ public static final String REFACTOR_FATAL_SEVERITY= "4"; //$NON-NLS-1$ public static final String REFACTOR_ERROR_SEVERITY= "3"; //$NON-NLS-1$ @@ -151,5 +168,9 @@ public class PreferenceConstants { PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_TASK_TAG_COLOR, new RGB(127, 159, 191)); store.setDefault(PreferenceConstants.EDITOR_TASK_TAG_BOLD, true); + + store.setDefault(PreferenceConstants.EDITOR_CORRECTION_INDICATION, false); + store.setDefault(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS, false); + } } \ No newline at end of file