diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java
index 9ccdc683849..e2934ce540c 100644
--- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeBuilder.java
@@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136)
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.make.core;
@@ -205,11 +206,11 @@ public class MakeBuilder extends ACBuilder {
if (last == null) {
last = new Integer(100);
}
- StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 100), cos, last.intValue());
ErrorParserManager epm = new ErrorParserManager(getProject(), workingDirectoryURI, this, info.getErrorParsers());
- epm.setOutputStream(streamMon);
- OutputStream stdout = epm.getOutputStream();
- OutputStream stderr = epm.getOutputStream();
+ epm.setOutputStream(cos);
+ StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 100), epm, last.intValue());
+ OutputStream stdout = streamMon;
+ OutputStream stderr = streamMon;
// Sniff console output for scanner info
ConsoleOutputSniffer sniffer = ScannerInfoConsoleParserFactory.getMakeBuilderOutputSniffer(
stdout, stderr, getProject(), workingDirectory, null, this, null);
@@ -256,7 +257,6 @@ public class MakeBuilder extends ACBuilder {
monitor.subTask(MakeMessages.getString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$
consoleOut.close();
consoleErr.close();
- epm.reportProblems();
cos.close();
}
} catch (Exception e) {
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
index f39c468f3fa..fad2e606c7e 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Intel Corporation and others.
+ * Copyright (c) 2007, 2010 Intel Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* Intel Corporation - Initial API and implementation
* IBM Corporation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.core;
@@ -1035,7 +1036,6 @@ public class CommonBuilder extends ACBuilder {
monitor.subTask(ManagedMakeMessages
.getResourceString(MARKERS));
//TODO: addBuilderMarkers(epm);
- epm.reportProblems();
bsMngr.setProjectBuildState(currentProject, pBS);
} else {
@@ -1912,11 +1912,11 @@ public class CommonBuilder extends ACBuilder {
if (last == null) {
last = new Integer(100);
}
- StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 100), cos, last.intValue());
ErrorParserManager epm = new ErrorParserManager(currProject, workingDirectoryURI, this, builder.getErrorParsers());
- epm.setOutputStream(streamMon);
- OutputStream stdout = epm.getOutputStream();
- OutputStream stderr = epm.getOutputStream();
+ epm.setOutputStream(cos);
+ StreamMonitor streamMon = new StreamMonitor(new SubProgressMonitor(monitor, 100), epm, last.intValue());
+ OutputStream stdout = streamMon;
+ OutputStream stderr = streamMon;
// Sniff console output for scanner info
// ICfgScannerConfigBuilderInfo2Set container = CfgScannerConfigProfileManager.getCfgScannerConfigBuildInfo(cfg);
// CfgInfoContext context = new CfgInfoContext(cfg);
@@ -1980,7 +1980,6 @@ public class CommonBuilder extends ACBuilder {
monitor.subTask(ManagedMakeMessages.getResourceString("MakeBuilder.Creating_Markers")); //$NON-NLS-1$
consoleOut.close();
consoleErr.close();
- epm.reportProblems();
cos.close();
}
} catch (Exception e) {
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
index 180ad899bfa..551363bca24 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java
@@ -1146,7 +1146,6 @@ public class GeneratedMakefileBuilder extends ACBuilder {
monitor.subTask(ManagedMakeMessages
.getResourceString(MARKERS));
addBuilderMarkers(epm);
- epm.reportProblems();
consoleOutStream.close();
}
}
@@ -1334,10 +1333,8 @@ public class GeneratedMakefileBuilder extends ACBuilder {
epmOutputStream.close();
epmOutputStream = null;
// Generate any error markers that the build has discovered
- monitor.subTask(ManagedMakeMessages
- .getResourceString(MARKERS));
+ monitor.subTask(ManagedMakeMessages.getResourceString(MARKERS));
addBuilderMarkers(epm);
- epm.reportProblems();
} else {
buf = new StringBuffer();
buf.append(ManagedMakeMessages.getFormattedString(NOTHING_BUILT, getProject().getName()));
@@ -1568,7 +1565,6 @@ public class GeneratedMakefileBuilder extends ACBuilder {
// Generate any error markers that the build has discovered
addBuilderMarkers(epm);
- epm.reportProblems();
consoleOutStream.close();
} catch (Exception e) {
StringBuffer buf = new StringBuffer();
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserEfsFileMatchingTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserEfsFileMatchingTest.java
index 1e0c3830208..46021b087dd 100644
--- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserEfsFileMatchingTest.java
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserEfsFileMatchingTest.java
@@ -156,7 +156,7 @@ public class ErrorParserEfsFileMatchingTest extends TestCase {
line = line + '\n';
epManager.write(line.getBytes(), 0, line.length());
epManager.close();
- epManager.reportProblems();
+ epManager.getOutputStream().close();
}
/**
@@ -175,7 +175,7 @@ public class ErrorParserEfsFileMatchingTest extends TestCase {
line = line + '\n';
epManager.write(line.getBytes(), 0, line.length());
epManager.close();
- epManager.reportProblems();
+ epManager.getOutputStream().close();
}
/**
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java
index 157d420d4c7..1850477797b 100644
--- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserFileMatchingTest.java
@@ -158,7 +158,7 @@ public class ErrorParserFileMatchingTest extends TestCase {
line = line + '\n';
epManager.write(line.getBytes(), 0, line.length());
epManager.close();
- epManager.reportProblems();
+ epManager.getOutputStream().close();
}
/**
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserManagerTest.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserManagerTest.java
index 0579e1544cd..ef7766b6be5 100644
--- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserManagerTest.java
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/ErrorParserManagerTest.java
@@ -153,7 +153,7 @@ public class ErrorParserManagerTest extends TestCase {
private void end() throws IOException {
epManager.getOutputStream();
epManager.close();
- epManager.reportProblems();
+ epManager.getOutputStream().close();
}
public void testParsersSanity() throws CoreException, IOException {
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/GenericErrorParserTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/GenericErrorParserTests.java
index 724ebcf8366..1bdd11ffcbd 100644
--- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/GenericErrorParserTests.java
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/GenericErrorParserTests.java
@@ -125,7 +125,7 @@ public abstract class GenericErrorParserTests extends TestCase {
transferInputStreamToOutputStream(inputStream, manager.getOutputStream(), 1024);
manager.close();
- manager.reportProblems();
+ manager.getOutputStream().close();
if (expectedErrorCount >= 0) {
assertEquals(expectedErrorCount, markerGenerator.numErrors);
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java
index 8c31ce13f6b..e076eb9f562 100644
--- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/errorparsers/tests/RegexErrorParserTests.java
@@ -207,7 +207,6 @@ public class RegexErrorParserTests extends TestCase {
regexErrorParser.processLine("Variable!Description!10!"+fileName, epManager);
errorList.clear();
- epManager.reportProblems();
assertEquals(3, errorList.size());
// Regular
@@ -704,7 +703,6 @@ public class RegexErrorParserTests extends TestCase {
regexErrorParser.processLine("pattern wrong", epManager);
errorList.clear();
- epManager.reportProblems();
assertEquals(0, errorList.size());
}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
index bbf08b37f46..b97f517ce31 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Sergey Prigogin (Google)
* James Blackburn (Broadcom) - Bug 247838
* Andrew Gvozdev (Quoin Inc)
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.core;
@@ -25,6 +26,7 @@ import java.util.Vector;
import org.eclipse.cdt.core.errorparsers.ErrorParserNamedWrapper;
import org.eclipse.cdt.core.resources.ACBuilder;
+import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.errorparsers.ErrorParserExtensionManager;
import org.eclipse.cdt.utils.CygPath;
@@ -307,7 +309,6 @@ public class ErrorParserManager extends OutputStream {
if (fErrorParsers.size() == 0)
return;
-
String lineTrimmed = line.trim();
lineCounter++;
@@ -337,6 +338,9 @@ public class ErrorParserManager extends OutputStream {
// It should not stop parsing of the rest of output.
try {
if (curr.processLine(lineToParse, this)) {
+ ProblemMarkerInfo m = fErrors.size() > 0 ? fErrors.get(0): null;
+ outputLine(line, m);
+ fErrors.clear();
return;
}
} catch (Exception e){
@@ -345,8 +349,29 @@ public class ErrorParserManager extends OutputStream {
}
}
}
+ outputLine(line, null);
}
+ /**
+ * Conditionally output line to outputStream. If stream
+ * supports error markers, use it, otherwise use conventional stream
+ */
+ private void outputLine(String line, ProblemMarkerInfo marker) {
+ String l = line + "\n"; //$NON-NLS-1$
+ if ( outputStream == null ) return;
+ try {
+ if ( marker != null && outputStream instanceof IErrorMarkeredOutputStream ) {
+ IErrorMarkeredOutputStream s = (IErrorMarkeredOutputStream) outputStream;
+ s.write(l, marker);
+ } else {
+ byte[] b = l.getBytes();
+ outputStream.write(b, 0, b.length);
+ }
+ } catch (IOException e) {
+ CCorePlugin.log(e);
+ }
+ }
+
/**
* @return counter counting processed lines of output
* @since 5.2
@@ -500,7 +525,6 @@ public class ErrorParserManager extends OutputStream {
/**
* Add marker to the list of error markers.
- * Markers are actually added in the end of processing in {@link #reportProblems()}.
*
* @param file - resource to add the new marker.
* @param lineNumber - line number of the error.
@@ -514,7 +538,6 @@ public class ErrorParserManager extends OutputStream {
/**
* Add marker to the list of error markers.
- * Markers are actually added in the end of processing in {@link #reportProblems()}.
*
* @param file - resource to add the new marker.
* @param lineNumber - line number of the error.
@@ -530,6 +553,7 @@ public class ErrorParserManager extends OutputStream {
public void generateExternalMarker(IResource file, int lineNumber, String desc, int severity, String varName, IPath externalPath) {
ProblemMarkerInfo problemMarkerInfo = new ProblemMarkerInfo(file, lineNumber, desc, severity, varName, externalPath);
fErrors.add(problemMarkerInfo);
+ fMarkerGenerator.addMarker(problemMarkerInfo);
if (severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE)
hasErrors = true;
}
@@ -544,6 +568,8 @@ public class ErrorParserManager extends OutputStream {
/**
* Method setOutputStream.
+ * Note: you have to close this stream explicitly
+ * don't rely on ErrorParserManager.close().
* @param os - output stream
*/
public void setOutputStream(OutputStream os) {
@@ -551,8 +577,9 @@ public class ErrorParserManager extends OutputStream {
}
/**
- * Method getOutputStream. It has a reference count
- * the stream must be close the same number of time this method was call.
+ * Method getOutputStream.
+ * Note: you have to close this stream explicitly
+ * don't rely on ErrorParserManager.close().
* @return OutputStream
*/
public OutputStream getOutputStream() {
@@ -562,14 +589,14 @@ public class ErrorParserManager extends OutputStream {
/**
* @see java.io.OutputStream#close()
+ * Note: don't rely on this method to close underlying OutputStream,
+ * close it explicitly
*/
@Override
- public void close() throws IOException {
+ public synchronized void close() throws IOException {
if (nOpens > 0 && --nOpens == 0) {
checkLine(true);
fDirectoryStack.removeAllElements();
- if (outputStream != null)
- outputStream.close();
}
}
@@ -589,8 +616,6 @@ public class ErrorParserManager extends OutputStream {
public synchronized void write(int b) throws IOException {
currentLine.append((char) b);
checkLine(false);
- if (outputStream != null)
- outputStream.write(b);
}
@Override
@@ -604,10 +629,12 @@ public class ErrorParserManager extends OutputStream {
}
currentLine.append(new String(b, 0, len));
checkLine(false);
- if (outputStream != null)
- outputStream.write(b, off, len);
}
+ // This method examines contents of currentLine buffer
+ // if it contains whole line this line is checked by error
+ // parsers (processLine method).
+ // If flush is true rest of line is checked by error parsers.
private void checkLine(boolean flush) {
String buffer = currentLine.toString();
int i = 0;
@@ -632,7 +659,8 @@ public class ErrorParserManager extends OutputStream {
}
/**
- * Create actual markers from the list of collected problems.
+ * @deprecated as of 5.2. This method is no longer reporting problems.
+ * The problem markers are generated after processing each line.
*
* @return {@code true} if detected a problem indicating that build failed.
* The semantics of the return code is inconsistent. As far as build is concerned
@@ -640,18 +668,9 @@ public class ErrorParserManager extends OutputStream {
* {@link IMarkerGenerator#SEVERITY_ERROR_RESOURCE} and
* {@link IMarkerGenerator#SEVERITY_ERROR_BUILD}
*/
+ @Deprecated
public boolean reportProblems() {
- boolean reset = false;
- if (nOpens == 0) {
- for (ProblemMarkerInfo problemMarkerInfo : fErrors) {
- if (problemMarkerInfo.severity == IMarkerGenerator.SEVERITY_ERROR_BUILD) {
- reset = true;
- }
- fMarkerGenerator.addMarker(problemMarkerInfo);
- }
- fErrors.clear();
- }
- return reset;
+ return false;
}
/**
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/IErrorMarkeredOutputStream.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/IErrorMarkeredOutputStream.java
new file mode 100644
index 00000000000..096d195f986
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/IErrorMarkeredOutputStream.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2010 CodeSourcery and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Dmitry Kozlov (CodeSourcery) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.core;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+
+/**
+ * Output stream for use in build console capable of processing markers info
+ * attached to the output.
+ * @since 5.2
+ */
+public interface IErrorMarkeredOutputStream {
+
+ public void write(String s, ProblemMarkerInfo marker) throws IOException;
+
+ public void write(byte[] b, int offset, int len) throws IOException;
+
+ public void flush() throws IOException;
+
+ public void close() throws IOException;
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties
index 5d27e61217c..29d4771d182 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties
@@ -29,6 +29,8 @@ ConsolePreferencePage.outputColor.label=Output text color
ConsolePreferencePage.infoColor.label=Information message text color
ConsolePreferencePage.errorColor.label=Error message text color
ConsolePreferencePage.backgroundColor.label=Background color
+ConsolePreferencePage.problemBackgroundColor.label=Background color for build problems
+ConsolePreferencePage.problemHighlightedColor.label=Highlighting color for build problems
# ------- Project/Prefernces/Wizards COnfiguration blocks -------
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsole.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsole.java
index 59a9cbe92c7..cec4127f567 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsole.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsole.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2007 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Red Hat Inc. - Multiple build console support
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
@@ -22,16 +23,24 @@ import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.part.IPageBookViewPage;
public class BuildConsole extends AbstractConsole {
-
+
+ /**
+ * Menu group identifier for the console view context menu and toolbar, for actions pertaining to
+ * error navigation (value "errorGroup"
).
+ */
+ public static final String ERROR_GROUP = "errorGroup"; //$NON-NLS-1$
+
/**
* Property constant indicating the color of a stream has changed.
*/
public static final String P_STREAM_COLOR = CUIPlugin.PLUGIN_ID + ".CONSOLE_P_STREAM_COLOR"; //$NON-NLS-1$
+ private static BuildConsolePage fBuildConsolePage;
+
private IBuildConsoleManager fConsoleManager;
private String fConsoleName;
private String fConsoleId;
- private Color fBackground;
+ private Color fBackground;
public BuildConsole(IBuildConsoleManager manager, String name, String id) {
super(name, CPluginImages.DESC_BUILD_CONSOLE);
@@ -41,7 +50,12 @@ public class BuildConsole extends AbstractConsole {
}
public IPageBookViewPage createPage(IConsoleView view) {
- return new BuildConsolePage(view, this, fConsoleId);
+ fBuildConsolePage = new BuildConsolePage(view, this, fConsoleId);
+ return fBuildConsolePage;
+ }
+
+ static BuildConsolePage getPage() {
+ return fBuildConsolePage;
}
public void setTitle(IProject project) {
@@ -53,7 +67,7 @@ public class BuildConsole extends AbstractConsole {
}
public IBuildConsoleManager getConsoleManager() {
- return fConsoleManager;
+ return fConsoleManager;
}
public void setBackground(Color background) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleManager.java
index 0041f034354..33b3f257882 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleManager.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2007 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - initial API and implementation
* Red Hat Inc. - multiple build console support
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
@@ -53,8 +54,16 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
ListenerList listeners = new ListenerList();
BuildConsole fConsole;
private Map fConsoleMap = new HashMap();
- Color infoColor, outputColor, errorColor, backgroundColor;
- BuildConsoleStream infoStream, outputStream, errorStream;
+ Color infoColor, outputColor, errorColor, backgroundColor, problemHighlightedColor, problemBackgroundColor;
+ public Color getProblemHighlightedColor() {
+ return problemHighlightedColor;
+ }
+
+ public Color getProblemBackgroundColor() {
+ return problemBackgroundColor;
+ }
+
+ BuildConsoleStreamDecorator infoStream, outputStream, errorStream;
String fName, fContextMenuId;
static public final int BUILD_STREAM_TYPE_INFO = 0;
@@ -159,6 +168,8 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
outputColor.dispose();
errorColor.dispose();
backgroundColor.dispose();
+ problemBackgroundColor.dispose();
+ problemHighlightedColor.dispose();
}
ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new org.eclipse.ui.console.IConsole[]{fConsole});
CUIPlugin.getWorkspace().removeResourceChangeListener(this);
@@ -177,9 +188,9 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
}
public void startup(String name, String id) {
- infoStream = new BuildConsoleStream();
- outputStream = new BuildConsoleStream();
- errorStream = new BuildConsoleStream();
+ infoStream = new BuildConsoleStreamDecorator();
+ outputStream = new BuildConsoleStreamDecorator();
+ errorStream = new BuildConsoleStreamDecorator();
fName = name;
fContextMenuId = id;
@@ -205,6 +216,8 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
errorStream.setColor(errorColor);
backgroundColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_BACKGROUND_COLOR);
fConsole.setBackground(backgroundColor);
+ problemHighlightedColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_HIGHLIGHTED_COLOR);
+ problemBackgroundColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_BACKGROUND_COLOR);
}
});
CUIPlugin.getWorkspace().addResourceChangeListener(this);
@@ -239,10 +252,33 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
fConsole.setBackground(newColor);
backgroundColor.dispose();
backgroundColor = newColor;
+ } else if (property.equals(BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_HIGHLIGHTED_COLOR)) {
+ Color newColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_HIGHLIGHTED_COLOR);
+ problemHighlightedColor.dispose();
+ problemHighlightedColor = newColor;
+ redrawTextViewer();
+ } else if (property.equals(BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_BACKGROUND_COLOR)) {
+ Color newColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_BACKGROUND_COLOR);
+ problemBackgroundColor.dispose();
+ problemBackgroundColor = newColor;
+ redrawTextViewer();
}
}
- public BuildConsoleStream getStream(int type) throws CoreException {
+ private void redrawTextViewer() {
+ final BuildConsolePage p = BuildConsole.getPage();
+ if ( p == null ) return;
+ final BuildConsoleViewer v = p.getViewer();
+ if ( v == null ) return;
+ Display display = Display.getDefault();
+ display.asyncExec(new Runnable() {
+ public void run() {
+ v.getTextWidget().redraw();
+ }
+ });
+ }
+
+ public BuildConsoleStreamDecorator getStreamDecorator(int type) throws CoreException {
switch (type) {
case BUILD_STREAM_TYPE_ERROR :
return errorStream;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePage.java
index 4aeed7874c1..ee2d28dabe6 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePage.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2008 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - initial API and implementation
* Red Hat Inc. - multiple build console support
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
@@ -19,9 +20,12 @@ import java.util.Map;
import java.util.ResourceBundle;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
@@ -36,6 +40,7 @@ import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -59,6 +64,8 @@ import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.console.IConsoleConstants;
@@ -66,15 +73,21 @@ import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.actions.ClearOutputAction;
import org.eclipse.ui.console.actions.TextViewerAction;
import org.eclipse.ui.console.actions.TextViewerGotoLineAction;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.texteditor.FindReplaceAction;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.IUpdate;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+import org.eclipse.cdt.core.model.ICModelMarker;
+import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IBuildConsoleEvent;
import org.eclipse.cdt.ui.IBuildConsoleListener;
+import org.eclipse.cdt.ui.IBuildConsoleManager;
import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage;
@@ -86,6 +99,10 @@ public class BuildConsolePage extends Page
ITextListener,
IAdaptable {
+ static final int POSITION_NEXT = -1;
+ static final int POSITION_PREV = -2;
+ static final int POSITION_FIST = -3;
+
private BuildConsole fConsole;
private IConsoleView fConsoleView;
private String fContextMenuId;
@@ -109,6 +126,9 @@ public class BuildConsolePage extends Page
private Menu fMenu;
private ScrollLockAction fScrollLockAction;
private boolean fIsLocked;
+ private NextErrorAction fNextErrorAction;
+ private PreviousErrorAction fPreviousErrorAction;
+ private ShowErrorAction fShowErrorAction;
/**
* @param view
@@ -137,7 +157,13 @@ public class BuildConsolePage extends Page
protected IDocument setDocument() {
IProject project = getProject();
if (project != null) {
- getViewer().setDocument(getConsole().getConsoleManager().getConsoleDocument(project));
+ IBuildConsoleManager consoleManager = getConsole().getConsoleManager();
+ getViewer().setDocument(consoleManager.getConsoleDocument(project));
+ IConsole console = consoleManager.getConsole(project);
+ if ( console instanceof BuildConsolePartitioner) {
+ BuildConsolePartitioner par = (BuildConsolePartitioner)console;
+ showError(par, fShowErrorAction.isChecked() );
+ }
}
return null;
}
@@ -206,6 +232,7 @@ public class BuildConsolePage extends Page
setTabs(CUIPlugin.getDefault().getPluginPreferences().getInt(BuildConsolePreferencePage.PREF_BUILDCONSOLE_TAB_WIDTH));
getConsole().addPropertyChangeListener(this);
+ CUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
fViewer.addTextListener(this);
fViewer.getTextWidget().setBackground(getConsole().getBackground());
@@ -238,8 +265,8 @@ public class BuildConsolePage extends Page
final Object source = event.getSource();
final String property = event.getProperty();
- if (BuildConsole.P_STREAM_COLOR.equals(property) && source instanceof BuildConsoleStream) {
- BuildConsoleStream stream = (BuildConsoleStream)source;
+ if (BuildConsole.P_STREAM_COLOR.equals(property) && source instanceof BuildConsoleStreamDecorator) {
+ BuildConsoleStreamDecorator stream = (BuildConsoleStreamDecorator)source;
if (stream.getConsole().equals(getConsole()) && getControl() != null) {
Display display = getControl().getDisplay();
display.asyncExec(new Runnable() {
@@ -261,6 +288,10 @@ public class BuildConsolePage extends Page
protected void createActions() {
fClearOutputAction = new ClearOutputAction(getViewer());
fScrollLockAction = new ScrollLockAction(getViewer());
+ fNextErrorAction = new NextErrorAction(this);
+ fPreviousErrorAction = new PreviousErrorAction(this);
+ fShowErrorAction = new ShowErrorAction();
+
fScrollLockAction.setChecked(fIsLocked);
getViewer().setAutoScroll(!fIsLocked);
// In order for the clipboard actions to accessible via their shortcuts
@@ -311,6 +342,11 @@ public class BuildConsolePage extends Page
}
protected void configureToolBar(IToolBarManager mgr) {
+ mgr.insertBefore(IConsoleConstants.OUTPUT_GROUP, new GroupMarker(BuildConsole.ERROR_GROUP));
+ mgr.appendToGroup(BuildConsole.ERROR_GROUP, fPreviousErrorAction);
+ mgr.appendToGroup(BuildConsole.ERROR_GROUP, fNextErrorAction);
+ mgr.appendToGroup(BuildConsole.ERROR_GROUP, fShowErrorAction);
+
mgr.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fScrollLockAction);
mgr.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fClearOutputAction);
}
@@ -506,4 +542,88 @@ public class BuildConsolePage extends Page
findReplace.update();
}
}
+
+ /**
+ * Highlight next/previous error or error by console offset
+ * @param position POSITION_NEXT (-1), POSITION_PREV (-2), or offset
+ */
+ void moveToError(int position) {
+ IProject project = getProject();
+ IBuildConsoleManager consoleManager = CUIPlugin.getDefault().getConsoleManager();
+ IConsole console = consoleManager.getConsole(project);
+ if ( console instanceof BuildConsolePartitioner) {
+ BuildConsolePartitioner par = (BuildConsolePartitioner)console;
+ // Move to specified line in the model (BuildConsolePartitioner)
+ if ( position == POSITION_NEXT ) {
+ par.fDocumentMarkerManager.moveToNextError();
+ } else if ( position == POSITION_PREV ) {
+ par.fDocumentMarkerManager.moveToPreviousError();
+ } else if ( position == POSITION_FIST ) {
+ par.fDocumentMarkerManager.moveToFirstError();
+ } else if ( position >= 0 ) {
+ if ( ! par.fDocumentMarkerManager.moveToErrorByOffset(position) ) {
+ // we haven't moved, because offset points to non-error partition
+ return;
+ }
+ }
+ showError(par, position > 0 || fShowErrorAction.isChecked() );
+ }
+ }
+
+ /**
+ * Highlight current error and show it in editor
+ */
+ public void showError(BuildConsolePartitioner par, boolean openInEditor) {
+ // Highlight current error
+ BuildConsolePartition p = par.fDocumentMarkerManager.getCurrentPartition();
+ if ( p == null ) return;
+ getViewer().selectPartition(par, p);
+ // Show error in editor if necessary
+ // (always show when absolute positioning, otherwise depends
+ // on fShowErrorAction state)
+ if ( openInEditor ) {
+ openErrorInEditor(par.fDocumentMarkerManager.getCurrentErrorMarker());
+ }
+ }
+
+ /**
+ * Open error specified by marker in editor
+ */
+ public static void openErrorInEditor(ProblemMarkerInfo marker) {
+ IWorkbenchWindow window = CUIPlugin.getActiveWorkbenchWindow();
+
+ if ( marker == null || marker.file == null || window == null ) return;
+
+ IWorkbenchPage page = window.getActivePage();
+ if (page == null) return;
+
+ IEditorPart editor = page.getActiveEditor();
+ if (editor != null) {
+ IEditorInput input = editor.getEditorInput();
+ IFile file = ResourceUtil.getFile(input);
+ if (file != null && file.equals(marker.file) && OpenStrategy.activateOnOpen()) {
+ page.activate(editor);
+ }
+ }
+
+ if ( marker.file instanceof IFile ) {
+ try {
+ // Find IMarker corresponding to ProblemMarkerInfo
+ IMarker mrkrs[] = marker.file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ONE);
+ for (IMarker m: mrkrs) {
+ if ( marker.lineNumber == ((Integer)m.getAttribute(IMarker.LINE_NUMBER)).intValue() &&
+ marker.description.equals(m.getAttribute(IMarker.MESSAGE)) &&
+ marker.severity == ((Integer)m.getAttribute(IMarker.SEVERITY)).intValue() ) {
+ IDE.openEditor(page, m, OpenStrategy.activateOnOpen());
+ return;
+ }
+ }
+ } catch (PartInitException e) {
+ CUIPlugin.log(e);
+ } catch (CoreException e) {
+ CUIPlugin.log(e);
+ }
+ }
+ }
+
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartition.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartition.java
index 7e695bbf3cc..051cc58fb29 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartition.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartition.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,29 +7,39 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.jface.text.TypedRegion;
public class BuildConsolePartition extends TypedRegion {
- /**
- * Associated stream
- */
- private BuildConsoleStream fStream;
+ /** Associated stream */
+ private BuildConsoleStreamDecorator fStream;
+
+ /** Marker associated with this partition if any */
+ private ProblemMarkerInfo fMarker;
- /**
- * Partition type
- */
+ /** Partition type */
public static final String CONSOLE_PARTITION_TYPE = CUIPlugin.getPluginId() + ".CONSOLE_PARTITION_TYPE"; //$NON-NLS-1$
-
- public BuildConsolePartition(BuildConsoleStream stream, int offset, int length) {
- super(offset, length, CONSOLE_PARTITION_TYPE);
+
+ /** Partition type to report errors in console */
+ public static final String ERROR_PARTITION_TYPE = CUIPlugin.getPluginId() + ".ERROR_PARTITION_TYPE"; //$NON-NLS-1$
+
+ public BuildConsolePartition(BuildConsoleStreamDecorator stream, int offset, int length, String type) {
+ super(offset, length, type);
fStream = stream;
}
+ public BuildConsolePartition(BuildConsoleStreamDecorator stream, int offset, int length, String type, ProblemMarkerInfo marker) {
+ super(offset, length, type);
+ fStream = stream;
+ fMarker = marker;
+ }
+
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -54,7 +64,7 @@ public class BuildConsolePartition extends TypedRegion {
*
* @return this partition's stream
*/
- public BuildConsoleStream getStream() {
+ public BuildConsoleStreamDecorator getStream() {
return fStream;
}
@@ -66,6 +76,9 @@ public class BuildConsolePartition extends TypedRegion {
* @return boolean
*/
public boolean canBeCombinedWith(BuildConsolePartition partition) {
+ // Error partitions never can be combined together
+ if ( getType() == ERROR_PARTITION_TYPE ) return false;
+
int start = getOffset();
int end = start + getLength();
int otherStart = partition.getOffset();
@@ -88,18 +101,20 @@ public class BuildConsolePartition extends TypedRegion {
int otherEnd = otherStart + partition.getLength();
int theStart = Math.min(start, otherStart);
int theEnd = Math.max(end, otherEnd);
- return createNewPartition(theStart, theEnd - theStart);
+ return createNewPartition(theStart, theEnd - theStart, CONSOLE_PARTITION_TYPE);
}
/**
- * Creates a new patition of this type with the given color, offset, and
- * length.
- *
+ * Creates a new partition of this type with the given offset, and length.
* @param offset
* @param length
* @return a new partition with the given range
*/
- public BuildConsolePartition createNewPartition(int offset, int length) {
- return new BuildConsolePartition(getStream(), offset, length);
+ public BuildConsolePartition createNewPartition(int offset, int length, String type) {
+ return new BuildConsolePartition(getStream(), offset, length, type, getMarker());
+ }
+
+ public ProblemMarkerInfo getMarker() {
+ return fMarker;
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartitioner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartitioner.java
index 71201ed2765..85869562a1c 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartitioner.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsolePartitioner.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,10 +7,10 @@
*
* Contributors:
* QNX Software Systems - initial API and implementation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -32,6 +32,7 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.ui.CUIPlugin;
@@ -54,11 +55,13 @@ public class BuildConsolePartitioner
/**
* The stream that was last appended to
*/
- BuildConsoleStream fLastStream = null;
+ BuildConsoleStreamDecorator fLastStream = null;
BuildConsoleDocument fDocument;
+ DocumentMarkerManager fDocumentMarkerManager;
boolean killed;
BuildConsoleManager fManager;
+ Boolean outputStreamClosed = new Boolean(false);
/**
* A queue of stream entries written to standard out and standard err.
@@ -72,24 +75,23 @@ public class BuildConsolePartitioner
class StreamEntry {
- /**
- * Identifier of the stream written to.
- */
- private BuildConsoleStream fStream;
- /**
- * The text written
- */
- private StringBuffer fText = null;
+ /** Identifier of the stream written to. */
+ private BuildConsoleStreamDecorator fStream;
+ /** The text written */
+ private StringBuffer fText = null;
+ /** Problem marker corresponding to the line of text */
+ private ProblemMarkerInfo fMarker;
- StreamEntry(String text, BuildConsoleStream stream) {
+ StreamEntry(String text, BuildConsoleStreamDecorator stream, ProblemMarkerInfo marker) {
fText = new StringBuffer(text);
fStream = stream;
+ fMarker = marker;
}
/**
* Returns the stream identifier
*/
- public BuildConsoleStream getStream() {
+ public BuildConsoleStreamDecorator getStream() {
return fStream;
}
@@ -107,6 +109,14 @@ public class BuildConsolePartitioner
public String getText() {
return fText.toString();
}
+
+ /**
+ * Returns error marker
+ */
+ public ProblemMarkerInfo getMarker() {
+ return fMarker;
+ }
+
}
public BuildConsolePartitioner(BuildConsoleManager manager) {
@@ -114,6 +124,7 @@ public class BuildConsolePartitioner
fMaxLines = BuildConsolePreferencePage.buildConsoleLines();
fDocument = new BuildConsoleDocument();
fDocument.setDocumentPartitioner(this);
+ fDocumentMarkerManager = new DocumentMarkerManager(fDocument, this);
connect(fDocument);
}
@@ -125,8 +136,7 @@ public class BuildConsolePartitioner
* @param stream
* the stream to append to
*/
-
- public void appendToDocument(String text, BuildConsoleStream stream) {
+ public void appendToDocument(String text, BuildConsoleStreamDecorator stream, ProblemMarkerInfo marker) {
boolean addToQueue = true;
synchronized (fQueue) {
int i = fQueue.size();
@@ -134,13 +144,13 @@ public class BuildConsolePartitioner
StreamEntry entry = fQueue.get(i - 1);
// if last stream is the same and we have not exceeded our
// display write limit, append.
- if (entry.getStream() == stream && entry.size() < 10000) {
+ if (entry.getStream() == stream && entry.size() < 10000 && entry.getMarker() == marker) {
entry.appendText(text);
addToQueue = false;
}
}
if (addToQueue) {
- fQueue.add(new StreamEntry(text, stream));
+ fQueue.add(new StreamEntry(text, stream, marker));
}
}
Runnable r = new Runnable() {
@@ -155,12 +165,15 @@ public class BuildConsolePartitioner
fLastStream = entry.getStream();
try {
warnOfContentChange(fLastStream);
- if (fLastStream == null) {
- fDocument.set(entry.getText());
- } else {
- fDocument.replace(fDocument.getLength(), 0, entry.getText());
- checkOverflow();
+
+ if ( fLastStream == null ) {
+ // special case to empty document
+ fPartitions.clear();
+ fDocumentMarkerManager.clear();
+ fDocument.set(""); //$NON-NLS-1$
}
+ addStreamEntryToDocument(entry);
+ checkOverflow();
} catch (BadLocationException e) {
}
}
@@ -171,7 +184,25 @@ public class BuildConsolePartitioner
}
}
- void warnOfContentChange(BuildConsoleStream stream) {
+ private void addStreamEntryToDocument(StreamEntry entry) throws BadLocationException {
+ if ( entry.getMarker() == null ) {
+ // It is plain unmarkered console output
+ addPartition(new BuildConsolePartition(fLastStream,
+ fDocument.getLength(),
+ entry.getText().length(),
+ BuildConsolePartition.CONSOLE_PARTITION_TYPE));
+ } else {
+ // this text line in entry is markered with ProblemMarkerInfo,
+ // create special partition for it.
+ addPartition(new BuildConsolePartition(fLastStream,
+ fDocument.getLength(),
+ entry.getText().length(),
+ BuildConsolePartition.ERROR_PARTITION_TYPE, entry.getMarker()));
+ }
+ fDocument.replace(fDocument.getLength(), 0, entry.getText());
+ }
+
+ void warnOfContentChange(BuildConsoleStreamDecorator stream) {
if (stream != null) {
ConsolePlugin.getDefault().getConsoleManager().warnOfContentChange(stream.getConsole());
}
@@ -237,7 +268,8 @@ public class BuildConsolePartitioner
ITypedRegion partition = fPartitions.get(i);
int partitionStart = partition.getOffset();
int partitionEnd = partitionStart + partition.getLength();
- if ( (offset >= partitionStart && offset <= partitionEnd) || (offset < partitionStart && end >= partitionStart)) {
+ if ( (offset >= partitionStart && offset <= partitionEnd) ||
+ (offset < partitionStart && end >= partitionStart)) {
list.add(partition);
}
}
@@ -266,7 +298,6 @@ public class BuildConsolePartitioner
fPartitions.clear();
return new Region(0, 0);
}
- addPartition(new BuildConsolePartition(fLastStream, event.getOffset(), text.length()));
ITypedRegion[] affectedRegions = computePartitioning(event.getOffset(), text.length());
if (affectedRegions.length == 0) {
return null;
@@ -308,17 +339,19 @@ public class BuildConsolePartitioner
int offset = region.getOffset();
if (offset < overflow) {
int endOffset = offset + region.getLength();
- if (endOffset < overflow) {
- // remove partition
+ if (endOffset < overflow ||
+ messageConsolePartition.getType() == BuildConsolePartition.ERROR_PARTITION_TYPE ) {
+ // remove partition,
+ // partitions with problem markers can't be split - remove them too
} else {
// split partition
int length = endOffset - overflow;
- newPartition = messageConsolePartition.createNewPartition(0, length);
+ newPartition = messageConsolePartition.createNewPartition(0, length, messageConsolePartition.getType());
}
} else {
- // modify parition offset
+ // modify partition offset
newPartition = messageConsolePartition.createNewPartition(messageConsolePartition.getOffset()
- - overflow, messageConsolePartition.getLength());
+ - overflow, messageConsolePartition.getLength(), messageConsolePartition.getType());
}
if (newPartition != null) {
newParitions.add(newPartition);
@@ -326,6 +359,7 @@ public class BuildConsolePartitioner
}
}
fPartitions = newParitions;
+ fDocumentMarkerManager.moveToFirstError();
try {
fDocument.replace(0, overflow, ""); //$NON-NLS-1$
@@ -336,8 +370,7 @@ public class BuildConsolePartitioner
}
/**
- * Adds a new colored input partition, combining with the previous partition
- * if possible.
+ * Adds a new partition, combining with the previous partition if possible.
*/
private BuildConsolePartition addPartition(BuildConsolePartition partition) {
if (fPartitions.isEmpty()) {
@@ -371,7 +404,6 @@ public class BuildConsolePartitioner
Display display = CUIPlugin.getStandardDisplay();
if (display != null) {
display.asyncExec(new Runnable() {
-
public void run() {
fManager.startConsoleActivity(project);
}
@@ -379,43 +411,48 @@ public class BuildConsolePartitioner
}
if (BuildConsolePreferencePage.isClearBuildConsole()) {
- appendToDocument("", null); //$NON-NLS-1$
- }
- }
-
- public class BuildOutputStream extends ConsoleOutputStream {
-
- final BuildConsoleStream fStream;
-
- public BuildOutputStream(BuildConsoleStream stream) {
- fStream = stream;
- }
-
- @Override
- public void flush() throws IOException {
- }
-
- @Override
- public void close() throws IOException {
- flush();
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- appendToDocument(new String(b, off, len), fStream);
+ appendToDocument("", null, null); //$NON-NLS-1$
}
}
public ConsoleOutputStream getOutputStream() throws CoreException {
- return new BuildOutputStream(fManager.getStream(BuildConsoleManager.BUILD_STREAM_TYPE_OUTPUT));
+ outputStreamClosed = Boolean.FALSE;
+ return new BuildOutputStream(this, fManager.getStreamDecorator(BuildConsoleManager.BUILD_STREAM_TYPE_OUTPUT));
}
public ConsoleOutputStream getInfoStream() throws CoreException {
- return new BuildOutputStream(fManager.getStream(BuildConsoleManager.BUILD_STREAM_TYPE_INFO));
+ return new BuildOutputStream(this, fManager.getStreamDecorator(BuildConsoleManager.BUILD_STREAM_TYPE_INFO));
}
public ConsoleOutputStream getErrorStream() throws CoreException {
- return new BuildOutputStream(fManager.getStream(BuildConsoleManager.BUILD_STREAM_TYPE_ERROR));
+ return new BuildOutputStream(this, fManager.getStreamDecorator(BuildConsoleManager.BUILD_STREAM_TYPE_ERROR));
+ }
+
+ /** This method is useful for future debugging and bugfixing */
+ @SuppressWarnings("unused")
+ private void printDocumentPartitioning() {
+ System.out.println("Document partitioning: "); //$NON-NLS-1$
+ for (ITypedRegion tr : fPartitions) {
+ BuildConsolePartition p = (BuildConsolePartition) tr;
+ int start = p.getOffset();
+ int end = p.getOffset() + p.getLength();
+ String text;
+ String isError = "U"; //$NON-NLS-1$
+ if (p.getType() == BuildConsolePartition.ERROR_PARTITION_TYPE) {
+ isError = "E"; //$NON-NLS-1$
+ } else if (p.getType() == BuildConsolePartition.CONSOLE_PARTITION_TYPE) {
+ isError = "C"; //$NON-NLS-1$
+ }
+ try {
+ text = fDocument.get(p.getOffset(), p.getLength());
+ } catch (BadLocationException e) {
+ text = "N/A"; //$NON-NLS-1$
+ }
+ if (text.endsWith("\n")) { //$NON-NLS-1$
+ text = text.substring(0, text.length() - 1);
+ }
+ System.out.println(" " + isError + " " + start + "-" + end + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ ":[" + text + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
-
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleStream.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleStreamDecorator.java
similarity index 87%
rename from core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleStream.java
rename to core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleStreamDecorator.java
index 8fb61eb15b9..363d1d07360 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleStream.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleStreamDecorator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * Copyright (c) 2009, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,13 +7,14 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
import org.eclipse.swt.graphics.Color;
-public class BuildConsoleStream {
+public class BuildConsoleStreamDecorator {
private BuildConsole fConsole = null;
private Color fColor = null;
@@ -22,7 +23,7 @@ public class BuildConsoleStream {
* Constructs a new stream connected to the given console.
*
*/
- public BuildConsoleStream() {
+ public BuildConsoleStreamDecorator() {
}
public void setConsole(BuildConsole console) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleViewer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleViewer.java
index 9d4f922b903..ce5c8ec5b1b 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleViewer.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildConsoleViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2006 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
@@ -17,14 +18,26 @@ import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.LineBackgroundEvent;
+import org.eclipse.swt.custom.LineBackgroundListener;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
-public class BuildConsoleViewer extends TextViewer implements LineStyleListener {
+import org.eclipse.cdt.ui.CUIPlugin;
+
+public class BuildConsoleViewer extends TextViewer
+ implements LineStyleListener,
+ LineBackgroundListener,
+ MouseTrackListener,
+ MouseListener {
protected InternalDocumentListener fInternalDocumentListener = new InternalDocumentListener();
/**
@@ -81,13 +94,15 @@ public class BuildConsoleViewer extends TextViewer implements LineStyleListener
*/
public BuildConsoleViewer(Composite parent) {
super(parent, getSWTStyles());
- getTextWidget().setDoubleClickEnabled(true);
- getTextWidget().setFont(parent.getFont());
- getTextWidget().addLineStyleListener(this);
- getTextWidget().setEditable(false);
- getTextWidget().setWordWrap(true);
+ StyledText styledText = getTextWidget();
+ styledText.addLineStyleListener(this);
+ styledText.addLineBackgroundListener(this);
+ styledText.addMouseTrackListener(this);
+ styledText.setFont(parent.getFont());
+ styledText.setDoubleClickEnabled(true);
+ styledText.setEditable(false);
+ styledText.setWordWrap(true);
}
-
/**
* Returns the SWT style flags used when instantiating this viewer
@@ -121,7 +136,6 @@ public class BuildConsoleViewer extends TextViewer implements LineStyleListener
}
}
-
/*
* (non-Javadoc)
*
@@ -154,21 +168,96 @@ public class BuildConsoleViewer extends TextViewer implements LineStyleListener
*
* @see org.eclipse.swt.custom.LineStyleListener#lineGetStyle(org.eclipse.swt.custom.LineStyleEvent)
*/
- public void lineGetStyle(LineStyleEvent event) {
+ public void lineGetStyle(LineStyleEvent event) {
IDocument document = getDocument();
- if (document != null) {
- BuildConsolePartitioner partitioner = (BuildConsolePartitioner) document.getDocumentPartitioner();
- if (partitioner != null) {
- ITypedRegion[] regions = partitioner.computePartitioning(event.lineOffset, event.lineOffset
- + event.lineText.length());
- StyleRange[] styles = new StyleRange[regions.length];
- for (int i = 0; i < regions.length; i++) {
- BuildConsolePartition partition = (BuildConsolePartition) regions[i];
- Color color = partition.getStream().getColor();
- styles[i] = new StyleRange(partition.getOffset(), partition.getLength(), color, null);
- }
- event.styles = styles;
+ if (document == null) return;
+ BuildConsolePartitioner partitioner = (BuildConsolePartitioner) document.getDocumentPartitioner();
+ if (partitioner == null) return;
+
+ BuildConsolePartition p = partitioner.fDocumentMarkerManager.getCurrentPartition();
+ Color problemHighlightedColor = partitioner.fManager.getProblemHighlightedColor();
+
+ // Note, computePartitioning actually doesn't change anything in partitioning,
+ // but only computes number of affected regions.
+ ITypedRegion[] regions = partitioner.computePartitioning(event.lineOffset, event.lineText.length());
+ StyleRange[] styles = new StyleRange[regions.length];
+ for (int i = 0; i < regions.length; i++) {
+ BuildConsolePartition partition = (BuildConsolePartition) regions[i];
+ Color colorFG = partition.getStream().getColor();
+ Color colorBG = null;
+
+ // Highlight current partition
+ if ( partition == p ) {
+ colorFG = problemHighlightedColor;
}
+ StyleRange styleRange = new StyleRange(partition.getOffset(), partition.getLength(), colorFG, colorBG);
+ styles[i] = styleRange;
+ }
+ event.styles = styles;
+ }
+
+ public void selectPartition(BuildConsolePartitioner partitioner, BuildConsolePartition p) {
+ try {
+ int start = partitioner.getDocument().getLineOfOffset(p.getOffset());
+ int end = partitioner.getDocument().getLineOfOffset(p.getOffset()+p.getLength()-1);
+
+ if ( fAutoScroll ) {
+ // Check if area around this line is visible, scroll if needed
+ int top = getTopIndex();
+ int bottom = getBottomIndex();
+ if ( start < top + 1 ) {
+ setTopIndex(start - 1 > 0 ? start - 1 : 0);
+ } else if ( end > bottom -1 ) {
+ setTopIndex(top + start - bottom + 1);
+ }
+ }
+
+ // Select line
+ StyledText st = getTextWidget();
+ st.redrawRange(0, partitioner.getDocument().getLength(), true);
+
+ } catch (BadLocationException e) {
+ CUIPlugin.log(e);
+ }
+ }
+
+ public void mouseEnter(MouseEvent e) {
+ getTextWidget().addMouseListener(this);
+ }
+
+ public void mouseExit(MouseEvent e) {
+ getTextWidget().removeMouseListener(this);
+ }
+
+ public void mouseHover(MouseEvent e) {
+ }
+
+ public void mouseDoubleClick(MouseEvent e) {
+ int offset = -1;
+ try {
+ Point p = new Point(e.x, e.y);
+ offset = getTextWidget().getOffsetAtLocation(p);
+ BuildConsole.getPage().moveToError(offset);
+ } catch (IllegalArgumentException ex) {
+ }
+ }
+
+ public void mouseDown(MouseEvent e) {
+ }
+
+ public void mouseUp(MouseEvent e) {
+ }
+
+ public void lineGetBackground(LineBackgroundEvent event) {
+ IDocument document = getDocument();
+ if (document == null) return;
+ BuildConsolePartitioner partitioner = (BuildConsolePartitioner) document.getDocumentPartitioner();
+ if (partitioner == null) return;
+
+ BuildConsolePartition partition = (BuildConsolePartition) partitioner.getPartition(event.lineOffset);
+ // Set background for error partitions
+ if ( partition != null && partition.getType() == BuildConsolePartition.ERROR_PARTITION_TYPE ) {
+ event.lineBackground = partitioner.fManager.getProblemBackgroundColor();
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java
new file mode 100644
index 00000000000..c77a0dfbe7a
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - initial API and implementation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.ui.buildconsole;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.core.ConsoleOutputStream;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+
+import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
+
+/**
+ * Output stream which put all output to BuildConsolePartitioner
+ * and informs it when stream is closed
+ */
+public class BuildOutputStream extends ConsoleOutputStream implements IErrorMarkeredOutputStream {
+
+ final BuildConsoleStreamDecorator fStream;
+ private BuildConsolePartitioner fPartitioner;
+
+ public BuildOutputStream(BuildConsolePartitioner partitioner,
+ BuildConsoleStreamDecorator stream) {
+ fPartitioner = partitioner;
+ fStream = stream;
+ }
+
+ @Override
+ public void flush() throws IOException {
+ }
+
+ @Override
+ public void close() throws IOException {
+ flush();
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ fPartitioner.appendToDocument(new String(b, off, len), fStream, null);
+ }
+
+ public void write(String s, ProblemMarkerInfo marker) throws IOException {
+ fPartitioner.appendToDocument(s, fStream, marker);
+
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.java
index 0401acf5aab..0f5dcfafb62 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2008 QNX Software Systems and others.
+ * Copyright (c) 2002, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
@@ -29,6 +30,9 @@ public final class ConsoleMessages extends NLS {
public static String BuildConsolePage_Select__All_Ctrl_A_12;
public static String BuildConsolePage_Select_All;
public static String ScrollLockAction_Scroll_Lock_1;
+ public static String PreviousErrorAction_Tooltip;
+ public static String NextErrorAction_Tooltip;
+ public static String ShowErrorAction_Tooltip;
static {
NLS.initializeMessages(BUNDLE_NAME, ConsoleMessages.class);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.properties
index 7de670862d2..a461e0535e1 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ConsoleMessages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2003, 2008 QNX Software Systems and others.
+# Copyright (c) 2003, 2010 QNX Software Systems and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -20,3 +20,7 @@ BuildConsolePage_Select__All_Ctrl_A_12=Select &All@Ctrl+A
BuildConsolePage_Select_All=Select All
ScrollLockAction_Scroll_Lock_1=Scroll Lock
+
+NextErrorAction_Tooltip=&Next Error
+PreviousErrorAction_Tooltip=&Previous Error
+ShowErrorAction_Tooltip=&Show Error In Editor
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/DocumentMarkerManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/DocumentMarkerManager.java
new file mode 100644
index 00000000000..6f46c9a2c16
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/DocumentMarkerManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2010 CodeSourcery and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Dmitry Kozlov (CodeSourcery) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.ui.buildconsole;
+
+import org.eclipse.jface.text.ITypedRegion;
+
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+
+/**
+ * Manages current position of highlighted error in BuildConsole
+ */
+class DocumentMarkerManager {
+
+ BuildConsoleDocument fDocument;
+ BuildConsolePartitioner fPartitioner;
+
+ int highlightedPartitionIndex = -1;
+
+ DocumentMarkerManager(BuildConsoleDocument document, BuildConsolePartitioner partitioner) {
+ fDocument = document;
+ fPartitioner = partitioner;
+ }
+
+ /** Increment index */
+ void moveToNextError() {
+ if ( fPartitioner.fPartitions.size() == 0 ) return;
+ if ( highlightedPartitionIndex == -1 ) {
+ moveToFirstError();
+ return;
+ }
+ int i = highlightedPartitionIndex + 1;
+ do {
+ if ( i == fPartitioner.fPartitions.size() ) {
+ i = 0;
+ }
+ if ( fPartitioner.fPartitions.get(i).getType() == BuildConsolePartition.ERROR_PARTITION_TYPE ) {
+ highlightedPartitionIndex = i;
+ return;
+ } else {
+ i++;
+ }
+ } while ( highlightedPartitionIndex != i);
+ }
+
+ /** Decrement index */
+ void moveToPreviousError() {
+ if ( fPartitioner.fPartitions.size() == 0 ) return;
+ if ( highlightedPartitionIndex == -1 ) {
+ moveToFirstError();
+ return;
+ }
+
+ int i = highlightedPartitionIndex - 1;
+ do {
+ if ( i == -1 ) {
+ i = fPartitioner.fPartitions.size() - 1;
+ }
+ if ( fPartitioner.fPartitions.get(i).getType() == BuildConsolePartition.ERROR_PARTITION_TYPE ) {
+ highlightedPartitionIndex = i;
+ return;
+ } else {
+ i--;
+ }
+ } while ( highlightedPartitionIndex != i);
+ }
+
+ void moveToFirstError() {
+ for (int i=0; i