Skip to content

Commit

Permalink
Implemented proper integration of bld execution with a console window…
Browse files Browse the repository at this point in the history
… showing activity.
  • Loading branch information
gbevin committed Jul 14, 2024
1 parent 742aad3 commit a0e4e69
Show file tree
Hide file tree
Showing 14 changed files with 533 additions and 70 deletions.
17 changes: 17 additions & 0 deletions src/main/java/icons/BldIcons.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package icons;

import com.intellij.openapi.util.IconLoader;

import javax.swing.*;

public class BldIcons {
private static javax.swing.Icon load(String path) {
return IconLoader.getIcon(path, BldIcons.class);
}

public static final Icon Icon = load("/icons/bldIcon.svg");
}
36 changes: 36 additions & 0 deletions src/main/java/rife/bld/idea/ProjectOpenStartupActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.idea;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.ProjectActivity;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import rife.bld.idea.execution.BldExecution;

public class ProjectOpenStartupActivity implements ProjectActivity {
@Nullable
@Override
public Object execute(@NotNull Project project, @NotNull Continuation<? super Unit> continuation) {
System.out.println("Startup");

BldExecution.listTasks(project);

/* Clear console window. */
// ApplicationManager.getApplication().invokeAndWait(() -> {
// ConsoleView executionConsole = BldConsoleManager.getConsole(project);
// executionConsole.getComponent().setVisible(true);
// executionConsole.clear();
// var console = ToolWindowManagerEx.getInstance(project).getToolWindow(BldConstants.BLD_CONSOLE_NAME);
// if (console != null) {
// console.activate(null);
// }
// }, ModalityState.nonModal());

return null;
}
}
69 changes: 69 additions & 0 deletions src/main/java/rife/bld/idea/console/BldConsoleManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.idea.console;

import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
import rife.bld.idea.utils.BldPluginDisposable;

public class BldConsoleManager {
private final ConsoleView bldConsole_;

public BldConsoleManager(@NotNull Project project) {
bldConsole_ = createNewConsole(project);
Disposer.register(BldPluginDisposable.getInstance(project), bldConsole_);
}

private static ConsoleView createNewConsole(@NotNull Project project) {
return TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();
}

public static ConsoleView getConsole(@NotNull Project project) {
var service = project.getService(BldConsoleManager.class);
return service.getConsole();
}

public ConsoleView getConsole() {
return bldConsole_;
}

public static void showTaskMessage(@NotNull String message, @NotNull ConsoleViewContentType type, @NotNull Project project) {
var executionConsole = BldConsoleManager.getConsole(project);
// Create a filter that monitors console outputs, and turns them into a hyperlink if applicable.
Filter filter = (line, entireLength) -> {
// Optional<ParseResult> result = ParseResult.parseErrorLocation(line, ERROR_TAG);
// if (result.isPresent()) {
//
// OpenFileHyperlinkInfo linkInfo = new OpenFileHyperlinkInfo(
// project,
// result.get().getFile(),
// result.get().getLineNumber() - 1, // line number needs to be 0 indexed
// result.get().getColumnNumber() - 1 // column number needs to be 0 indexed
// );
// int startHyperlink = entireLength - line.length() + line.indexOf(ERROR_TAG);
//
// return new Filter.Result(
// startHyperlink,
// entireLength,
// linkInfo,
// null // TextAttributes, going with default hence null
// );
// }
return null;
};

ApplicationManager.getApplication().invokeLater(() -> {
executionConsole.addMessageFilter(filter);
executionConsole.print(message, type);
}, ModalityState.nonModal());
}
}
135 changes: 135 additions & 0 deletions src/main/java/rife/bld/idea/console/BldConsoleViewPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.idea.console;

import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.errorTreeView.NewErrorTreeRenderer;
import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.ui.AutoScrollToSourceHandler;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SideBorder;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import rife.bld.idea.execution.BldExecution;
import rife.bld.idea.utils.BldBundle;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;

public class BldConsoleViewPanel extends JPanel {
protected static final Logger LOG = Logger.getInstance("#com.intellij.ide.errorTreeView.NewErrorTreeViewPanel");

private final ErrorTreeViewConfiguration configuration_;
protected Project project_;

public BldConsoleViewPanel(Project project, ConsoleView console) {
project_ = project;
configuration_ = ErrorTreeViewConfiguration.getInstance(project);
setLayout(new BorderLayout());

AutoScrollToSourceHandler auto_scroll_to_source = new AutoScrollToSourceHandler() {
@Override
protected boolean isAutoScrollMode() {
return configuration_.isAutoscrollToSource();
}

@Override
protected void setAutoScrollMode(boolean state) {
configuration_.setAutoscrollToSource(state);
}
};

var message_panel = new JPanel(new BorderLayout());

var root = new DefaultMutableTreeNode();
final var tree_model = new DefaultTreeModel(root);
var tree = createTree(tree_model);
tree.getEmptyText().setText(IdeBundle.message("errortree.noMessages"));

auto_scroll_to_source.install(tree);
TreeUtil.installActions(tree);

tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.setLargeModel(true);

var scroll_pane = NewErrorTreeRenderer.install(tree);
scroll_pane.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT));
message_panel.add(console.getComponent(), BorderLayout.CENTER);

add(createToolbarPanel(), BorderLayout.WEST);

add(message_panel, BorderLayout.CENTER);

EditSourceOnDoubleClickHandler.install(tree);
}

@NotNull
protected Tree createTree(@NotNull final DefaultTreeModel treeModel) {
return new Tree(treeModel) {
@Override
public void setRowHeight(int i) {
super.setRowHeight(0);
// this is needed in order to make UI calculate the height for each particular row
}
};
}

private static class StopAction extends DumbAwareAction {
public StopAction() {
super(IdeBundle.message("action.stop"), null, AllIcons.Actions.Suspend);
}

@Override
public void actionPerformed(AnActionEvent e) {
var project = e.getProject();
if (project != null) {
BldExecution.terminateBldProcess(project);
BldConsoleManager.getConsole(project).print(BldBundle.message("bld.command.terminated"), ConsoleViewContentType.ERROR_OUTPUT);
}
}

@Override
public void update(AnActionEvent event) {
// Make the action only clickable when there is an active bld process
var presentation = event.getPresentation();
var project = event.getProject();
if (project == null) {
return;
}
presentation.setEnabled(BldExecution.hasActiveBldProcess(project));
}

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
}

private JPanel createToolbarPanel() {
var action = new StopAction();

var group = new DefaultActionGroup();
group.add(action);

var toolbar_panel = new JPanel(new BorderLayout());
var action_manager = ActionManager.getInstance();
var let_toolbar = action_manager.createActionToolbar(ActionPlaces.COMPILER_MESSAGES_TOOLBAR, group, false);
toolbar_panel.add(let_toolbar.getComponent(), BorderLayout.WEST);

return toolbar_panel;
}
}
21 changes: 21 additions & 0 deletions src/main/java/rife/bld/idea/console/BldConsoleWindowFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2024 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
*/
package rife.bld.idea.console;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.ui.content.ContentFactory;
import org.jetbrains.annotations.NotNull;

public class BldConsoleWindowFactory implements ToolWindowFactory {
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
var console = BldConsoleManager.getConsole(project);
var window = new BldConsoleViewPanel(project, console);
var content = ContentFactory.getInstance().createContent(window, null, false);
toolWindow.getContentManager().addContent(content);
}
}
Loading

0 comments on commit a0e4e69

Please sign in to comment.