diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/TargetBuild.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/TargetBuild.java index 7f7bd0b578b..a496a8556f6 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/TargetBuild.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/TargetBuild.java @@ -100,7 +100,7 @@ public class TargetBuild { static public void buildTargets(Shell shell, final IMakeTarget[] targets) { // Setup the global build console - CUIPlugin.getDefault().getConsoleManager().startGlobalConsole(); + CUIPlugin.getDefault().startGlobalConsole(); saveAllResources(targets); Job targetJob = new Job(MakeUIPlugin.getResourceString("TargetBuild.backgroundTask.name")) { //$NON-NLS-1$ diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildAllConfigurationsAction.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildAllConfigurationsAction.java index 7e7901d3b09..371244d31d8 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildAllConfigurationsAction.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildAllConfigurationsAction.java @@ -38,7 +38,7 @@ public class BuildAllConfigurationsAction implements IObjectActionDelegate { public void run(IAction action) { // Setup the global build console - CUIPlugin.getDefault().getConsoleManager().startGlobalConsole(); + CUIPlugin.getDefault().startGlobalConsole(); for (IProject project : projects) { ICProjectDescription prjd = CoreModel.getDefault().getProjectDescription(project, false); diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildConfigurationsJob.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildConfigurationsJob.java index 6e9ddb0f29d..71e724646f0 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildConfigurationsJob.java +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/actions/BuildConfigurationsJob.java @@ -69,7 +69,7 @@ public class BuildConfigurationsJob extends Job { @Override protected IStatus run(IProgressMonitor monitor) { // Setup the global build console - CUIPlugin.getDefault().getConsoleManager().startGlobalConsole(); + CUIPlugin.getDefault().startGlobalConsole(); IConfiguration[] cfgs = new IConfiguration[cfgDescriptions.length]; for (int i=0; i fConsoleMap = new HashMap(); private Color infoColor; private Color outputColor; @@ -117,10 +110,13 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang static public final int BUILD_STREAM_TYPE_OUTPUT = 1; static public final int BUILD_STREAM_TYPE_ERROR = 2; - static public final String DEFAULT_CONTEXT_MENU_ID = CUIPlugin.PLUGIN_ID + ".CBuildConole"; //$NON-NLS-1$ + static public final String DEFAULT_CONTEXT_MENU_ID = CUIPlugin.PLUGIN_ID + ".CDTBuildConsole"; //$NON-NLS-1$ private IProject fLastProject; + /** + * Default constructor. + */ public BuildConsoleManager() { } @@ -169,7 +165,7 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang } if (consoleView instanceof IConsoleView) { if (BuildConsole.getCurrentPage() == null) - ((IConsoleView)consoleView).display(fGlobalConsole); + ((IConsoleView)consoleView).display(fConsole); else ((IConsoleView)consoleView).display(BuildConsole.getCurrentPage().getConsole()); } @@ -212,6 +208,9 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang } } + /** + * Release resources allocated on {@link #startup(String, String, URL)}. + */ public void shutdown() { if (infoColor != null) { infoColor.dispose(); @@ -223,7 +222,7 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang problemInfoBackgroundColor.dispose(); problemHighlightedColor.dispose(); } - ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new org.eclipse.ui.console.IConsole[]{fGlobalConsole, fConsole}); + ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new org.eclipse.ui.console.IConsole[]{fConsole}); CUIPlugin.getWorkspace().removeResourceChangeListener(this); CUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); } @@ -239,7 +238,38 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang } } + /** + * Create new build console. Subclasses may override to create a specialized + * console. + * + * @param name - name of console to appear in the list of consoles in context menu + * in the Console view. + * @param contextId - context menu id in the Console view. + * @param iconUrl - a {@link URL} of the icon for the context menu of the Console + * view. The url is expected to point to an image in eclipse OSGi bundle. + * {@code iconUrl} can be null, in that case the default image is used. + * @return newly created build console. + */ + protected BuildConsole createBuildConsole(String name, String contextId, final URL iconUrl) { + return new BuildConsole(this, name, contextId, iconUrl); + } + + /** + * Start console activities. This will create a new console in the Console view, + * create streams, color resources, register listeners etc. + * Most work is done in UI thread. + * + * Use {@link #shutdown()} after the console activity ends. + * + * @param name - name of the console to appear in the Console view. + * @param contextId - context menu id in the Console view. + * @param iconUrl - icon to show in the context menu. + */ public void startup(String name, String contextId, final URL iconUrl) { + // Ensure global console is initialized before any other build console + if (!(this instanceof GlobalBuildConsoleManager)) + GlobalBuildConsoleManager.startup(); + infoStream = new BuildConsoleStreamDecorator(); outputStream = new BuildConsoleStreamDecorator(); errorStream = new BuildConsoleStreamDecorator(); @@ -254,10 +284,10 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang * @see java.lang.Runnable#run() */ public void run() { - // install colors - fGlobalConsole = new GlobalBuildConsole(BuildConsoleManager.this, fName, null); - fConsole = new BuildConsole(BuildConsoleManager.this, fName, fContextMenuId, iconUrl); - ConsolePlugin.getDefault().getConsoleManager().addConsoles(new org.eclipse.ui.console.IConsole[]{fGlobalConsole, fConsole}); + // add console to the Console view + fConsole = createBuildConsole(fName, fContextMenuId, iconUrl); + ConsolePlugin.getDefault().getConsoleManager().addConsoles(new org.eclipse.ui.console.IConsole[]{fConsole}); + infoStream.setConsole(fConsole); infoColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_INFO_COLOR); infoStream.setColor(infoColor); @@ -269,7 +299,6 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang errorStream.setColor(errorColor); backgroundColor = createBackgroundColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_BACKGROUND_COLOR); fConsole.setBackground(backgroundColor); - fGlobalConsole.setBackground(backgroundColor); problemHighlightedColor = createColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_HIGHLIGHTED_COLOR); problemErrorBackgroundColor = createBackgroundColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_BACKGROUND_COLOR); problemWarningBackgroundColor = createBackgroundColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_WARNING_BACKGROUND_COLOR); @@ -306,7 +335,6 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang } else if (property.equals(BuildConsolePreferencePage.PREF_BUILDCONSOLE_BACKGROUND_COLOR)) { Color newColor = createBackgroundColor(CUIPlugin.getStandardDisplay(), BuildConsolePreferencePage.PREF_BUILDCONSOLE_BACKGROUND_COLOR); fConsole.setBackground(newColor); - fGlobalConsole.setBackground(newColor); backgroundColor.dispose(); backgroundColor = newColor; } else if (property.equals(BuildConsolePreferencePage.PREF_BUILDCONSOLE_PROBLEM_HIGHLIGHTED_COLOR)) { @@ -381,28 +409,26 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang } /** - * Returns the console for the project, or null if none. + * {@inheritDoc} */ public IConsole getConsole(IProject project) { - return new MultiBuildConsoleAdapter(getProjectConsole(project), getGlobalConsole()); + return new MultiBuildConsoleAdapter(getProjectConsole(project), GlobalBuildConsoleManager.getGlobalConsole()); } /** - * @return the console for the specified project + * {@inheritDoc} + * + * @return the console for the specified project. Returns {@code null} + * if project is {@code null} or not accessible. */ public IConsole getProjectConsole(IProject project) { - Assert.isNotNull(project); + if (project==null || !project.isAccessible()) + return null; + fLastProject = project; return getProjectConsolePartioner(project).getConsole(); } - /** - * @return the global build console - */ - public IConsole getGlobalConsole() { - return getGlobalConsolePartitioner().getConsole(); - } - /* * (non-Javadoc) * @@ -424,31 +450,6 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang return partitioner; } - /** - * @return the partitioner for the global build console - */ - private BuildConsolePartitioner getGlobalConsolePartitioner() { - if (fGlobalConsolePartitioner == null) - fGlobalConsolePartitioner = new BuildConsolePartitioner(this); - return fGlobalConsolePartitioner; - } - - /** - * Start the global console; called at the start of the build. - * Clears the contents of the console and sets up the log output stream. - */ - public void startGlobalConsole() { - if (BuildConsolePreferencePage.isClearBuildConsole()) - getGlobalConsolePartitioner().appendToDocument("", null, null); //$NON-NLS-1$ - getGlobalConsolePartitioner().setStreamOpened(); - } - - public void stopGlobalConsole() { - // Doesn't do anything currently. This would be a cleaner place to close the global console - // log, but there is nowhere in CDT that can invoke it at the end of the entire build. - // Instead, the log is repeatedly closed and opened for append by each project build. - } - /** * @return the document backing the build console for the specified project */ @@ -457,13 +458,6 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang return getProjectConsolePartioner(project).getDocument(); } - /** - * @return the document backing the global build console - */ - public IDocument getGlobalConsoleDocument() { - return getGlobalConsolePartitioner().getDocument(); - } - public void addConsoleListener(IBuildConsoleListener listener) { listeners.add(listener); } @@ -473,35 +467,50 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang } /** - * @return logging preferences for a given project or for the workspace. - * @param project to get logging preferences for; or null for the workspace. + * @return logging preferences for a given project. + * @param project to get logging preferences for, can't be {@code null}. */ - public static Preferences getBuildLogPreferences(IProject project) { - if (project == null) - return InstanceScope.INSTANCE.getNode(QUALIFIER).node(GLOBAL_BUILD_CONSOLE_NODE); - else - return new LocalProjectScope(project).getNode(QUALIFIER).node(BUILD_CONSOLE_NODE); + public Preferences getBuildLogPreferences(IProject project) { + return new LocalProjectScope(project).getNode(PREF_QUALIFIER).node(BUILD_CONSOLE_NODE); } /** - * @return logging preference store for a given project; or for the workspace. - * @param project to get logging preferences for; or null for the workspace. + * @return default location of logs for a project. + * @param project to get default log location for, can't be {@code null}. */ - public static IPreferenceStore getBuildLogPreferenceStore(IProject project) { - if (project == null) - return new ScopedPreferenceStore(InstanceScope.INSTANCE, QUALIFIER + "/" + GLOBAL_BUILD_CONSOLE_NODE); //$NON-NLS-1$ - else - return new ScopedPreferenceStore(new LocalProjectScope(project), QUALIFIER + "/" + BUILD_CONSOLE_NODE); //$NON-NLS-1$ - } - - /** - * @return default location of logs for a project or for the workspace. - * @param project to get default log location for; or null for the workspace. - */ - public static String getDefaultConsoleLogLocation(IProject project) { - String name = project == null ? GLOBAL_LOG_FILE : project.getName() + PROJECT_LOG_EXT; - IPath defaultLogLocation = CUIPlugin.getDefault().getStateLocation().append(name); + public String getDefaultConsoleLogLocation(IProject project) { + IPath defaultLogLocation = CUIPlugin.getDefault().getStateLocation().append(project.getName() + PROJECT_LOG_EXT); return defaultLogLocation.toOSString(); } + /** + * Where the log for per-project console is kept. + * + * @param project - the project. Cannot be {@code null}. + * @return {@link URI} of build log or {@code null} if not available. + */ + public URI getLogURI(IProject project) { + Assert.isNotNull(project); + + if (fContextMenuId!=DEFAULT_CONTEXT_MENU_ID) + return null; + + URI logURI = null; + + Preferences prefs = getBuildLogPreferences(project); + boolean keepLog = prefs.getBoolean(KEY_KEEP_LOG, CONSOLE_KEEP_LOG_DEFAULT); + if (keepLog) { + String strLocation; + strLocation = prefs.get(KEY_LOG_LOCATION, getDefaultConsoleLogLocation(project)); + if (strLocation.trim().length()>0) { + logURI = URIUtil.toURI(strLocation); + } + if (logURI==null) { + IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID,"Can't determine URI for location=["+strLocation+"]"); //$NON-NLS-1$ //$NON-NLS-2$ + CUIPlugin.log(status); + } + } + return logURI; + } + } 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 5602aaa1df2..b45a085fdac 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 @@ -163,15 +163,8 @@ public class BuildConsolePage extends Page IProject project = getProject(); if (project != null) { IBuildConsoleManager consoleManager = getConsole().getConsoleManager(); - IDocument document; - IConsole console; - if (getConsole() instanceof GlobalBuildConsole) { - document = consoleManager.getGlobalConsoleDocument(); - console = consoleManager.getGlobalConsole(); - } else { - document = consoleManager.getConsoleDocument(project); - console = consoleManager.getProjectConsole(project); - } + IDocument document = consoleManager.getConsoleDocument(project); + IConsole console = consoleManager.getProjectConsole(project); getViewer().setDocument(document); if (console instanceof BuildConsolePartitioner) { BuildConsolePartitioner par = (BuildConsolePartitioner)console; @@ -563,13 +556,8 @@ public class BuildConsolePage extends Page * Get the current CDT IConsole being displayed on the page */ private IConsole getCurrentConsole() { - BuildConsoleManager consoleManager = (BuildConsoleManager)CUIPlugin.getDefault().getConsoleManager(); - if (getConsole() instanceof GlobalBuildConsole) - return consoleManager.getGlobalConsole(); - else if (getProject() == null) - return null; - else - return consoleManager.getProjectConsole(getProject()); + IBuildConsoleManager consoleManager = fConsole.getConsoleManager(); + return consoleManager.getProjectConsole(getProject()); } /** 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 d975c539793..648bed37d05 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 @@ -23,12 +23,9 @@ import java.util.Vector; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; @@ -41,7 +38,6 @@ import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.console.ConsolePlugin; -import org.osgi.service.prefs.Preferences; import org.eclipse.cdt.core.ConsoleOutputStream; import org.eclipse.cdt.core.ProblemMarkerInfo; @@ -209,27 +205,6 @@ public class BuildConsolePartitioner asyncProcessQueue(); } - /** - * @return {@link URI} of build log or {@code null} if not available. - */ - static private URI getLogURI(IProject project) { - URI logURI = null; - - Preferences prefs = BuildConsoleManager.getBuildLogPreferences(project); - boolean keepLog = prefs.getBoolean(BuildConsoleManager.KEY_KEEP_LOG, BuildConsoleManager.CONSOLE_KEEP_LOG_DEFAULT); - if (keepLog) { - String strLocation = prefs.get(BuildConsoleManager.KEY_LOG_LOCATION, BuildConsoleManager.getDefaultConsoleLogLocation(project)); - if (strLocation.trim().length()>0) { - logURI = URIUtil.toURI(strLocation); - } - if (logURI==null) { - IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID,"Can't determine URI for location=["+strLocation+"]"); //$NON-NLS-1$ //$NON-NLS-2$ - CUIPlugin.log(status); - } - } - return logURI; - } - /** * Adds the new text to the document. * @@ -308,7 +283,7 @@ public class BuildConsolePartitioner * @param append Set to true if the log should be opened for appending, false for overwriting. */ private void logOpen(boolean append) { - fLogURI = getLogURI(fProject); + fLogURI = fManager.getLogURI(fProject); if (fLogURI!=null) { try { IFileStore logStore = EFS.getStore(fLogURI); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/CopyBuildLogAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/CopyBuildLogAction.java index aa463ae5a35..31bc00bd753 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/CopyBuildLogAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/CopyBuildLogAction.java @@ -48,19 +48,13 @@ public class CopyBuildLogAction extends Action { @Override public void run() { - IBuildConsoleManager consoleManager = CUIPlugin.getDefault().getConsoleManager(); - IConsole console; - if (fConsolePage.getConsole() instanceof GlobalBuildConsole) - console = consoleManager.getGlobalConsole(); - else { - IProject project = fConsolePage.getProject(); - if (project == null || !project.isAccessible()) - return; - console = consoleManager.getProjectConsole(project); - } + IBuildConsoleManager consoleManager = fConsolePage.getConsole().getConsoleManager(); + IProject project = fConsolePage.getProject(); + IConsole console = consoleManager.getProjectConsole(project); + + Shell shell = Display.getCurrent().getActiveShell(); if (console instanceof BuildConsolePartitioner) { - Shell shell = Display.getCurrent().getActiveShell(); URI srcURI = ((BuildConsolePartitioner)console).getLogURI(); if (srcURI==null) { MessageDialog.openWarning(shell, ConsoleMessages.CopyLog_UnavailableLog, @@ -107,6 +101,9 @@ public class CopyBuildLogAction extends Action { ResourcesUtil.refreshWorkspaceFiles(destURI); } } + } else { + MessageDialog.openWarning(shell, ConsoleMessages.CopyLog_UnavailableLog, + ConsoleMessages.CopyLog_BuildNotLogged); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsole.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsole.java index 15c598f9d73..5e9f39376fc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsole.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsole.java @@ -10,16 +10,17 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.buildconsole; +import java.net.URL; + import org.eclipse.cdt.ui.IBuildConsoleManager; import org.eclipse.core.resources.IProject; /** - * Customised BuildConsole for the global console that displays its title differently + * Customized BuildConsole for the global console that displays its title differently */ public class GlobalBuildConsole extends BuildConsole { - public GlobalBuildConsole(IBuildConsoleManager manager, String name, String id) { - super(manager, name, id); - setName(ConsoleMessages.BuildConsole_GlobalConsole); + public GlobalBuildConsole(IBuildConsoleManager manager, String name, String contextId, URL iconUrl) { + super(manager, name, contextId, iconUrl); } @Override diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsoleManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsoleManager.java new file mode 100644 index 00000000000..d841cef88d4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/GlobalBuildConsoleManager.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2011 Jeff Johnston (Red Hat Inc.) 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: + * Jeff Johnston (Red Hat Inc.), Andrew Gvozdev - initial implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.buildconsole; + +import java.net.URI; +import java.net.URL; + +import org.eclipse.core.filesystem.URIUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.service.prefs.Preferences; + +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage; + +/** + * Build console manager managing the global CDT build console. + * Singleton. + * + */ +public class GlobalBuildConsoleManager extends BuildConsoleManager { + private static final String GLOBAL_BUILD_CONSOLE_NODE = "globalBuildConsole"; //$NON-NLS-1$ + private static final String GLOBAL_LOG_FILE = "global-build.log"; //$NON-NLS-1$ + + private static final String GLOBAL_CONTEXT_MENU_ID = CUIPlugin.PLUGIN_ID + ".CDTGlobalBuildConsole"; //$NON-NLS-1$ + + /** Singleton instance */ + private static GlobalBuildConsoleManager INSTANCE = null; + private static BuildConsolePartitioner fGlobalConsolePartitioner = null; + + /** + * Default constructor is private. The only instance will be created on + * access of static methods and assigned to {@link #INSTANCE}. + */ + private GlobalBuildConsoleManager() { + // startup is in the constructor to ensure starting only once + startup(ConsoleMessages.BuildConsole_GlobalConsole, GLOBAL_CONTEXT_MENU_ID, null); + } + + /** + * @return get instance creating one if necessary. + */ + private static GlobalBuildConsoleManager getInstance() { + if (INSTANCE==null) + INSTANCE = new GlobalBuildConsoleManager(); + return INSTANCE; + } + + /** + * @return get global console partitioner creating one if necessary. + */ + private static BuildConsolePartitioner getConsolePartitioner() { + if (fGlobalConsolePartitioner==null) { + fGlobalConsolePartitioner = new BuildConsolePartitioner(getInstance()); + } + return fGlobalConsolePartitioner; + } + + + /** + * Start the console. This will call {@link #startup(String, String, URL)} + * to add the global console to the Console view. + */ + public static void startup() { + // instantiate the INSTANCE + getInstance(); + } + + /** + * Stop the console and deallocate resources allocated during {@link #startup()} + */ + public static void stop() { + // avoid initializing INSTANCE needlessly during shutdown + if (INSTANCE!=null) + INSTANCE.shutdown(); + } + + @Override + protected BuildConsole createBuildConsole(String name, String contextId, final URL iconUrl) { + return new GlobalBuildConsole(this, name, contextId, iconUrl); + } + + /** + * @return the global build console. + */ + public static IConsole getGlobalConsole() { + return getConsolePartitioner().getConsole(); + } + + /** + * Start the global console; called at the start of the build. + * Clears the contents of the console and sets up the log output stream. + */ + public static void startGlobalConsole() { + if (BuildConsolePreferencePage.isClearBuildConsole()) + getConsolePartitioner().appendToDocument("", null, null); //$NON-NLS-1$ + getConsolePartitioner().setStreamOpened(); + } + + /** + * Intended to handle event after console output for the whole build including + * referenced projects finished. Currently this event is not triggered and + * the function does nothing. + */ + public static void stopGlobalConsole() { + // Doesn't do anything currently. This would be a cleaner place to close the global console + // log, but there is nowhere in CDT that can invoke it at the end of the entire build. + // Instead, the log is repeatedly closed and opened for append by each project build. + } + + /** + * @return logging preference store for the workspace. + */ + public static IPreferenceStore getBuildLogPreferenceStore() { + return new ScopedPreferenceStore(InstanceScope.INSTANCE, PREF_QUALIFIER + "/" + GLOBAL_BUILD_CONSOLE_NODE); //$NON-NLS-1$ + } + + /** + * @return logging preferences for the workspace. + */ + public static Preferences getBuildLogPreferences() { + return InstanceScope.INSTANCE.getNode(PREF_QUALIFIER).node(GLOBAL_BUILD_CONSOLE_NODE); + } + + /** + * @return default location of logs for the workspace. + */ + public static String getDefaultConsoleLogLocation() { + IPath defaultLogLocation = CUIPlugin.getDefault().getStateLocation().append(GLOBAL_LOG_FILE); + return defaultLogLocation.toOSString(); + } + + @Override + public IConsole getConsole(IProject project) { + return getGlobalConsole(); + } + + @Override + public IConsole getProjectConsole(IProject project) { + return getGlobalConsole(); + } + + @Override + public IDocument getConsoleDocument(IProject project) { + return getConsolePartitioner().getDocument(); + } + + @Override + public IProject getLastBuiltProject() { + return null; + } + + /** + * @return {@link URI} of the global build log or {@code null} if not available. + */ + @Override + public URI getLogURI(IProject project) { + URI logURI = null; + + Preferences prefs = getBuildLogPreferences(); + boolean keepLog = prefs.getBoolean(KEY_KEEP_LOG, CONSOLE_KEEP_LOG_DEFAULT); + if (keepLog) { + String strLocation = prefs.get(KEY_LOG_LOCATION, getDefaultConsoleLogLocation()); + if (strLocation.trim().length()>0) { + logURI = URIUtil.toURI(strLocation); + } + if (logURI==null) { + IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID,"Can't determine URI for location=["+strLocation+"]"); //$NON-NLS-1$ //$NON-NLS-2$ + CUIPlugin.log(status); + } + } + return logURI; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ShowErrorAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ShowErrorAction.java index 923a7b4abe4..7fbd327cee6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ShowErrorAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/ShowErrorAction.java @@ -18,7 +18,6 @@ import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.cdt.core.resources.IConsole; -import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.IBuildConsoleManager; /** @@ -45,15 +44,9 @@ public class ShowErrorAction extends Action { public void run() { super.run(); if (isChecked()) { - IBuildConsoleManager consoleManager = CUIPlugin.getDefault().getConsoleManager(); + IBuildConsoleManager consoleManager = fConsolePage.getConsole().getConsoleManager(); IProject project = fConsolePage.getProject(); - IConsole console; - if (fConsolePage.getConsole() instanceof GlobalBuildConsole) - console = consoleManager.getGlobalConsole(); - else if (project == null) - return; - else - console = consoleManager.getProjectConsole(project); + IConsole console = consoleManager.getProjectConsole(project); if (console instanceof BuildConsolePartitioner) { BuildConsolePartitioner par = (BuildConsolePartitioner)console; fConsolePage.showError(par, true); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/BuildGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/BuildGroup.java index 3d476d8a58a..1567d45c24f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/BuildGroup.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/cview/BuildGroup.java @@ -80,7 +80,7 @@ public class BuildGroup extends CViewActionGroup { saveEditors(prjs); // Clear the build console, and open a stream - CUIPlugin.getDefault().getConsoleManager().startGlobalConsole(); + CUIPlugin.getDefault().startGlobalConsole(); // Now delegate to the parent super.run(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/BuildLogPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/BuildLogPreferencePage.java index 938f9b3d6f6..357062e03cc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/BuildLogPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/BuildLogPreferencePage.java @@ -52,7 +52,8 @@ public class BuildLogPreferencePage extends PropertyPage implements ICOptionCont IProject project = getProject(); isProjectLevel= project != null; if(isProjectLevel) { - Preferences prefs = BuildConsoleManager.getBuildLogPreferences(project); + BuildConsoleManager consoleManager = getConsoleManager(); + Preferences prefs = consoleManager.getBuildLogPreferences(project); Composite contents = ControlFactory.createCompositeEx(parent, 3, GridData.FILL_BOTH); ((GridLayout) contents.getLayout()).makeColumnsEqualWidth = false; @@ -78,7 +79,7 @@ public class BuildLogPreferencePage extends PropertyPage implements ICOptionCont ((GridData) logLocationLabel.getLayoutData()).grabExcessHorizontalSpace = false; logLocationText = ControlFactory.createTextField(contents, SWT.SINGLE | SWT.BORDER); - String logLocation = prefs.get(BuildConsoleManager.KEY_LOG_LOCATION, BuildConsoleManager.getDefaultConsoleLogLocation(project)); + String logLocation = prefs.get(BuildConsoleManager.KEY_LOG_LOCATION, consoleManager.getDefaultConsoleLogLocation(project)); logLocationText.setText(logLocation); logLocationText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { @@ -113,15 +114,16 @@ public class BuildLogPreferencePage extends PropertyPage implements ICOptionCont protected void performDefaults() { if(isProjectLevel) { IProject project = getProject(); - Preferences prefs = BuildConsoleManager.getBuildLogPreferences(project); - prefs.put(BuildConsoleManager.KEY_LOG_LOCATION, BuildConsoleManager.getDefaultConsoleLogLocation(project)); + BuildConsoleManager consoleManager = getConsoleManager(); + Preferences prefs = consoleManager.getBuildLogPreferences(project); + prefs.put(BuildConsoleManager.KEY_LOG_LOCATION, consoleManager.getDefaultConsoleLogLocation(project)); prefs.putBoolean(BuildConsoleManager.KEY_KEEP_LOG, BuildConsoleManager.CONSOLE_KEEP_LOG_DEFAULT); try { prefs.flush(); } catch (BackingStoreException e) { CUIPlugin.log(e); } - logLocationText.setText(prefs.get(BuildConsoleManager.KEY_LOG_LOCATION, BuildConsoleManager.getDefaultConsoleLogLocation(project))); + logLocationText.setText(prefs.get(BuildConsoleManager.KEY_LOG_LOCATION, consoleManager.getDefaultConsoleLogLocation(project))); enableLoggingCheckbox.setSelection(prefs.getBoolean(BuildConsoleManager.KEY_KEEP_LOG, BuildConsoleManager.CONSOLE_KEEP_LOG_DEFAULT)); updateEnablements(); } @@ -131,7 +133,8 @@ public class BuildLogPreferencePage extends PropertyPage implements ICOptionCont @Override public boolean performOk() { if(isProjectLevel) { - Preferences prefs = BuildConsoleManager.getBuildLogPreferences(getProject()); + BuildConsoleManager consoleManager = getConsoleManager(); + Preferences prefs = consoleManager.getBuildLogPreferences(getProject()); prefs.put(BuildConsoleManager.KEY_LOG_LOCATION, logLocationText.getText()); prefs.putBoolean(BuildConsoleManager.KEY_KEEP_LOG, enableLoggingCheckbox.getSelection()); try { @@ -154,6 +157,10 @@ public class BuildLogPreferencePage extends PropertyPage implements ICOptionCont return project; } + private BuildConsoleManager getConsoleManager() { + return (BuildConsoleManager)CUIPlugin.getDefault().getConsoleManager(); + } + @Deprecated public org.eclipse.core.runtime.Preferences getPreferences() { throw new UnsupportedOperationException(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/GlobalBuildLogPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/GlobalBuildLogPreferencePage.java index f15be53f4ca..8bd9929096b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/GlobalBuildLogPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/GlobalBuildLogPreferencePage.java @@ -23,6 +23,7 @@ import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.cdt.internal.ui.buildconsole.BuildConsoleManager; +import org.eclipse.cdt.internal.ui.buildconsole.GlobalBuildConsoleManager; /** * Preference page for build logging options, such as whether the @@ -31,7 +32,7 @@ import org.eclipse.cdt.internal.ui.buildconsole.BuildConsoleManager; public class GlobalBuildLogPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { public GlobalBuildLogPreferencePage() { super(GRID); - setPreferenceStore(BuildConsoleManager.getBuildLogPreferenceStore(null)); + setPreferenceStore(GlobalBuildConsoleManager.getBuildLogPreferenceStore()); } /** @@ -65,12 +66,12 @@ public class GlobalBuildLogPreferencePage extends FieldEditorPreferencePage impl } public void init(IWorkbench workbench) { - initDefaults(BuildConsoleManager.getBuildLogPreferenceStore(null)); + initDefaults(GlobalBuildConsoleManager.getBuildLogPreferenceStore()); } public static void initDefaults(IPreferenceStore prefs) { prefs.setDefault(BuildConsoleManager.KEY_KEEP_LOG, BuildConsoleManager.CONSOLE_KEEP_LOG_DEFAULT); prefs.setDefault(BuildConsoleManager.KEY_LOG_LOCATION, - BuildConsoleManager.getDefaultConsoleLogLocation(null)); + GlobalBuildConsoleManager.getDefaultConsoleLogLocation()); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java index 9ea7e522bbc..7c68d7fda2b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java @@ -29,6 +29,7 @@ import java.util.Set; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdapterManager; import org.eclipse.core.runtime.IConfigurationElement; @@ -88,6 +89,7 @@ import org.eclipse.cdt.internal.ui.ICStatusConstants; import org.eclipse.cdt.internal.ui.IContextMenuConstants; import org.eclipse.cdt.internal.ui.ResourceAdapterFactory; import org.eclipse.cdt.internal.ui.buildconsole.BuildConsoleManager; +import org.eclipse.cdt.internal.ui.buildconsole.GlobalBuildConsoleManager; import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.CDocumentProvider; import org.eclipse.cdt.internal.ui.editor.WorkingCopyManager; @@ -502,6 +504,7 @@ public class CUIPlugin extends AbstractUIPlugin { * * @param name - console name. * @param contextId - console id matching context id in the Console view dropdown. + * Can't be {@code null}. * @param iconUrl - a {@link URL} of the icon for the context menu of the Console * view. The url is expected to point to an image in eclipse OSGi bundle. * {@code iconUrl} can be null, in that case the default image is used. @@ -510,6 +513,8 @@ public class CUIPlugin extends AbstractUIPlugin { * @noreference This method is not intended to be referenced by clients. */ public IBuildConsoleManager getConsoleManager(String name, String contextId, URL iconUrl) { + Assert.isNotNull(contextId); + BuildConsoleManager manager = fBuildConsoleManagers.get(contextId); if (manager == null ) { manager = new BuildConsoleManager(); @@ -519,6 +524,12 @@ public class CUIPlugin extends AbstractUIPlugin { return manager; } + /** + * @since 5.3 + */ + public void startGlobalConsole() { + GlobalBuildConsoleManager.startGlobalConsole(); + } /* * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ @@ -598,6 +609,8 @@ public class CUIPlugin extends AbstractUIPlugin { } fBuildConsoleManagers.clear(); } + + GlobalBuildConsoleManager.stop(); unregisterAdapters(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/IBuildConsoleManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/IBuildConsoleManager.java index 5b0f6240aff..d9f4fccab78 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/IBuildConsoleManager.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/IBuildConsoleManager.java @@ -30,16 +30,6 @@ public interface IBuildConsoleManager { * @since 5.3 */ IConsole getProjectConsole(IProject project); - /** - * @return the global console - * @since 5.3 - */ - IConsole getGlobalConsole(); - /** - * @return the document backing the global console - * @since 5.3 - */ - IDocument getGlobalConsoleDocument(); /** * @param project * @return IDocument backing the console for the given project @@ -49,14 +39,4 @@ public interface IBuildConsoleManager { void addConsoleListener(IBuildConsoleListener listener); void removeConsoleListener(IBuildConsoleListener listener); - /** - * Setup the the global console at the start of the build - * @since 5.3 - */ - void startGlobalConsole(); - /** - * Tear down the the global console at the start of the build - * @since 5.3 - */ - void stopGlobalConsole(); }