diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties
index ff429f60ca7..a839fb9edf6 100644
--- a/core/org.eclipse.cdt.ui/plugin.properties
+++ b/core/org.eclipse.cdt.ui/plugin.properties
@@ -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...
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index bdcafb55510..b1f6fa1a17d 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -2632,6 +2632,18 @@
+
+
+
+
+
+
+
+
fGlobalActions = new HashMap(10);
private List fSelectionActions = new ArrayList(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);
- }
-
- }
}
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 85869562a1c..35917f5b559 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
@@ -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 fQueue = new Vector(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;
+ }
}
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
index c77a0dfbe7a..b61f1245f87 100644
--- 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
@@ -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
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 fb9bb6deeb3..bfdc1ab9a92 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
@@ -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);
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 b5916fabd5c..996397476b8 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
@@ -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
\ No newline at end of file
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
new file mode 100644
index 00000000000..e0aed6a7802
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/CopyBuildLogAction.java
@@ -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);
+ }
+ }
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/SaveConsoleAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/SaveConsoleAction.java
deleted file mode 100644
index 553cb9005b6..00000000000
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/SaveConsoleAction.java
+++ /dev/null
@@ -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);
- }
- }
-
-}
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
new file mode 100644
index 00000000000..f92add233e6
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/BuildLogPreferencePage.java
@@ -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);
+ }
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java
index dd61370bc7f..695a4789482 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.java
@@ -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;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
index 9c2a47279bf..414cd5e5e72 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
@@ -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