1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-14 12:35:22 +02:00

bug 306222: Further enhancement of Save Build Console feature

This commit is contained in:
Andrew Gvozdev 2010-05-21 13:53:29 +00:00
parent 65be0d654f
commit c7d29290dd
13 changed files with 565 additions and 184 deletions

View file

@ -216,6 +216,8 @@ DeleteRcConfigAction.label=Reset to Default...
ExcludeAction.label=Exclude from Build...
BuildConfigurationActionSet.descr=Build active configuration for the current project
BuildLoggingPreferencePage.name=Logging
# Common Editor ruler actions
AddTask.label=Add &Task...
AddTask.tooltip=Add Task...

View file

@ -2632,6 +2632,18 @@
</adapt>
</enabledWhen>
</page>
<page
name="%BuildLoggingPreferencePage.name"
id="org.eclipse.cdt.managedbuilder.ui.properties.BuildLogPreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.BuildLogPreferencePage"
category="org.eclipse.cdt.managedbuilder.ui.properties.Page_head_build">
<keywordReference id="org.eclipse.cdt.ui.common"/>
<enabledWhen>
<adapt type="org.eclipse.core.resources.IProject">
<test property="org.eclipse.core.resources.projectNature" value="org.eclipse.cdt.core.cnature"/>
</adapt>
</enabledWhen>
</page>
</extension>
<extension

View file

@ -12,19 +12,23 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.util.IPropertyChangeListener;
@ -40,6 +44,7 @@ import org.eclipse.ui.PartInitException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleView;
import org.osgi.service.prefs.Preferences;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.ui.CUIPlugin;
@ -47,9 +52,16 @@ import org.eclipse.cdt.ui.IBuildConsoleEvent;
import org.eclipse.cdt.ui.IBuildConsoleListener;
import org.eclipse.cdt.ui.IBuildConsoleManager;
import org.eclipse.cdt.internal.core.LocalProjectScope;
import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage;
public class BuildConsoleManager implements IBuildConsoleManager, IResourceChangeListener, IPropertyChangeListener {
private static final String QUALIFIER = CUIPlugin.PLUGIN_ID;
private static final String BUILD_CONSOLE_NODE = "buildConsole"; //$NON-NLS-1$
public static final String KEY_KEEP_LOG = "keepLog"; //$NON-NLS-1$
public static final String KEY_LOG_LOCATION = "logLocation"; //$NON-NLS-1$
public static final boolean CONSOLE_KEEP_LOG_DEFAULT = true;
ListenerList listeners = new ListenerList();
BuildConsole fConsole;
@ -319,7 +331,7 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
private BuildConsolePartitioner getConsolePartioner(IProject project) {
BuildConsolePartitioner partioner = fConsoleMap.get(project);
if (partioner == null) {
partioner = new BuildConsolePartitioner(this);
partioner = new BuildConsolePartitioner(project, this);
fConsoleMap.put(project, partioner);
}
return partioner;
@ -342,4 +354,40 @@ public class BuildConsoleManager implements IBuildConsoleManager, IResourceChang
listeners.remove(listener);
}
/**
* @return logging preferences for a given project.
* @param project to get logging preferences for.
*/
public static Preferences getBuildLogPreferences(IProject project) {
return new LocalProjectScope(project).getNode(QUALIFIER).node(BUILD_CONSOLE_NODE);
}
/**
* @return default location of logs for a project.
* @param project to get default log location for.
*/
public static String getDefaultConsoleLogLocation(IProject project) {
IPath defaultLogLocation = CUIPlugin.getDefault().getStateLocation().append(project.getName()+".build.log"); //$NON-NLS-1$
return defaultLogLocation.toOSString();
}
/**
* Refresh output file when it happens to belong to Workspace. There could
* be multiple workspace {@link IFile} associated with one URI.
*
* @param uri - URI of the file.
*/
static void refreshWorkspaceFiles(URI uri) {
if (uri!=null) {
IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri);
for (IFile file : files) {
try {
file.refreshLocal(IResource.DEPTH_ZERO, null);
} catch (CoreException e) {
CUIPlugin.log(e);
}
}
}
}
}

