IDEA-89915 Notification on stderror output in Run panel / Console

This commit is contained in:
Vassiliy Kudryashov
2012-09-14 16:14:06 +04:00
parent 1310d1a353
commit 10c6ec2b84
10 changed files with 74 additions and 11 deletions
@@ -60,6 +60,7 @@ public abstract class CommandLineState implements RunnableState {
return myEnvironment.getExecutionTarget();
}
@NotNull
public ExecutionResult execute(@NotNull final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException {
final ProcessHandler processHandler = startProcess();
final ConsoleView console = createConsole(executor);
@@ -17,12 +17,13 @@
package com.intellij.execution.ui;
import com.intellij.openapi.Disposable;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface ObservableConsoleView {
void addChangeListener(ChangeListener listener, Disposable parent);
void addChangeListener(@NotNull ChangeListener listener, @NotNull Disposable parent);
interface ChangeListener {
void contentAdded(Collection<ConsoleViewContentType> types);
@@ -48,7 +48,7 @@
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Show console when standard out changes"/>
<text resource-bundle="messages/ExecutionBundle" key="logs.show.console.on.stdout"/>
</properties>
</component>
<component id="b4310" class="javax.swing.JCheckBox" binding="myShowConsoleOnStdErrCb" default-binding="true">
@@ -56,7 +56,7 @@
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Show console when standard error changes"/>
<text resource-bundle="messages/ExecutionBundle" key="logs.show.console.on.stderr"/>
</properties>
</component>
</children>
@@ -1512,7 +1512,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
@Override
public void addChangeListener(final ChangeListener listener, final Disposable parent) {
public void addChangeListener(@NotNull final ChangeListener listener, @NotNull final Disposable parent) {
myListeners.add(listener);
Disposer.register(parent, new Disposable() {
@Override
@@ -52,6 +52,8 @@ public class Tool implements SchemeElement {
private boolean myEnabled;
private boolean myUseConsole;
private boolean myShowConsoleOnStdOut;
private boolean myShowConsoleOnStdErr;
private boolean mySynchronizeAfterExecution;
private String myWorkingDirectory;
@@ -103,6 +105,14 @@ public class Tool implements SchemeElement {
return myUseConsole;
}
public boolean isShowConsoleOnStdOut() {
return myShowConsoleOnStdOut;
}
public boolean isShowConsoleOnStdErr() {
return myShowConsoleOnStdErr;
}
public boolean synchronizeAfterExecution() {
return mySynchronizeAfterExecution;
}
@@ -139,6 +149,14 @@ public class Tool implements SchemeElement {
myUseConsole = useConsole;
}
void setShowConsoleOnStdOut(boolean showConsole) {
myShowConsoleOnStdOut = showConsole;
}
void setShowConsoleOnStdErr(boolean showConsole) {
myShowConsoleOnStdErr = showConsole;
}
public void setFilesSynchronizedAfterRun(boolean synchronizeAfterRun) {
mySynchronizeAfterExecution = synchronizeAfterRun;
}
@@ -192,6 +210,8 @@ public class Tool implements SchemeElement {
myShownInSearchResultsPopup = source.myShownInSearchResultsPopup;
myEnabled = source.myEnabled;
myUseConsole = source.myUseConsole;
myShowConsoleOnStdOut = source.myShowConsoleOnStdOut;
myShowConsoleOnStdErr = source.myShowConsoleOnStdErr;
mySynchronizeAfterExecution = source.mySynchronizeAfterExecution;
myWorkingDirectory = source.myWorkingDirectory;
myProgram = source.myProgram;
@@ -215,6 +235,8 @@ public class Tool implements SchemeElement {
myShownInSearchResultsPopup == source.myShownInSearchResultsPopup &&
myEnabled == source.myEnabled &&
myUseConsole == source.myUseConsole &&
myShowConsoleOnStdOut == source.myShowConsoleOnStdOut &&
myShowConsoleOnStdErr == source.myShowConsoleOnStdErr &&
mySynchronizeAfterExecution == source.mySynchronizeAfterExecution &&
Comparing.equal(myWorkingDirectory, source.myWorkingDirectory) &&
Comparing.equal(myProgram, source.myProgram) &&
@@ -16,6 +16,7 @@
package com.intellij.tools;
import com.intellij.execution.ExecutionBundle;
import com.intellij.ide.DataManager;
import com.intellij.ide.macro.MacroManager;
import com.intellij.ide.macro.MacrosDialog;
@@ -36,8 +37,11 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.util.Consumer;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.text.BadLocationException;
import java.awt.*;
@@ -55,6 +59,8 @@ public class ToolEditorDialog extends DialogWrapper {
private final JCheckBox myShowInProjectTreeCheckbox = new JCheckBox(ToolsBundle.message("tools.menu.project.checkbox"));
private final JCheckBox myShowInSearchResultsPopupCheckbox = new JCheckBox(ToolsBundle.message("tools.menu.search.checkbox"));
private final JCheckBox myUseConsoleCheckbox = new JCheckBox(ToolsBundle.message("tools.open.console.checkbox"));
private final JCheckBox myShowConsoleOnStdOutCheckbox = new JCheckBox(ExecutionBundle.message("logs.show.console.on.stdout"));
private final JCheckBox myShowConsoleOnStdErrCheckbox = new JCheckBox(ExecutionBundle.message("logs.show.console.on.stderr"));
private final JCheckBox mySynchronizedAfterRunCheckbox = new JCheckBox(ToolsBundle.message("tools.synchronize.files.checkbox"));
private boolean myEnabled;
@@ -179,6 +185,8 @@ public class ToolEditorDialog extends DialogWrapper {
setTitle(ToolsBundle.message("tools.edit.title"));
init();
addListeners();
myShowConsoleOnStdOutCheckbox.setVisible(false);
myShowConsoleOnStdErrCheckbox.setVisible(false);
}
private JPanel createCommandPane() {
@@ -375,6 +383,14 @@ public class ToolEditorDialog extends DialogWrapper {
handleOKButton();
}
});
myUseConsoleCheckbox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
myShowConsoleOnStdOutCheckbox.setVisible(myUseConsoleCheckbox.isSelected());
myShowConsoleOnStdErrCheckbox.setVisible(myUseConsoleCheckbox.isSelected());
}
});
}
private void handleOKButton() {
@@ -392,6 +408,8 @@ public class ToolEditorDialog extends DialogWrapper {
tool.setShownInProjectViews(myShowInProjectTreeCheckbox.isSelected());
tool.setShownInSearchResultsPopup(myShowInSearchResultsPopupCheckbox.isSelected());
tool.setUseConsole(myUseConsoleCheckbox.isSelected());
tool.setShowConsoleOnStdOut(myShowConsoleOnStdOutCheckbox.isSelected());
tool.setShowConsoleOnStdErr(myShowConsoleOnStdErrCheckbox.isSelected());
tool.setFilesSynchronizedAfterRun(mySynchronizedAfterRunCheckbox.isSelected());
tool.setEnabled(myEnabled);
@@ -428,6 +446,8 @@ public class ToolEditorDialog extends DialogWrapper {
myShowInProjectTreeCheckbox.setSelected(tool.isShownInProjectViews());
myShowInSearchResultsPopupCheckbox.setSelected(tool.isShownInSearchResultsPopup());
myUseConsoleCheckbox.setSelected(tool.isUseConsole());
myShowConsoleOnStdOutCheckbox.setSelected(tool.isShowConsoleOnStdOut());
myShowConsoleOnStdErrCheckbox.setSelected(tool.isShowConsoleOnStdErr());
mySynchronizedAfterRunCheckbox.setSelected(tool.synchronizeAfterExecution());
myEnabled = tool.isEnabled();
myTfCommandWorkingDirectory.setText(toCurrentSystemFormat(tool.getWorkingDirectory()));
@@ -453,11 +473,13 @@ public class ToolEditorDialog extends DialogWrapper {
}
private JPanel getOptionsPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
JPanel panel = new JPanel(new MigLayout("fill, gap 10"));
panel.setBorder(IdeBorderFactory.createTitledBorder(ToolsBundle.message("tools.options.group"), true));
panel.add(mySynchronizedAfterRunCheckbox);
panel.add(myUseConsoleCheckbox);
panel.add(myOutputFiltersButton);
panel.add(myOutputFiltersButton, "ax right, wrap");
panel.add(myShowConsoleOnStdOutCheckbox);
panel.add(myShowConsoleOnStdErrCheckbox, "spanx 2");
return panel;
}
@@ -16,21 +16,20 @@
package com.intellij.tools;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.RegexpFilter;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.process.ColoredProcessHandler;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.process.*;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -89,11 +88,21 @@ public class ToolRunProfile implements ModuleRunProfile{
return processHandler;
}
@NotNull
public ExecutionResult execute(@NotNull final Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
final ExecutionResult result = super.execute(executor, runner);
final ProcessHandler processHandler = result.getProcessHandler();
if (processHandler != null) {
processHandler.addProcessListener(new ToolProcessAdapter(project, myTool.synchronizeAfterExecution(), getName()));
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {
if ((outputType == ProcessOutputTypes.STDOUT && myTool.isShowConsoleOnStdOut())
|| (outputType == ProcessOutputTypes.STDERR && myTool.isShowConsoleOnStdErr())) {
ExecutionManager.getInstance(project).getContentManager().toFrontRunContent(executor, processHandler);
}
}
});
}
return result;
}
@@ -42,6 +42,8 @@ class ToolsProcessor extends BaseSchemeProcessor<ToolsGroup> {
@NonNls private static final String SHOW_IN_SEARCH_POPUP = "showInSearchPopup";
@NonNls private static final String DISABLED = "disabled";
@NonNls private static final String USE_CONSOLE = "useConsole";
@NonNls private static final String SHOW_CONSOLE_ON_STDOUT = "showConsoleOnStdOut";
@NonNls private static final String SHOW_CONSOLE_ON_STDERR = "showConsoleOnStdErr";
@NonNls private static final String SYNCHRONIZE_AFTER_EXECUTION = "synchronizeAfterRun";
@NonNls private static final String EXEC = "exec";
@NonNls private static final String WORKING_DIRECTORY = "WORKING_DIRECTORY";
@@ -76,6 +78,8 @@ class ToolsProcessor extends BaseSchemeProcessor<ToolsGroup> {
tool.setShownInSearchResultsPopup(Boolean.valueOf(element.getAttributeValue(SHOW_IN_SEARCH_POPUP)).booleanValue());
tool.setEnabled(!Boolean.valueOf(element.getAttributeValue(DISABLED)).booleanValue());
tool.setUseConsole(Boolean.valueOf(element.getAttributeValue(USE_CONSOLE)).booleanValue());
tool.setShowConsoleOnStdOut(Boolean.valueOf(element.getAttributeValue(SHOW_CONSOLE_ON_STDOUT)).booleanValue());
tool.setShowConsoleOnStdErr(Boolean.valueOf(element.getAttributeValue(SHOW_CONSOLE_ON_STDERR)).booleanValue());
tool.setFilesSynchronizedAfterRun(Boolean.valueOf(element.getAttributeValue(SYNCHRONIZE_AFTER_EXECUTION)).booleanValue());
Element exec = element.getChild(EXEC);
@@ -150,6 +154,8 @@ class ToolsProcessor extends BaseSchemeProcessor<ToolsGroup> {
element.setAttribute(SHOW_IN_SEARCH_POPUP, Boolean.toString(tool.isShownInSearchResultsPopup()));
element.setAttribute(DISABLED, Boolean.toString(!tool.isEnabled()));
element.setAttribute(USE_CONSOLE, Boolean.toString(tool.isUseConsole()));
element.setAttribute(SHOW_CONSOLE_ON_STDOUT, Boolean.toString(tool.isShowConsoleOnStdOut()));
element.setAttribute(SHOW_CONSOLE_ON_STDERR, Boolean.toString(tool.isShowConsoleOnStdErr()));
element.setAttribute(SYNCHRONIZE_AFTER_EXECUTION, Boolean.toString(tool.synchronizeAfterExecution()));
Element taskElement = new Element(EXEC);
@@ -286,6 +286,8 @@ run.configuration.error.no.jdk.specified=No JDK specified
run.configuration.cannot.find.vm.executable=Cannot find VM executable
logs.tab.title=Logs
logs.show.console.on.stdout=Show console when standard out changes
logs.show.console.on.stderr=Show console when standard error changes
before.launch.panel.title=Before launch
before.launch.panel.empty=There are no tasks to run before launch
before.launch.panel.cyclic_dependency_warning=''{0}'' has already configured to be launched before {1}.\nSuch cyclic dependencies are not allowed.
@@ -133,7 +133,7 @@ public abstract class BaseTestsOutputConsoleView implements ConsoleView, Observa
myConsole = null;
}
public void addChangeListener(final ChangeListener listener, final Disposable parent) {
public void addChangeListener(@NotNull final ChangeListener listener, @NotNull final Disposable parent) {
if (myConsole instanceof ObservableConsoleView) {
((ObservableConsoleView)myConsole).addChangeListener(listener, parent);
} else {