import com.jetbrains.commandInterface.commandLine.CommandLineLanguage;
import com.jetbrains.commandInterface.commandLine.psi.CommandLineFile;
import com.jetbrains.python.psi.PyUtil;
+import com.jetbrains.toolWindowWithActions.ConsoleWithProcess;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
* @author Ilya.Kazakevich
*/
@SuppressWarnings({"DeserializableClassInSecureContext", "SerializableClassInSecureContext"}) // Nobody will serialize console
-final class CommandConsole extends LanguageConsoleImpl implements Consumer<String>, Condition<LanguageConsoleView> {
+final class CommandConsole extends LanguageConsoleImpl implements Consumer<String>, Condition<LanguageConsoleView>, ConsoleWithProcess {
/**
* List of commands (to be injected into {@link CommandLineFile}) if any
*/
* @return process handler currently running on console (if any) or null if in {@link #switchToCommandMode() command mode}
* @see #switchToProcessMode(ProcessHandler)
*/
+ @Override
@Nullable
- ProcessHandler getProcessHandler() {
+ public ProcessHandler getProcessHandler() {
return myProcessHandler;
}
import com.intellij.execution.console.LanguageConsoleBuilder;
import com.intellij.execution.console.LanguageConsoleView;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.ToolWindowAnchor;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.ui.content.Content;
-import com.intellij.ui.content.ContentManager;
-import com.intellij.ui.content.impl.ContentImpl;
import com.intellij.util.Consumer;
import com.jetbrains.commandInterface.command.Command;
+import com.jetbrains.toolWindowWithActions.WindowWithActions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
final Project project = module.getProject();
final CommandConsole console = CommandConsole.createConsole(module, consoleName, commandList);
- final ToolWindowApi windowApi = new ToolWindowApi(project, consoleName);
- // Add console to the toolwindow wrapping it with tabs
- windowApi.add(ConsoleTabsPanel.wrapConsole(console, new MyCloseDelegate(windowApi)));
+ // Show console on "toolwindow"
+ WindowWithActions.showConsoleWithProcess(console,
+ console.getEditor().getComponent(),
+ consoleName,
+ project,
+ null);
ArgumentHintLayer.attach(console); // Display [arguments]
return console;
}
-
- /**
- * Console tabs needs so-called "closer": engine to be called when user wishes to close tabs.
- * We need to delegate this call to the {@link ToolWindowApi#close()} to close whole window
- */
- private static final class MyCloseDelegate implements Runnable {
- @NotNull
- private final ToolWindowApi myWindowApi;
-
- private MyCloseDelegate(@NotNull final ToolWindowApi windowApi) {
- myWindowApi = windowApi;
- }
-
- @Override
- public void run() {
- myWindowApi.close();
- }
- }
}
+++ /dev/null
-/*
- * Copyright 2000-2015 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.jetbrains.commandInterface.console;
-
-import com.intellij.execution.actions.StopProcessAction;
-import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;
-import com.intellij.ide.actions.CloseAction;
-import com.intellij.openapi.actionSystem.*;
-import com.jetbrains.python.PyBundle;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-
-/**
- * Panel with action buttons that wraps {@link CommandConsole}.
- * Entry point is {@link #wrapConsole(CommandConsole, Runnable)}. You may then just add it to what ever you want.
- *
- * @author Ilya.Kazakevich
- */
-@SuppressWarnings({"DeserializableClassInSecureContext", "SerializableClassInSecureContext"}) // Who will serialize panel?
-final class ConsoleTabsPanel extends JPanel {
- private ConsoleTabsPanel() {
-
- }
-
- /**
- * Wraps console with panel with buttons returning composite component to add somewhere.
- *
- * @param console Console to wrap.
- * @param closer Listener to delegate "close all" command (when user clicks red cross aka "close" button)
- * @return composite component with console on the right part and buttons on the left part
- */
- @NotNull
- static JComponent wrapConsole(@NotNull final CommandConsole console, @NotNull final Runnable closer) {
- final ConsoleTabsPanel instance = new ConsoleTabsPanel();
-
- // Box layout: panel goes to the left, console to the right
- final LayoutManager layout = new BoxLayout(instance, BoxLayout.LINE_AXIS);
- instance.setLayout(layout);
-
- // use actions from console itself
- final List<AnAction> actionList = new ArrayList<AnAction>(Arrays.asList(console.createConsoleActions()));
- actionList.add(new MyCloseAction(closer, console)); // "Close" action
- actionList.add(new MyStopProcessAction(console)); // "Stop process" action
-
-
- final DefaultActionGroup toolbarActions = new DefaultActionGroup(actionList);
-
- final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, toolbarActions, false);
- toolbar.setTargetComponent(console);
-
- // TODO: Move GUI and alignment out of here.
- final JComponent toolbarComponent = toolbar.getComponent();
-
- toolbarComponent.setMaximumSize(toolbarComponent.getPreferredSize()); // To make actions panel as small as possible (not 50% of width)
- toolbarComponent.setAlignmentY(0); // Align actions to the top
- instance.add(toolbarComponent);
- instance.add(console.getComponent());
- AbstractConsoleRunnerWithHistory.registerActionShortcuts(actionList, console.getConsoleEditor().getComponent());
- return instance;
- }
-
- /**
- * Closes console and notifies closer when user clicks "close"
- */
- private static final class MyCloseAction extends CloseAction {
- @NotNull
- private final Runnable myCloser;
- @NotNull
- private final CommandConsole myConsole;
-
- /**
- * @param closer engine to be called when user clicks "close"
- * @param console console itself
- */
- MyCloseAction(@NotNull final Runnable closer, @NotNull final CommandConsole console) {
- myCloser = closer;
- myConsole = console;
- }
-
- @Override
- public void update(final AnActionEvent e) {
- super.update(e);
- e.getPresentation().setText(PyBundle.message("commandLine.closeWindow"));
- }
-
- @Override
- public void actionPerformed(final AnActionEvent e) {
- super.actionPerformed(e);
- StopProcessAction.stopProcess(myConsole.getProcessHandler()); // Stop process before closing console, no need to left junk
- myCloser.run();
- }
- }
-
- /**
- * Stops currently running process (if any)
- */
- private static final class MyStopProcessAction extends StopProcessAction {
- private final CommandConsole myConsole;
-
- /**
- * @param console command console where process takes place
- */
- private MyStopProcessAction(@NotNull final CommandConsole console) {
- super(PyBundle.message("commandLine.stopProcess"), null, null);
- myConsole = console;
- }
-
- @Override
- public void update(final AnActionEvent e) {
- super.update(e);
- setProcessHandler(myConsole.getProcessHandler()); // Attach action to process handler (if any) or detach (if no process runs)
- }
- }
-}
commandLine.argumentHint.defaultName=arguments
# What to display of user entered junk
commandLine.commandNotFound={0}: command not found
+
+# Window with actions
# "X" button title
-commandLine.closeWindow=Close command line window
+windowWithActions.closeWindow=Close window
# "Stop" button title
-commandLine.stopProcess=Stop currently running process
-
+windowWithActions.stopProcess=Stop currently running process
--- /dev/null
+/*
+ * Copyright 2000-2015 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.jetbrains.toolWindowWithActions;
+
+import com.intellij.execution.actions.StopProcessAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.jetbrains.python.PyBundle;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * "Stop" action that stops process, attached to console.
+ * It also stops process when {@link #run()} is called. Useful for cases like some "close listener"
+ *
+ * @author Ilya.Kazakevich
+ */
+final class ConsoleStopProcessAction extends StopProcessAction implements Runnable {
+ private final ConsoleWithProcess myConsole;
+
+
+ ConsoleStopProcessAction(@NotNull final ConsoleWithProcess console) {
+ super(PyBundle.message("windowWithActions.stopProcess"), null, null);
+ myConsole = console;
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ super.update(e);
+ setProcessHandler(myConsole.getProcessHandler()); // Attach action to process handler (if any) or detach (if no process runs)
+ }
+
+
+ @Override
+ public void run() {
+ stopProcess(myConsole.getProcessHandler());
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2015 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.jetbrains.toolWindowWithActions;
+
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.ui.ConsoleView;
+import org.jetbrains.annotations.Nullable;
+
+// TODO: Move to the same package as ConsoleView
+/**
+ * Console that knows how to run process. Such console stores somewhere {@link ProcessHandler} passed
+ * to {@link #attachToProcess(ProcessHandler)} and may return it via {@link #getProcessHandler()}
+ *
+ * @author Ilya.Kazakevich
+ */
+public interface ConsoleWithProcess extends ConsoleView {
+ /**
+ * @return process handler of process currently running or null if no such process
+ */
+ @Nullable
+ ProcessHandler getProcessHandler();
+}
--- /dev/null
+/*
+ * Copyright 2000-2015 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.jetbrains.toolWindowWithActions;
+
+import com.intellij.execution.runners.AbstractConsoleRunnerWithHistory;
+import com.intellij.ide.actions.CloseAction;
+import com.intellij.openapi.actionSystem.*;
+import com.jetbrains.python.PyBundle;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Panel with action buttons that wraps come widget adding action buttons.
+ * Entry point is {@link #wrap(JComponent, Collection, JComponent, AnAction...)}.
+ *
+ * @author Ilya.Kazakevich
+ */
+@SuppressWarnings({"DeserializableClassInSecureContext", "SerializableClassInSecureContext"}) // Who will serialize panel?
+final class PanelWithActions extends JPanel {
+ private PanelWithActions() {
+
+ }
+
+ /**
+ * Wraps component with panel with buttons returning composite component to add somewhere.
+ *
+ * @param dataComponent component to wrap with action panel
+ * @param closeListeners Listeners to delegate "close all" command (when user clicks red cross aka "close" button)
+ * @param actionListenerComponent component to bind to action shortcuts (null if no shortcuts will be used)
+ * @param customActions additional actions to add
+ * @return composite component with console on the right part and buttons on the left part
+ */
+ @NotNull
+ static JComponent wrap(@NotNull final JComponent dataComponent,
+ @NotNull final Collection<Runnable> closeListeners,
+ @Nullable final JComponent actionListenerComponent,
+ @NotNull final AnAction... customActions) {
+ final PanelWithActions instance = new PanelWithActions();
+
+ // Box layout: panel goes to the left, console to the right
+ final LayoutManager layout = new BoxLayout(instance, BoxLayout.LINE_AXIS);
+ instance.setLayout(layout);
+
+ // use actions from console itself
+
+
+ final List<AnAction> actionList = new ArrayList<AnAction>(Arrays.asList(customActions));
+ final DefaultActionGroup toolbarActions = new DefaultActionGroup();
+ actionList.add(new MyCloseAction(closeListeners));
+ toolbarActions.addAll(actionList);
+
+ final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, toolbarActions, false);
+ toolbar.setTargetComponent(dataComponent);
+
+ // TODO: Move GUI and alignment out of here.
+ final JComponent toolbarComponent = toolbar.getComponent();
+
+ toolbarComponent.setMaximumSize(toolbarComponent.getPreferredSize()); // To make actions panel as small as possible (not 50% of width)
+ toolbarComponent.setAlignmentY(0); // Align actions to the top
+ instance.add(toolbarComponent);
+ instance.add(dataComponent);
+ if (actionListenerComponent != null) {
+ AbstractConsoleRunnerWithHistory.registerActionShortcuts(actionList, actionListenerComponent);
+ }
+ return instance;
+ }
+
+ /**
+ * Closes console and notifies close listeners when user clicks "close"
+ */
+ private static final class MyCloseAction extends CloseAction {
+ @NotNull
+ private final Collection<Runnable> myCloseListeners = new ArrayList<Runnable>();
+
+ /**
+ * @param closeListeners engines to be called when user clicks "close"
+ */
+ MyCloseAction(@NotNull final Collection<Runnable> closeListeners) {
+ myCloseListeners.addAll(closeListeners);
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ super.update(e);
+ e.getPresentation().setText(PyBundle.message("windowWithActions.closeWindow"));
+ }
+
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ super.actionPerformed(e);
+ for (final Runnable closeListener : myCloseListeners) {
+ closeListener.run();
+ }
+ }
+ }
+}
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.jetbrains.commandInterface.console;
+package com.jetbrains.toolWindowWithActions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
private final ToolWindowManager myToolWindowManager;
/**
- * @param project project
+ * @param project project
* @param windowName name to be used as id (and shown to user)
*/
ToolWindowApi(@NotNull final Project project, @NotNull final String windowName) {
--- /dev/null
+/*
+ * Copyright 2000-2015 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.jetbrains.toolWindowWithActions;
+
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Creates toolwindow at the bottom of the screen displaying {@link ConsoleView console} or some custom {@link JComponent} with
+ * actions on the left side.
+ * <br/>
+ * To display console consider using {@link #showConsole(ConsoleView, JComponent, String, Project, Runnable, AnAction...)}.
+ * For everything else use {@link #show(JComponent, JComponent, String, Project, Runnable, AnAction...)}
+ *
+ * @author Ilya.Kazakevich
+ */
+public final class WindowWithActions {
+
+ private WindowWithActions() {
+ }
+
+
+ /**
+ * Displays console with toolwindow with "close" and "stop" actions.
+ *
+ * @param consoleWithProcess console to display
+ * @param actionListenerComponent component to bind to actions shortcuts (can be null)
+ * @param title window title (should be unique!)
+ * @param project project where displaying takes place
+ * @param closeListeners engines to listen for "close" events. Something that stops console process may be good example of it.
+ * Null if you do not want this delegate to be called.
+ * @param customActions additional actions to add
+ */
+ public static void showConsoleWithProcess(@NotNull final ConsoleWithProcess consoleWithProcess,
+ @Nullable final JComponent actionListenerComponent,
+ @NotNull final String title,
+ @NotNull final Project project,
+ @Nullable final Collection<Runnable> closeListeners,
+ @NotNull final AnAction... customActions) {
+ final ConsoleStopProcessAction stopProcessAction = new ConsoleStopProcessAction(consoleWithProcess);
+
+ // Add "stop action" as action and as close listener to stop process when console is closing
+ final Collection<Runnable> resultCloseListeners = new ArrayList<Runnable>(Collections.singleton(stopProcessAction));
+ if (closeListeners != null) {
+ resultCloseListeners.addAll(closeListeners);
+ }
+ final AnAction[] resultActions = ArrayUtil.mergeArrays(new AnAction[]{stopProcessAction}, customActions);
+ showConsole(consoleWithProcess, actionListenerComponent, title, project, resultCloseListeners, resultActions);
+ }
+
+ /**
+ * Displays console in the toolwindow
+ *
+ * @param consoleView console to display
+ * @param actionListenerComponent component to bind to actions shortcuts (can be null)
+ * @param title window title (should be unique!)
+ * @param project project where displaying takes place
+ * @param closeListeners engine to listen for "close" events. Something that stops console process may be good example of it.
+ * Null if you do not want this delegate to be called.
+ * @param customActions additional actions to add
+ */
+ public static void showConsole(@NotNull final ConsoleView consoleView,
+ @Nullable final JComponent actionListenerComponent,
+ @NotNull final String title,
+ @NotNull final Project project,
+ @Nullable final Collection<Runnable> closeListeners,
+ @NotNull final AnAction... customActions) {
+ final AnAction[] actions = ArrayUtil.mergeArrays(customActions, consoleView.createConsoleActions());
+ show(consoleView.getComponent(), actionListenerComponent, title, project, closeListeners, actions);
+ }
+
+ /**
+ * Displays some component in the toolwindow
+ *
+ * @param dataComponent component to display
+ * @param actionListenerComponent component to bind to actions shortcuts (can be null)
+ * @param title window title (should be unique!)
+ * @param project project where displaying takes place
+ * @param closeListeners engines to listen for "close" events. Something that stops console process may be good example of it.
+ * Null if you do not want this delegate to be called.
+ * @param customActions additional actions to add
+ */
+ public static void show(@NotNull final JComponent dataComponent,
+ @Nullable final JComponent actionListenerComponent,
+ @NotNull final String title,
+ @NotNull final Project project,
+ @Nullable final Collection<Runnable> closeListeners,
+ @NotNull final AnAction... customActions) {
+ final ToolWindowApi api = new ToolWindowApi(project, title);
+
+ final Collection<Runnable> closeListenersToAdd = new ArrayList<Runnable>(Collections.singleton(new MyToolWindowCloser(api)));
+ if (closeListeners != null) {
+ closeListenersToAdd.addAll(closeListeners);
+ }
+ api.add(PanelWithActions.wrap(dataComponent, closeListenersToAdd, actionListenerComponent, customActions));
+ }
+
+ /**
+ * When user clicks "close", we should close whole window, so we delegate it to {@link ToolWindowApi}
+ */
+ private static final class MyToolWindowCloser implements Runnable {
+ @NotNull
+ private final ToolWindowApi myApi;
+
+ private MyToolWindowCloser(@NotNull final ToolWindowApi api) {
+ myApi = api;
+ }
+
+ @Override
+ public void run() {
+ myApi.close();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2000-2015 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 to display toolwindow on the bottom of the screen with custom content and several actions.
+ * This package also has shortcut to display {@link com.intellij.execution.ui.ConsoleView} with its actions.
+ * And when console is {@link com.jetbrains.toolWindowWithActions.ConsoleWithProcess} it also displays "stop" action
+ *
+ * Entry point is {@link com.jetbrains.toolWindowWithActions.WindowWithActions}
+ *
+ * @see com.jetbrains.toolWindowWithActions.WindowWithActions
+ * @author Ilya.Kazakevich
+ */
+package com.jetbrains.toolWindowWithActions;
\ No newline at end of file