View file

@ -26,10 +26,6 @@ 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.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
@ -86,22 +82,14 @@ import org.eclipse.ui.texteditor.FindReplaceAction;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ProblemMarkerInfo;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
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.core.BuildOutputLogger;
import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage;
public class BuildConsolePage extends Page
@ -110,9 +98,7 @@ public class BuildConsolePage extends Page
IPropertyChangeListener,
IBuildConsoleListener,
ITextListener,
IAdaptable,
IPreferenceChangeListener,
ICProjectDescriptionListener {
IAdaptable {
static final int POSITION_NEXT = -1;
static final int POSITION_PREV = -2;
@ -136,7 +122,7 @@ public class BuildConsolePage extends Page
private ClearOutputAction fClearOutputAction;
private Map<String, IAction> fGlobalActions = new HashMap<String, IAction>(10);
private List<String> fSelectionActions = new ArrayList<String>(3);
SaveConsoleAction fSaveConsoleAction;
private CopyBuildLogAction fSaveLogAction;
// menus
private Menu fMenu;
@ -156,33 +142,11 @@ public class BuildConsolePage extends Page
fConsole = console;
fConsoleView = view;
fContextMenuId = contextId;
IEclipsePreferences pref = new InstanceScope().getNode(CCorePlugin.PLUGIN_ID);
pref.addPreferenceChangeListener(this);
CoreModel.getDefault().addCProjectDescriptionListener(this, CProjectDescriptionEvent.DATA_APPLIED );
}
protected void setProject(IProject project) {
if (fProject != project && project.isAccessible()) {
fProject = project;
ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(project);
if (projDesc == null) {
// don't support logging for non-C/C++ projects
fSaveConsoleAction.setChecked(false);
fSaveConsoleAction.setEnabled(false);
} else {
fSaveConsoleAction.setEnabled(true);
fSaveConsoleAction.setChecked(false);
ICConfigurationDescription configDesc = projDesc.getActiveConfiguration();
// Read save console log preferences
try {
IEclipsePreferences pref = new InstanceScope().getNode(CCorePlugin.PLUGIN_ID);
boolean b = pref.getBoolean(BuildOutputLogger.getIsSavingKey(project, configDesc.getName()),false);
fSaveConsoleAction.setChecked(b);
} catch (Exception e) {
CUIPlugin.log(e);
}
}
}
}
@ -332,8 +296,7 @@ public class BuildConsolePage extends Page
fNextErrorAction = new NextErrorAction(this);
fPreviousErrorAction = new PreviousErrorAction(this);
fShowErrorAction = new ShowErrorAction(this);
fSaveConsoleAction = new SaveConsoleAction(this);
fSaveConsoleAction.setChecked(false);
fSaveLogAction = new CopyBuildLogAction(this);
getViewer().setAutoScroll(!fIsLocked);
// In order for the clipboard actions to accessible via their shortcuts
@ -388,7 +351,7 @@ public class BuildConsolePage extends Page
mgr.appendToGroup(BuildConsole.ERROR_GROUP, fNextErrorAction);
mgr.appendToGroup(BuildConsole.ERROR_GROUP, fPreviousErrorAction);
mgr.appendToGroup(BuildConsole.ERROR_GROUP, fShowErrorAction);
mgr.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fSaveConsoleAction);
mgr.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fSaveLogAction);
mgr.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fScrollLockAction);
mgr.appendToGroup(IConsoleConstants.OUTPUT_GROUP, fClearOutputAction);
}
@ -668,33 +631,4 @@ public class BuildConsolePage extends Page
}
}
public void preferenceChange(PreferenceChangeEvent event) {
if (fProject != null) {
ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(fProject);
ICConfigurationDescription configDesc = projDesc.getActiveConfiguration();
String sk = BuildOutputLogger.getIsSavingKey(fProject, configDesc.getName());
String fk = BuildOutputLogger.getFileNameKey(fProject, configDesc.getName());
if ( sk.equals(event.getKey()) || fk.equals(event.getKey()) ) {
IBuildConsoleManager consoleManager = CUIPlugin.getDefault().getConsoleManager();
IConsole console = consoleManager.getConsole(fProject);
if (console != null && console instanceof BuildConsolePartitioner) {
BuildOutputLogger.SaveBuildOutputPreferences bp = BuildOutputLogger.readSaveBuildOutputPreferences(fProject);
fSaveConsoleAction.setChecked(bp.isSaving);
}
}
}
}
public void handleEvent(CProjectDescriptionEvent event) {
ICProjectDescription newPd = event.getNewCProjectDescription();
ICProjectDescription oldPd = event.getOldCProjectDescription();
if ( fProject != null && fProject.equals(event.getProject()) &&
newPd != null && oldPd != null &&
newPd.getActiveConfiguration() != null &&
newPd.getActiveConfiguration() != oldPd.getActiveConfiguration() ) {
BuildOutputLogger.SaveBuildOutputPreferences bp = BuildOutputLogger.readSaveBuildOutputPreferences(fProject);
fSaveConsoleAction.setChecked(bp.isSaving);
}
}
}

