mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Build tool window: debugger integration
This commit is contained in:
@@ -16,17 +16,19 @@
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.build.events.*;
|
||||
import com.intellij.execution.actions.StopAction;
|
||||
import com.intellij.execution.actions.StopProcessAction;
|
||||
import com.intellij.execution.console.DuplexConsoleView;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.execution.ui.ExecutionConsole;
|
||||
import com.intellij.execution.runners.FakeRerunAction;
|
||||
import com.intellij.execution.ui.*;
|
||||
import com.intellij.execution.ui.actions.CloseAction;
|
||||
import com.intellij.execution.ui.layout.impl.RunnerLayoutUiImpl;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ComponentContainer;
|
||||
import com.intellij.openapi.ui.ThreeComponentsSplitter;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
@@ -35,17 +37,21 @@ import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.impl.ContentImpl;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import com.intellij.util.ui.EdtInvocationManager;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
@@ -55,6 +61,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
@@ -69,7 +76,7 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
@Nullable
|
||||
private final JBList<BuildInfo> myBuildsList;
|
||||
private final Map<Object, BuildInfo> myBuildsMap;
|
||||
private final Map<BuildInfo, DuplexConsoleView<BuildConsoleView, ConsoleView>> myViewMap;
|
||||
private final Map<BuildInfo, BuildView> myViewMap;
|
||||
private volatile Content myContent;
|
||||
private volatile DefaultActionGroup myToolbarActions;
|
||||
|
||||
@@ -131,8 +138,7 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
}
|
||||
}
|
||||
if (shouldBeCleared) {
|
||||
for (DuplexConsoleView<BuildConsoleView, ConsoleView> view : myViewMap.values()) {
|
||||
view.clear();
|
||||
for (BuildView view : myViewMap.values()) {
|
||||
Disposer.dispose(view);
|
||||
}
|
||||
listModel.clear();
|
||||
@@ -166,40 +172,80 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
}
|
||||
|
||||
ProcessHandler processHandler = ((StartBuildEvent)event).getProcessHandler();
|
||||
DuplexConsoleView<BuildConsoleView, ConsoleView> view = myViewMap.computeIfAbsent(buildInfo, info -> {
|
||||
ExecutionConsole executionConsole = ((StartBuildEvent)event).getExecutionConsole();
|
||||
if (executionConsole == null) {
|
||||
executionConsole = new BuildTextConsoleView(myProject);
|
||||
BuildView view = myViewMap.computeIfAbsent(buildInfo, info -> {
|
||||
ExecutionConsole executionConsole = null;
|
||||
ComponentContainer componentContainer = null;
|
||||
Supplier<RunContentDescriptor> contentDescriptorSupplier = ((StartBuildEvent)event).getContentDescriptorSupplier();
|
||||
if (contentDescriptorSupplier != null) {
|
||||
RunContentDescriptor contentDescriptor = contentDescriptorSupplier.get();
|
||||
if (contentDescriptor != null) {
|
||||
executionConsole = contentDescriptor.getExecutionConsole();
|
||||
List<AnAction> leftToolbarActions = ContainerUtil.newArrayList();
|
||||
RunnerLayoutUi layoutUi = contentDescriptor.getRunnerLayoutUi();
|
||||
if (layoutUi instanceof RunnerLayoutUiImpl) {
|
||||
RunnerLayoutUiImpl layoutUiImpl = (RunnerLayoutUiImpl)layoutUi;
|
||||
layoutUiImpl.setLeftToolbarVisible(false);
|
||||
layoutUiImpl.setContentToolbarBefore(false);
|
||||
leftToolbarActions.addAll(layoutUiImpl.getActions());
|
||||
}
|
||||
JComponent component = contentDescriptor.getComponent();
|
||||
AnAction[] leftToolbarActionsArray = leftToolbarActions.toArray(new AnAction[leftToolbarActions.size()]);
|
||||
componentContainer = new BuildConsoleView() {
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnAction[] createConsoleActions() {
|
||||
return leftToolbarActionsArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusableComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
final DuplexConsoleView<BuildConsoleView, ConsoleView> duplexConsoleView =
|
||||
new BuildDuplexConsoleView(executionConsole, ((StartBuildEvent)event));
|
||||
duplexConsoleView.setDisableSwitchConsoleActionOnProcessEnd(false);
|
||||
duplexConsoleView.getSwitchConsoleActionPresentation().setIcon(AllIcons.Actions.ChangeView);
|
||||
duplexConsoleView.getSwitchConsoleActionPresentation().setText("Toggle view");
|
||||
duplexConsoleView.enableConsole(!isConsoleEnabledByDefault());
|
||||
if (componentContainer == null) {
|
||||
componentContainer = executionConsole = new BuildTextConsoleView(myProject);
|
||||
}
|
||||
final BuildView buildView = new BuildView(myProject, componentContainer, ((StartBuildEvent)event));
|
||||
buildView.enableView(!isConsoleEnabledByDefault());
|
||||
if (processHandler != null) {
|
||||
if (executionConsole instanceof ConsoleView) {
|
||||
((ConsoleView)executionConsole).attachToProcess(processHandler);
|
||||
Consumer<ConsoleView> attachedConsoleConsumer = ((StartBuildEvent)event).getAttachedConsoleConsumer();
|
||||
if (attachedConsoleConsumer != null) {
|
||||
attachedConsoleConsumer.consume((ConsoleView)executionConsole);
|
||||
}
|
||||
}
|
||||
if (!processHandler.isStartNotified()) {
|
||||
processHandler.startNotify();
|
||||
}
|
||||
((ConsoleView)executionConsole).attachToProcess(processHandler);
|
||||
Consumer<ConsoleView> attachedConsoleConsumer = ((StartBuildEvent)event).getAttachedConsoleConsumer();
|
||||
if (attachedConsoleConsumer != null) {
|
||||
attachedConsoleConsumer.consume((ConsoleView)executionConsole);
|
||||
}
|
||||
}
|
||||
Disposer.register(myThreeComponentsSplitter, duplexConsoleView);
|
||||
Disposer.register(myThreeComponentsSplitter, buildView);
|
||||
if (isTabbedView()) {
|
||||
final JComponent consoleComponent = new JPanel(new BorderLayout());
|
||||
consoleComponent.add(duplexConsoleView, BorderLayout.CENTER);
|
||||
consoleComponent.add(buildView, BorderLayout.CENTER);
|
||||
DefaultActionGroup toolbarActions = new DefaultActionGroup();
|
||||
consoleComponent.add(ActionManager.getInstance().createActionToolbar(
|
||||
"", toolbarActions, false).getComponent(), BorderLayout.WEST);
|
||||
toolbarActions.addAll(duplexConsoleView.createConsoleActions());
|
||||
toolbarActions.addAll(buildView.createConsoleActions());
|
||||
myBuildContentManager.addTabbedContent(
|
||||
consoleComponent, getViewName(), buildInfo.title + ", " + DateFormatUtil.formatDateTime(System.currentTimeMillis()) + " ",
|
||||
true, AllIcons.CodeStyle.Gear, duplexConsoleView);
|
||||
true, AllIcons.CodeStyle.Gear, buildView);
|
||||
}
|
||||
return duplexConsoleView;
|
||||
return buildView;
|
||||
});
|
||||
|
||||
if (!isTabbedView() && myThreeComponentsSplitter.getLastComponent() == null) {
|
||||
@@ -212,15 +258,15 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
myBuildsList.getModel().getSize() > 1 &&
|
||||
myThreeComponentsSplitter.getFirstComponent() == null) {
|
||||
JBScrollPane scrollPane = new JBScrollPane();
|
||||
scrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
scrollPane.setBorder(JBUI.Borders.empty());
|
||||
scrollPane.setViewportView(myBuildsList);
|
||||
myThreeComponentsSplitter.setFirstComponent(scrollPane);
|
||||
myBuildsList.setVisible(true);
|
||||
myBuildsList.setSelectedIndex(0);
|
||||
myThreeComponentsSplitter.repaint();
|
||||
|
||||
for (DuplexConsoleView<BuildConsoleView, ConsoleView> consoleView : myViewMap.values()) {
|
||||
BuildConsoleView buildConsoleView = consoleView.getPrimaryConsoleView();
|
||||
for (BuildView consoleView : myViewMap.values()) {
|
||||
BuildConsoleView buildConsoleView = consoleView.getPrimaryView();
|
||||
if (buildConsoleView instanceof BuildTreeConsoleView) {
|
||||
((BuildTreeConsoleView)buildConsoleView).hideRootNode();
|
||||
}
|
||||
@@ -230,7 +276,7 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
myThreeComponentsSplitter.setFirstComponent(null);
|
||||
}
|
||||
myProgressWatcher.addBuild(buildInfo);
|
||||
view.getPrimaryConsoleView().print("\r", ConsoleViewContentType.SYSTEM_OUTPUT);
|
||||
//view.getPrimaryView().print("\r", ConsoleViewContentType.SYSTEM_OUTPUT);
|
||||
}
|
||||
else {
|
||||
if (event instanceof FinishBuildEvent) {
|
||||
@@ -247,18 +293,18 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
|
||||
runnables.add(() -> {
|
||||
final BuildInfo buildInfo = myBuildsMap.get(event.getId());
|
||||
DuplexConsoleView<BuildConsoleView, ConsoleView> view = myViewMap.get(buildInfo);
|
||||
BuildView view = myViewMap.get(buildInfo);
|
||||
if (event instanceof OutputBuildEvent) {
|
||||
ConsoleView consoleView = view.getSecondaryConsoleView();
|
||||
ComponentContainer consoleView = view.getSecondaryView();
|
||||
if (consoleView instanceof BuildConsoleView) {
|
||||
((BuildConsoleView)consoleView).onEvent(event);
|
||||
}
|
||||
else {
|
||||
consoleView.print(event.getMessage(), ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
else if ((consoleView instanceof ConsoleView)) {
|
||||
((ConsoleView)consoleView).print(event.getMessage(), ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
view.getPrimaryConsoleView().onEvent(event);
|
||||
view.getPrimaryView().onEvent(event);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -275,7 +321,7 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
BuildInfo selectedBuild = myBuildsList.getSelectedValue();
|
||||
if (selectedBuild == null) return;
|
||||
|
||||
DuplexConsoleView<BuildConsoleView, ConsoleView> view = myViewMap.get(selectedBuild);
|
||||
BuildView view = myViewMap.get(selectedBuild);
|
||||
JComponent lastComponent = myThreeComponentsSplitter.getLastComponent();
|
||||
if (view != null && lastComponent != view.getComponent()) {
|
||||
myThreeComponentsSplitter.setLastComponent(view.getComponent());
|
||||
@@ -392,49 +438,61 @@ public abstract class AbstractViewManager implements BuildProgressListener, Disp
|
||||
}
|
||||
}
|
||||
|
||||
private class BuildDuplexConsoleView extends DuplexConsoleView<BuildConsoleView, ConsoleView> implements DataProvider {
|
||||
private final ExecutionConsole myExecutionConsole;
|
||||
private static class BuildView extends CompositeView<BuildConsoleView, ComponentContainer> implements DataProvider {
|
||||
private final ComponentContainer myComponentContainer;
|
||||
private final StartBuildEvent myEvent;
|
||||
|
||||
public BuildDuplexConsoleView(ExecutionConsole executionConsole, StartBuildEvent event) {
|
||||
super(new BuildTreeConsoleView(AbstractViewManager.this.myProject), (ConsoleView)executionConsole);
|
||||
myExecutionConsole = executionConsole;
|
||||
public BuildView(Project project, ComponentContainer componentContainer, StartBuildEvent event) {
|
||||
super(new BuildTreeConsoleView(project), componentContainer);
|
||||
myComponentContainer = componentContainer;
|
||||
myEvent = event;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AnAction[] createConsoleActions() {
|
||||
final DefaultActionGroup textActionGroup = new DefaultActionGroup() {
|
||||
final DefaultActionGroup rerunActionGroup = new DefaultActionGroup();
|
||||
AnAction stopAction = null;
|
||||
if (myEvent.getProcessHandler() != null) {
|
||||
stopAction = new StopProcessAction("Stop", "Stop", myEvent.getProcessHandler());
|
||||
}
|
||||
final DefaultActionGroup consoleActionGroup = new DefaultActionGroup() {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
e.getPresentation().setVisible(!BuildDuplexConsoleView.this.isPrimaryConsoleEnabled());
|
||||
e.getPresentation().setVisible(!BuildView.this.isPrimaryConsoleEnabled());
|
||||
}
|
||||
};
|
||||
final AnAction[] consoleActions = ((ConsoleView)myExecutionConsole).createConsoleActions();
|
||||
for (AnAction anAction : consoleActions) {
|
||||
textActionGroup.add(anAction);
|
||||
if (myComponentContainer instanceof BuildConsoleView) {
|
||||
final AnAction[] consoleActions = ((BuildConsoleView)myComponentContainer).createConsoleActions();
|
||||
for (AnAction anAction : consoleActions) {
|
||||
if (anAction instanceof StopAction) {
|
||||
if (stopAction == null) {
|
||||
stopAction = anAction;
|
||||
}
|
||||
}
|
||||
else if (!(anAction instanceof FakeRerunAction ||
|
||||
anAction instanceof PinToolwindowTabAction ||
|
||||
anAction instanceof CloseAction)) {
|
||||
consoleActionGroup.add(anAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<AnAction> anActions = ContainerUtil.newArrayList();
|
||||
final DefaultActionGroup actionGroup = new DefaultActionGroup();
|
||||
AnAction[] restartActions = myEvent.getRestartActions();
|
||||
for (AnAction anAction : restartActions) {
|
||||
actionGroup.add(anAction);
|
||||
for (AnAction anAction : myEvent.getRestartActions()) {
|
||||
rerunActionGroup.add(anAction);
|
||||
}
|
||||
if (myEvent.getProcessHandler() != null) {
|
||||
actionGroup.add(new StopProcessAction("Stop", "Stop", myEvent.getProcessHandler()));
|
||||
if (stopAction != null) {
|
||||
rerunActionGroup.add(stopAction);
|
||||
}
|
||||
actionGroup.add(rerunActionGroup);
|
||||
actionGroup.addSeparator();
|
||||
AnAction[] actions = super.createConsoleActions();
|
||||
actionGroup.addAll(actions);
|
||||
if (actions.length > 0) {
|
||||
actionGroup.addSeparator();
|
||||
}
|
||||
anActions.add(actionGroup);
|
||||
anActions.add(textActionGroup);
|
||||
return ArrayUtil.toObjectArray(anActions, AnAction.class);
|
||||
return new AnAction[]{actionGroup, consoleActionGroup};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.ui.ComponentContainer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public interface BuildConsoleView extends ConsoleView, BuildProgressListener {
|
||||
String getViewId();
|
||||
public interface BuildConsoleView extends ComponentContainer, BuildProgressListener {
|
||||
AnAction[] createConsoleActions();
|
||||
}
|
||||
|
||||
@@ -38,11 +38,6 @@ public class BuildTextConsoleView extends ConsoleViewImpl implements BuildConsol
|
||||
super(project, viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewId() {
|
||||
return "console";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
myAnsiEscapeDecoder.escapeText(event.getMessage(), ProcessOutputTypes.STDOUT, this);
|
||||
|
||||
@@ -266,11 +266,6 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getViewId() {
|
||||
return "TREE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(BuildEvent event) {
|
||||
ExecutionNode parentNode = event.getParentId() == null ? null : nodesMap.get(event.getParentId());
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.build;
|
||||
|
||||
import com.intellij.execution.console.ConsoleHistoryController;
|
||||
import com.intellij.execution.console.LanguageConsoleView;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.ui.ComponentContainer;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class CompositeView<S extends ComponentContainer, T extends ComponentContainer> extends JPanel
|
||||
implements ComponentContainer, DataProvider {
|
||||
private final static String PRIMARY_PANEL = "PRIMARY_PANEL";
|
||||
private final static String SECONDARY_PANEL = "SECONDARY_PANEL";
|
||||
|
||||
@NotNull
|
||||
private final S myPrimaryView;
|
||||
@NotNull
|
||||
private final T mySecondaryView;
|
||||
private boolean myPrimary;
|
||||
@NotNull
|
||||
private final SwitchViewAction mySwitchViewAction;
|
||||
|
||||
public CompositeView(@NotNull S primaryView, @NotNull T secondaryView) {
|
||||
super(new CardLayout());
|
||||
myPrimaryView = primaryView;
|
||||
mySecondaryView = secondaryView;
|
||||
|
||||
add(myPrimaryView.getComponent(), PRIMARY_PANEL);
|
||||
add(mySecondaryView.getComponent(), SECONDARY_PANEL);
|
||||
|
||||
mySwitchViewAction = new SwitchViewAction();
|
||||
|
||||
myPrimary = true;
|
||||
enableView(true);
|
||||
|
||||
Disposer.register(this, myPrimaryView);
|
||||
Disposer.register(this, mySecondaryView);
|
||||
}
|
||||
|
||||
public void enableView(boolean primary) {
|
||||
if (primary == myPrimary) return;
|
||||
|
||||
CardLayout cl = (CardLayout)(getLayout());
|
||||
cl.show(this, primary ? PRIMARY_PANEL : SECONDARY_PANEL);
|
||||
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(() -> {
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(getView(primary).getComponent(), true);
|
||||
});
|
||||
myPrimary = primary;
|
||||
}
|
||||
|
||||
public boolean isPrimaryConsoleEnabled() {
|
||||
return myPrimary;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public S getPrimaryView() {
|
||||
return myPrimaryView;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public T getSecondaryView() {
|
||||
return mySecondaryView;
|
||||
}
|
||||
|
||||
public ComponentContainer getView(boolean primary) {
|
||||
return primary ? getPrimaryView() : getSecondaryView();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AnAction[] createConsoleActions() {
|
||||
List<AnAction> actions = ContainerUtil.newArrayList();
|
||||
actions.add(mySwitchViewAction);
|
||||
LanguageConsoleView langConsole =
|
||||
ContainerUtil.findInstance(Arrays.asList(myPrimaryView, mySecondaryView), LanguageConsoleView.class);
|
||||
ConsoleHistoryController controller = langConsole != null ? ConsoleHistoryController.getController(langConsole) : null;
|
||||
if (controller != null) actions.add(controller.getBrowseHistory());
|
||||
|
||||
return ArrayUtil.toObjectArray(actions, AnAction.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusableComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
final ComponentContainer consoleView = getView(isPrimaryConsoleEnabled());
|
||||
return consoleView instanceof DataProvider ? ((DataProvider)consoleView).getData(dataId) : null;
|
||||
}
|
||||
|
||||
private class SwitchViewAction extends ToggleAction implements DumbAware {
|
||||
public SwitchViewAction() {
|
||||
super("Toggle view", null,
|
||||
AllIcons.Actions.ChangeView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(final AnActionEvent event) {
|
||||
return !isPrimaryConsoleEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(final AnActionEvent event, final boolean flag) {
|
||||
enableView(!flag);
|
||||
ApplicationManager.getApplication().invokeLater(() -> update(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,15 @@ package com.intellij.build.events;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.ExecutionConsole;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
@@ -42,7 +44,7 @@ public interface StartBuildEvent extends StartEvent {
|
||||
AnAction[] getRestartActions();
|
||||
|
||||
@Nullable
|
||||
ExecutionConsole getExecutionConsole();
|
||||
Supplier<RunContentDescriptor> getContentDescriptorSupplier();
|
||||
|
||||
@Nullable
|
||||
Consumer<ConsoleView> getAttachedConsoleConsumer();
|
||||
|
||||
@@ -19,7 +19,7 @@ import com.intellij.build.events.StartBuildEvent;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.ExecutionConsole;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.SmartList;
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
@@ -41,9 +42,9 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
@NotNull
|
||||
private List<AnAction> myRestartActions = new SmartList<>();
|
||||
@Nullable
|
||||
private ExecutionConsole myExecutionConsole;
|
||||
@Nullable
|
||||
private ExecutionEnvironment myExecutionEnvironment;
|
||||
@Nullable
|
||||
private Supplier<RunContentDescriptor> myContentDescriptorSupplier;
|
||||
|
||||
public StartBuildEventImpl(@NotNull Object eventId,
|
||||
@NotNull String buildTitle,
|
||||
@@ -78,8 +79,8 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ExecutionConsole getExecutionConsole() {
|
||||
return myExecutionConsole;
|
||||
public Supplier<RunContentDescriptor> getContentDescriptorSupplier() {
|
||||
return myContentDescriptorSupplier;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -105,13 +106,13 @@ public class StartBuildEventImpl extends StartEventImpl implements StartBuildEve
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartBuildEventImpl withConsoleView(ExecutionConsole executionConsole) {
|
||||
myExecutionConsole = executionConsole;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartBuildEventImpl withExecutionEnvironment(ExecutionEnvironment env) {
|
||||
myExecutionEnvironment = env;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StartBuildEventImpl withContentDescriptorSupplier(Supplier<RunContentDescriptor> contentDescriptorSupplier) {
|
||||
myContentDescriptorSupplier = contentDescriptorSupplier;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +91,10 @@ run.configuration.settings.label.project={0} project:
|
||||
run.configuration.settings.label.tasks=Tasks:
|
||||
run.configuration.settings.label.vmoptions=VM options:
|
||||
run.configuration.settings.label.arguments=Arguments:
|
||||
run.text.starting.multiple.task={0}: Executing tasks ''{1}''...\n
|
||||
run.text.starting.single.task={0}: Executing task ''{1}''...\n
|
||||
run.text.ended.multiple.task={0}: Tasks execution finished ''{1}''.\n
|
||||
run.text.ended.single.task={0}: Task execution finished ''{1}''.\n
|
||||
run.text.starting.multiple.task={0}: Executing tasks ''{1}''...
|
||||
run.text.starting.single.task={0}: Executing task ''{1}''...
|
||||
run.text.ended.multiple.task={0}: Tasks execution finished ''{1}''.
|
||||
run.text.ended.single.task={0}: Task execution finished ''{1}''.
|
||||
run.error.undefined.task=No task to execute is specified
|
||||
run.invalid.jvm.agent.configuration=Invalid JVM agent configuration used ''{0}''
|
||||
|
||||
|
||||
+61
-26
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.externalSystem.service.execution;
|
||||
|
||||
import com.intellij.build.BuildProgressListener;
|
||||
import com.intellij.build.BuildViewManager;
|
||||
import com.intellij.build.TasksViewManager;
|
||||
import com.intellij.build.events.BuildEvent;
|
||||
import com.intellij.build.events.impl.FailureResultImpl;
|
||||
@@ -28,11 +29,14 @@ import com.intellij.execution.configurations.*;
|
||||
import com.intellij.execution.console.DuplexConsoleView;
|
||||
import com.intellij.execution.executors.DefaultDebugExecutor;
|
||||
import com.intellij.execution.impl.ConsoleViewImpl;
|
||||
import com.intellij.execution.impl.ExecutionManagerImpl;
|
||||
import com.intellij.execution.process.ProcessHandler;
|
||||
import com.intellij.execution.process.ProcessOutputTypes;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.runners.FakeRerunAction;
|
||||
import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.execution.ui.ExecutionConsole;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
@@ -76,6 +80,7 @@ import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -157,7 +162,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException {
|
||||
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) {
|
||||
MyRunnableState runnableState =
|
||||
new MyRunnableState(mySettings, getProject(), DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId()), this, env);
|
||||
copyUserDataTo(runnableState);
|
||||
@@ -188,6 +193,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
|
||||
@NotNull private final Project myProject;
|
||||
@NotNull private final ExternalSystemRunConfiguration myConfiguration;
|
||||
@NotNull private final ExecutionEnvironment myEnv;
|
||||
@Nullable private RunContentDescriptor myContentDescriptor;
|
||||
|
||||
private final int myDebugPort;
|
||||
|
||||
@@ -288,36 +294,16 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
|
||||
public void onStart(@NotNull ExternalSystemTaskId id, String workingDir) {
|
||||
if (progressListener != null) {
|
||||
long eventTime = System.currentTimeMillis();
|
||||
AnAction rerunTaskAction = new AnAction() {
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
super.update(e);
|
||||
Presentation p = e.getPresentation();
|
||||
p.setEnabled(processHandler.isProcessTerminated());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
try {
|
||||
MyRunnableState.this.execute(executor, runner);
|
||||
}
|
||||
catch (ExecutionException ex) {
|
||||
LOG.warn(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
rerunTaskAction.getTemplatePresentation().setText("Rerun");
|
||||
rerunTaskAction.getTemplatePresentation().setDescription("Rerun");
|
||||
rerunTaskAction.getTemplatePresentation().setIcon(AllIcons.Actions.Restart);
|
||||
AnAction rerunTaskAction = new MyTaskRerunAction(progressListener, myEnv, myContentDescriptor);
|
||||
progressListener.onEvent(
|
||||
new StartBuildEventImpl(id, executionName, eventTime, "running...")
|
||||
.withProcessHandler(processHandler, view -> {
|
||||
processHandler.notifyTextAvailable(greeting, ProcessOutputTypes.SYSTEM);
|
||||
processHandler.notifyTextAvailable(greeting + "\n\n", ProcessOutputTypes.SYSTEM);
|
||||
foldGreetingOrFarewell(consoleView, greeting, true);
|
||||
})
|
||||
.withContentDescriptorSupplier(() -> myContentDescriptor)
|
||||
.withRestartAction(rerunTaskAction)
|
||||
.withRestartActions(restartActions)
|
||||
.withConsoleView(consoleView)
|
||||
.withExecutionEnvironment(myEnv));
|
||||
}
|
||||
}
|
||||
@@ -371,14 +357,18 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
|
||||
farewell =
|
||||
ExternalSystemBundle.message("run.text.ended.single.task", endDateTime, mySettings.toString());
|
||||
}
|
||||
processHandler.notifyTextAvailable(farewell, ProcessOutputTypes.SYSTEM);
|
||||
processHandler.notifyTextAvailable(farewell + "\n", ProcessOutputTypes.SYSTEM);
|
||||
foldGreetingOrFarewell(consoleView, farewell, false);
|
||||
processHandler.notifyProcessTerminated(0);
|
||||
}
|
||||
};
|
||||
task.execute(ArrayUtil.prepend(taskListener, ExternalSystemTaskNotificationListener.EP_NAME.getExtensions()));
|
||||
});
|
||||
return new DefaultExecutionResult(null, processHandler);
|
||||
return new DefaultExecutionResult(consoleView, processHandler);
|
||||
}
|
||||
|
||||
public void setContentDescriptor(@Nullable RunContentDescriptor contentDescriptor) {
|
||||
myContentDescriptor = contentDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,4 +429,49 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyTaskRerunAction extends FakeRerunAction {
|
||||
private final BuildProgressListener myProgressListener;
|
||||
private final RunContentDescriptor myContentDescriptor;
|
||||
private final ExecutionEnvironment myEnvironment;
|
||||
|
||||
public MyTaskRerunAction(BuildProgressListener progressListener,
|
||||
ExecutionEnvironment environment,
|
||||
RunContentDescriptor contentDescriptor) {
|
||||
myProgressListener = progressListener;
|
||||
myContentDescriptor = contentDescriptor;
|
||||
myEnvironment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent event) {
|
||||
Presentation presentation = event.getPresentation();
|
||||
ExecutionEnvironment environment = getEnvironment(event);
|
||||
if (environment != null) {
|
||||
presentation.setText(ExecutionBundle.message("rerun.configuration.action.name",
|
||||
StringUtil.escapeMnemonics(environment.getRunProfile().getName())));
|
||||
Icon icon = ExecutionManagerImpl.isProcessRunning(getDescriptor(event))
|
||||
? AllIcons.Actions.Restart
|
||||
: myProgressListener instanceof BuildViewManager
|
||||
? AllIcons.Actions.Compile
|
||||
: environment.getExecutor().getIcon();
|
||||
presentation.setIcon(icon);
|
||||
presentation.setEnabled(isEnabled(event));
|
||||
return;
|
||||
}
|
||||
|
||||
presentation.setEnabled(false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected RunContentDescriptor getDescriptor(AnActionEvent event) {
|
||||
return myContentDescriptor != null ? myContentDescriptor : super.getDescriptor(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ExecutionEnvironment getEnvironment(@NotNull AnActionEvent event) {
|
||||
return myEnvironment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-1
@@ -53,7 +53,22 @@ public class ExternalSystemTaskDebugRunner extends GenericDebuggerRunner {
|
||||
int port = ((ExternalSystemRunConfiguration.MyRunnableState)state).getDebugPort();
|
||||
if (port > 0) {
|
||||
RemoteConnection connection = new RemoteConnection(true, "127.0.0.1", String.valueOf(port), true);
|
||||
return attachVirtualMachine(state, environment, connection, true);
|
||||
RunContentDescriptor runContentDescriptor = attachVirtualMachine(state, environment, connection, true);
|
||||
if (runContentDescriptor == null) return null;
|
||||
|
||||
((ExternalSystemRunConfiguration.MyRunnableState)state).setContentDescriptor(runContentDescriptor);
|
||||
RunContentDescriptor descriptor =
|
||||
new RunContentDescriptor(runContentDescriptor.getExecutionConsole(), runContentDescriptor.getProcessHandler(),
|
||||
runContentDescriptor.getComponent(), runContentDescriptor.getDisplayName(),
|
||||
runContentDescriptor.getIcon(), runContentDescriptor.getActivationCallback(),
|
||||
runContentDescriptor.getRestartActions()) {
|
||||
@Override
|
||||
public boolean isHiddenContent() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
descriptor.setRunnerLayoutUi(runContentDescriptor.getRunnerLayoutUi());
|
||||
return descriptor;
|
||||
}
|
||||
else {
|
||||
LOG.warn("Can't attach debugger to external system task execution. Reason: target debug port is unknown");
|
||||
|
||||
+15
-4
@@ -22,6 +22,7 @@ import com.intellij.execution.configurations.RunnerSettings
|
||||
import com.intellij.execution.executors.DefaultRunExecutor
|
||||
import com.intellij.execution.runners.ExecutionEnvironment
|
||||
import com.intellij.execution.runners.GenericProgramRunner
|
||||
import com.intellij.execution.runners.RunContentBuilder
|
||||
import com.intellij.execution.ui.RunContentDescriptor
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants
|
||||
import javax.swing.JComponent
|
||||
@@ -41,12 +42,22 @@ class ExternalSystemTaskRunner : GenericProgramRunner<RunnerSettings>() {
|
||||
|
||||
@Throws(ExecutionException::class)
|
||||
override fun doExecute(state: RunProfileState, environment: ExecutionEnvironment): RunContentDescriptor? {
|
||||
val executionResult = state.execute(environment.executor, this) ?: return null
|
||||
if (state !is ExternalSystemRunConfiguration.MyRunnableState) return null
|
||||
|
||||
return object : RunContentDescriptor(executionResult.executionConsole, executionResult.processHandler,
|
||||
EMPTY_COMPONENT, environment.runProfile.name, null) {
|
||||
override fun isHiddenContent() = true
|
||||
val executionResult = state.execute(environment.executor, this) ?: return null
|
||||
val runContentDescriptor = RunContentBuilder(executionResult, environment).showRunContent(environment.contentToReuse) ?: return null
|
||||
|
||||
state.setContentDescriptor(runContentDescriptor)
|
||||
val descriptor = object : RunContentDescriptor(runContentDescriptor.executionConsole, runContentDescriptor.processHandler,
|
||||
runContentDescriptor.component, runContentDescriptor.displayName,
|
||||
runContentDescriptor.icon, runContentDescriptor.activationCallback,
|
||||
runContentDescriptor.restartActions) {
|
||||
override fun isHiddenContent(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
descriptor.runnerLayoutUi = runContentDescriptor.runnerLayoutUi
|
||||
return descriptor
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+1
-2
@@ -567,8 +567,7 @@ public class ExternalSystemUtil {
|
||||
}
|
||||
|
||||
public void cancellImport() {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(
|
||||
(Runnable)() -> myTask.cancel(ExternalSystemTaskNotificationListener.EP_NAME.getExtensions()));
|
||||
myTask.cancel(ExternalSystemTaskNotificationListener.EP_NAME.getExtensions());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user