View file

@ -8,16 +8,25 @@
* Contributors:
* QNX Software Systems - initial API and implementation
* Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation
* Andrew Gvozdev (Quoin Inc.) - Copy build log (bug 306222)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.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;
@ -30,6 +39,7 @@ 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;
@ -45,6 +55,8 @@ public class BuildConsolePartitioner
IConsole,
IPropertyChangeListener {
private IProject fProject;
/**
* List of partitions
*/
@ -61,7 +73,6 @@ public class BuildConsolePartitioner
DocumentMarkerManager fDocumentMarkerManager;
boolean killed;
BuildConsoleManager fManager;
Boolean outputStreamClosed = new Boolean(false);
/**
* A queue of stream entries written to standard out and standard err.
@ -71,21 +82,40 @@ public class BuildConsolePartitioner
*/
Vector<StreamEntry> fQueue = new Vector<StreamEntry>(5);
//private boolean fAppending;
private URI fLogURI;
private OutputStream fLogStream;
class StreamEntry {
private class StreamEntry {
static public final int EVENT_APPEND = 0;
static public final int EVENT_OPEN_LOG = 1;
static public final int EVENT_CLOSE_LOG = 2;
/** Identifier of the stream written to. */
private BuildConsoleStreamDecorator fStream;
/** The text written */
private StringBuffer fText = null;
private StringBuffer fText = null;
/** Problem marker corresponding to the line of text */
private ProblemMarkerInfo fMarker;
/** Type of event **/
private int eventType;
StreamEntry(String text, BuildConsoleStreamDecorator stream, ProblemMarkerInfo marker) {
public StreamEntry(String text, BuildConsoleStreamDecorator stream, ProblemMarkerInfo marker) {
fText = new StringBuffer(text);
fStream = stream;
fMarker = marker;
eventType = EVENT_APPEND;
}
/**
* This constructor is used for special events such as clear console or close log.
*
* @param event - kind of event.
*/
public StreamEntry(int event) {
fText = null;
fStream = null;
fMarker = null;
eventType = event;
}
/**
@ -117,24 +147,73 @@ public class BuildConsolePartitioner
return fMarker;
}
/**
* Returns type of event
*/
public int getEventType() {
return eventType;
}
}
public BuildConsolePartitioner(BuildConsoleManager manager) {
public BuildConsolePartitioner(IProject project, BuildConsoleManager manager) {
fProject = project;
fManager = manager;
fMaxLines = BuildConsolePreferencePage.buildConsoleLines();
fDocument = new BuildConsoleDocument();
fDocument.setDocumentPartitioner(this);
fDocumentMarkerManager = new DocumentMarkerManager(fDocument, this);
connect(fDocument);
fLogURI = null;
fLogStream = null;
}
/**
* Sets the indicator that stream was opened so logging can be started. Should be called
* when opening the output stream.
*/
public void setStreamOpened() {
fQueue.add(new StreamEntry(StreamEntry.EVENT_OPEN_LOG));
asyncProcessQueue();
}
/**
* Sets the indicator that stream was closed so logging should be stopped. Should be called when
* build process has finished. Note that there could still be unprocessed console
* stream entries in the queue being worked on in the background.
*/
public void setStreamClosed() {
fQueue.add(new StreamEntry(StreamEntry.EVENT_CLOSE_LOG));
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.
*
* @param text
* the text to append
* @param stream
* the stream to append to
*
* @param text - the text to append.
* @param stream - the stream to append to.
*/
public void appendToDocument(String text, BuildConsoleStreamDecorator stream, ProblemMarkerInfo marker) {
boolean addToQueue = true;
@ -144,7 +223,7 @@ 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 && entry.getMarker() == marker) {
if (entry.getStream()==stream && entry.getEventType()==StreamEntry.EVENT_APPEND && entry.getMarker()==marker && entry.size()<10000) {
entry.appendText(text);
addToQueue = false;
}
@ -153,8 +232,18 @@ public class BuildConsolePartitioner
fQueue.add(new StreamEntry(text, stream, marker));
}
}
Runnable r = new Runnable() {
if (addToQueue) {
asyncProcessQueue();
}
}
/**
* Asynchronous processing of stream entries to append to console.
* Note that all these are processed by the same by the user-interface thread
* as of {@link Display#asyncExec(Runnable)}.
*/
private void asyncProcessQueue() {
Runnable r = new Runnable() {
public void run() {
StreamEntry entry;
try {
@ -162,24 +251,77 @@ public class BuildConsolePartitioner
} catch (ArrayIndexOutOfBoundsException e) {
return;
}
fLastStream = entry.getStream();
try {
warnOfContentChange(fLastStream);
switch (entry.getEventType()) {
case StreamEntry.EVENT_OPEN_LOG:
logOpen();
break;
case StreamEntry.EVENT_APPEND:
fLastStream = entry.getStream();
try {
warnOfContentChange(fLastStream);
if ( fLastStream == null ) {
// special case to empty document
fPartitions.clear();
fDocumentMarkerManager.clear();
fDocument.set(""); //$NON-NLS-1$
if (fLastStream == null) {
// special case to empty document
fPartitions.clear();
fDocumentMarkerManager.clear();
fDocument.set(""); //$NON-NLS-1$
}
addStreamEntryToDocument(entry);
log(entry.getText());
checkOverflow();
} catch (BadLocationException e) {
}
addStreamEntryToDocument(entry);
checkOverflow();
} catch (BadLocationException e) {
break;
case StreamEntry.EVENT_CLOSE_LOG:
logClose();
break;
}
}
private void logOpen() {
fLogURI = getLogURI(fProject);
if (fLogURI!=null) {
try {
IFileStore logStore = EFS.getStore(fLogURI);
fLogStream = logStore.openOutputStream(EFS.NONE, null);
} catch (CoreException e) {
CUIPlugin.log(e);
} finally {
BuildConsoleManager.refreshWorkspaceFiles(fLogURI);
}
}
}
private void log(String text) {
if (fLogStream!=null) {
try {
fLogStream.write(text.getBytes());
if (fQueue.isEmpty()) {
fLogStream.flush();
}
} catch (IOException e) {
CUIPlugin.log(e);
} finally {
BuildConsoleManager.refreshWorkspaceFiles(fLogURI);
}
}
}
private void logClose() {
if (fLogStream!=null) {
try {
fLogStream.close();
} catch (IOException e) {
CUIPlugin.log(e);
} finally {
BuildConsoleManager.refreshWorkspaceFiles(fLogURI);
}
fLogStream = null;
}
}
};
Display display = CUIPlugin.getStandardDisplay();
if (addToQueue && display != null) {
if (display != null) {
display.asyncExec(r);
}
}
@ -187,21 +329,21 @@ public class BuildConsolePartitioner
private void addStreamEntryToDocument(StreamEntry entry) throws BadLocationException {
if ( entry.getMarker() == null ) {
// It is plain unmarkered console output
addPartition(new BuildConsolePartition(fLastStream,
fDocument.getLength(),
addPartition(new BuildConsolePartition(fLastStream,
fDocument.getLength(),
entry.getText().length(),
BuildConsolePartition.CONSOLE_PARTITION_TYPE));
} else {
// this text line in entry is markered with ProblemMarkerInfo,
// this text line in entry is markered with ProblemMarkerInfo,
// create special partition for it.
addPartition(new BuildConsolePartition(fLastStream,
fDocument.getLength(),
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());
@ -268,7 +410,7 @@ public class BuildConsolePartitioner
ITypedRegion partition = fPartitions.get(i);
int partitionStart = partition.getOffset();
int partitionEnd = partitionStart + partition.getLength();
if ( (offset >= partitionStart && offset <= partitionEnd) ||
if ( (offset >= partitionStart && offset <= partitionEnd) ||
(offset < partitionStart && end >= partitionStart)) {
list.add(partition);
}
@ -339,9 +481,9 @@ public class BuildConsolePartitioner
int offset = region.getOffset();
if (offset < overflow) {
int endOffset = offset + region.getLength();
if (endOffset < overflow ||
if (endOffset < overflow ||
messageConsolePartition.getType() == BuildConsolePartition.ERROR_PARTITION_TYPE ) {
// remove partition,
// remove partition,
// partitions with problem markers can't be split - remove them too
} else {
// split partition
@ -410,13 +552,15 @@ public class BuildConsolePartitioner
});
}
fLogURI = null;
fLogStream = null;
if (BuildConsolePreferencePage.isClearBuildConsole()) {
appendToDocument("", null, null); //$NON-NLS-1$
}
}
public ConsoleOutputStream getOutputStream() throws CoreException {
outputStreamClosed = Boolean.FALSE;
return new BuildOutputStream(this, fManager.getStreamDecorator(BuildConsoleManager.BUILD_STREAM_TYPE_OUTPUT));
}
@ -427,7 +571,7 @@ public class BuildConsolePartitioner
public ConsoleOutputStream getErrorStream() throws CoreException {
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() {
@ -451,8 +595,15 @@ public class BuildConsolePartitioner
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$
System.out.println(" " + isError + " " + start + "-" + end + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
":[" + text + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* @return {@link URI} location of log file.
*/
public URI getLogURI() {
return fLogURI;
}
}

View file

@ -31,7 +31,8 @@ public class BuildOutputStream extends ConsoleOutputStream implements IErrorMark
public BuildOutputStream(BuildConsolePartitioner partitioner,
BuildConsoleStreamDecorator stream) {
fPartitioner = partitioner;
fStream = stream;
fPartitioner.setStreamOpened();
fStream = stream;
}
@Override
@ -41,6 +42,7 @@ public class BuildOutputStream extends ConsoleOutputStream implements IErrorMark
@Override
public void close() throws IOException {
flush();
fPartitioner.setStreamClosed();
}
@Override

View file

@ -34,7 +34,15 @@ public final class ConsoleMessages extends NLS {
public static String PreviousErrorAction_Tooltip;
public static String NextErrorAction_Tooltip;
public static String ShowErrorAction_Tooltip;
public static String SaveConsole_ActionTooltip;
public static String CopyLog_ActionTooltip;
public static String CopyLog_BuildNotLogged;
public static String CopyLog_ChooseDestination;
public static String CopyLog_ErrorCopyingFile;
public static String CopyLog_ErrorWhileCopyingLog;
public static String CopyLog_InvalidDestination;
public static String CopyLog_LogFileIsNotAvailable;
public static String CopyLog_UnableToAccess;
public static String CopyLog_UnavailableLog;
static {
NLS.initializeMessages(BUNDLE_NAME, ConsoleMessages.class);

View file

@ -20,9 +20,18 @@ BuildConsolePage_Copy_7=Copy
BuildConsolePage_Select__All_Ctrl_A_12=Select &All@Ctrl+A
BuildConsolePage_Select_All=Select All
CopyLog_ActionTooltip=Copy Build Log
CopyLog_BuildNotLogged=Last build was not logged. Check Logging page in project properties.
CopyLog_ChooseDestination=Choose Log File Destination
CopyLog_ErrorCopyingFile=Error Copying a File
CopyLog_ErrorWhileCopyingLog=Error while copying working log file:
CopyLog_InvalidDestination=Destination is not valid:
CopyLog_LogFileIsNotAvailable=Working log file is not available.
CopyLog_UnableToAccess=Unable to access build log at
CopyLog_UnavailableLog=Unavailable Log
ScrollLockAction_Scroll_Lock_1=Scroll Lock
NextErrorAction_Tooltip=Next Error
PreviousErrorAction_Tooltip=Previous Error
ShowErrorAction_Tooltip=Show Error In Editor
SaveConsole_ActionTooltip=Save Console Output To File

View file

@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2010 Andrew Gvozdev 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:
* Andrew Gvozdev (Quoin Inc.) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.buildconsole;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IBuildConsoleManager;
import org.eclipse.cdt.internal.ui.CPluginImages;
/**
* Action to copy build log from working file to a user selected file.
*/
public class CopyBuildLogAction extends Action {
private BuildConsolePage fConsolePage;
public CopyBuildLogAction(BuildConsolePage page) {
super();
setToolTipText(ConsoleMessages.CopyLog_ActionTooltip);
CPluginImages.setImageDescriptors(this, CPluginImages.T_LCL, CPluginImages.IMG_SAVE_CONSOLE);
fConsolePage = page;
}
@Override
public void run() {
IProject project = fConsolePage.getProject();
if (!project.isAccessible())
return;
IBuildConsoleManager consoleManager = CUIPlugin.getDefault().getConsoleManager();
IConsole console = consoleManager.getConsole(project);
if (console instanceof BuildConsolePartitioner) {
Shell shell = Display.getCurrent().getActiveShell();
URI srcURI = ((BuildConsolePartitioner)console).getLogURI();
if (srcURI==null) {
MessageDialog.openWarning(shell, ConsoleMessages.CopyLog_UnavailableLog,
ConsoleMessages.CopyLog_BuildNotLogged);
return;
}
IFileStore srcStore = null;
try {
srcStore = EFS.getStore(srcURI);
} catch (CoreException e) {
CUIPlugin.log(e);
MessageDialog.openError(shell, ConsoleMessages.CopyLog_UnavailableLog,
ConsoleMessages.CopyLog_UnableToAccess+srcURI);
return;
}
if (!srcStore.fetchInfo().exists()) {
MessageDialog.openError(shell, ConsoleMessages.CopyLog_UnavailableLog,
ConsoleMessages.CopyLog_LogFileIsNotAvailable);
return;
}
// open file dialog
FileDialog dialog = new FileDialog(shell, SWT.NONE);
dialog.setText(ConsoleMessages.CopyLog_ChooseDestination);
String destLocation = dialog.open();
if (destLocation!=null) {
URI destURI = URIUtil.toURI(destLocation);
if (destURI==null) {
MessageDialog.openError(shell, ConsoleMessages.CopyLog_UnavailableLog,
ConsoleMessages.CopyLog_InvalidDestination+destLocation);
return;
}
try {
IFileStore destStore = EFS.getStore(destURI);
srcStore.copy(destStore, EFS.OVERWRITE, null);
} catch (CoreException e) {
CUIPlugin.log(e);
MessageDialog.openError(shell, ConsoleMessages.CopyLog_ErrorCopyingFile,
ConsoleMessages.CopyLog_ErrorWhileCopyingLog+e.getLocalizedMessage());
} finally {
BuildConsoleManager.refreshWorkspaceFiles(destURI);
}
}
}
}
}

View file

@ -1,71 +0,0 @@
/*******************************************************************************
* 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.core.resources.IProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IBuildConsoleManager;
import org.eclipse.cdt.internal.core.BuildOutputLogger;
import org.eclipse.cdt.internal.ui.CPluginImages;
/**
* Save console content to a file
*/
public class SaveConsoleAction extends Action {
private BuildConsolePage fConsolePage;
public SaveConsoleAction(BuildConsolePage page) {
super();
setToolTipText(ConsoleMessages.SaveConsole_ActionTooltip);
setChecked(false);
CPluginImages.setImageDescriptors(this, CPluginImages.T_LCL, CPluginImages.IMG_SAVE_CONSOLE);
fConsolePage = page;
}
@Override
public void run() {
IProject project = fConsolePage.getProject();
if ( ! project.isAccessible() ) return;
IBuildConsoleManager consoleManager = CUIPlugin.getDefault().getConsoleManager();
IConsole console = consoleManager.getConsole(project);
// If state is switched to save build log, but log file is not set
// in project properties, show project properties dialog.
if ( console != null && console instanceof BuildConsolePartitioner ) {
BuildOutputLogger.SaveBuildOutputPreferences bp =
BuildOutputLogger.readSaveBuildOutputPreferences(project);
if ( isChecked() ) {
if ( bp.fileName == null || bp.fileName.trim().length() == 0 ) {
Shell shell = fConsolePage.getControl().getShell();
String id = "org.eclipse.cdt.managedbuilder.ui.properties.Page_head_build"; //$NON-NLS-1$
PreferenceDialog d = PreferencesUtil.createPropertyDialogOn(shell, project, id, new String[] { id }, null);
d.open();
BuildOutputLogger.SaveBuildOutputPreferences newBp =
BuildOutputLogger.readSaveBuildOutputPreferences(project);
setChecked(newBp.isSaving);
return;
}
}
bp.isSaving = isChecked();
BuildOutputLogger.writeSaveBuildOutputPreferences(project,bp);
}
}
}

View file

@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2010 Andrew Gvozdev 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:
* Andrew Gvozdev (Quoin Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.PropertyPage;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
import org.eclipse.cdt.internal.ui.buildconsole.BuildConsoleManager;
/**
* Preference page defining build log properties.
*/
public class BuildLogPreferencePage extends PropertyPage implements ICOptionContainer {
private boolean isProjectLevel;
private Button enableLoggingCheckbox;
private Button browseButton;
private Text logLocationText;
private Label logLocationLabel;
@Override
protected Control createContents(Composite parent) {
IProject project = getProject();
isProjectLevel= project != null;
if(isProjectLevel) {
Preferences prefs = BuildConsoleManager.getBuildLogPreferences(project);
Composite contents = ControlFactory.createCompositeEx(parent, 3, GridData.FILL_BOTH);
((GridLayout) contents.getLayout()).makeColumnsEqualWidth = false;
ControlFactory.createEmptySpace(contents, 3);
// [v] Enable Logging
enableLoggingCheckbox = ControlFactory.createCheckBox(contents, PreferencesMessages.BuildLogPreferencePage_EnableLogging);
boolean keepLog = prefs.getBoolean(BuildConsoleManager.KEY_KEEP_LOG, BuildConsoleManager.CONSOLE_KEEP_LOG_DEFAULT);
enableLoggingCheckbox.setSelection(keepLog);
enableLoggingCheckbox.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateEnablements();
}
});
ControlFactory.createEmptySpace(contents, 3);
// Log file location: [....................]
logLocationLabel = ControlFactory.createLabel(contents, PreferencesMessages.BuildLogPreferencePage_LogLocation);
((GridData) logLocationLabel.getLayoutData()).grabExcessHorizontalSpace = false;
logLocationText = ControlFactory.createTextField(contents, SWT.SINGLE | SWT.BORDER);
String logLocation = prefs.get(BuildConsoleManager.KEY_LOG_LOCATION, BuildConsoleManager.getDefaultConsoleLogLocation(project));
logLocationText.setText(logLocation);
logLocationText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
}
});
// [Browse...]
browseButton = ControlFactory.createPushButton(contents, PreferencesMessages.BuildLogPreferencePage_Browse);
((GridData) browseButton.getLayoutData()).horizontalAlignment = GridData.END;
browseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
FileDialog dialog = new FileDialog(getShell(), SWT.NONE);
dialog.setText(PreferencesMessages.BuildLogPreferencePage_ChooseLogFile);
String fileName = logLocationText.getText();
IPath logFolder = new Path(fileName).removeLastSegments(1);
dialog.setFilterPath(logFolder.toOSString());
String chosenFile = dialog.open();
if (chosenFile != null) {
logLocationText.setText(chosenFile);
}
}
});
updateEnablements();
}
return parent;
}
@Override
protected void performDefaults() {
if(isProjectLevel) {
IProject project = getProject();
Preferences prefs = BuildConsoleManager.getBuildLogPreferences(project);
prefs.put(BuildConsoleManager.KEY_LOG_LOCATION, BuildConsoleManager.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)));
enableLoggingCheckbox.setSelection(prefs.getBoolean(BuildConsoleManager.KEY_KEEP_LOG, BuildConsoleManager.CONSOLE_KEEP_LOG_DEFAULT));
updateEnablements();
}
super.performDefaults();
}
@Override
public boolean performOk() {
if(isProjectLevel) {
Preferences prefs = BuildConsoleManager.getBuildLogPreferences(getProject());
prefs.put(BuildConsoleManager.KEY_LOG_LOCATION, logLocationText.getText());
prefs.putBoolean(BuildConsoleManager.KEY_KEEP_LOG, enableLoggingCheckbox.getSelection());
try {
prefs.flush();
} catch (BackingStoreException e) {
CUIPlugin.log(e);
}
}
return true;
}
public IProject getProject(){
IProject project= null;
IAdaptable elem = getElement();
if (elem instanceof IProject) {
project= (IProject) elem;
} else if (elem != null) {
project= (IProject) elem.getAdapter(IProject.class);
}
return project;
}
public org.eclipse.core.runtime.Preferences getPreferences() {
throw new UnsupportedOperationException();
}
public void updateContainer() {
}
private void updateEnablements() {
boolean isLoggingEnabled = enableLoggingCheckbox.getSelection();
logLocationLabel.setEnabled(isLoggingEnabled);
logLocationText.setEnabled(isLoggingEnabled);
browseButton.setEnabled(isLoggingEnabled);
}
}

View file

@ -145,6 +145,10 @@ public final class PreferencesMessages extends NLS {
public static String AppearancePreferencePage_note;
public static String AppearancePreferencePage_preferenceOnlyForNewViews;
public static String AppearancePreferencePage_showSourceRootsAtTopOfProject_label;
public static String BuildLogPreferencePage_Browse;
public static String BuildLogPreferencePage_ChooseLogFile;
public static String BuildLogPreferencePage_EnableLogging;
public static String BuildLogPreferencePage_LogLocation;
public static String CEditorPreferencePage_folding_title;
public static String FoldingConfigurationBlock_enable;
public static String FoldingConfigurationBlock_combo_caption;

View file

@ -165,6 +165,12 @@ AppearancePreferencePage_preferenceOnlyForNewViews=This preference does not affe
AppearancePreferencePage_outlineGroupMacros_label=Group macro definitions in the Outline view
AppearancePreferencePage_showSourceRootsAtTopOfProject_label=Show source roots at top of project
#Build Logging
BuildLogPreferencePage_Browse=Browse...
BuildLogPreferencePage_ChooseLogFile=Choose Log File
BuildLogPreferencePage_EnableLogging=Enable logging
BuildLogPreferencePage_LogLocation=Log file location:
#Folding
CEditorPreferencePage_folding_title= &Folding